Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.04.2016, 18:55   #1
hoz
Форумчанин
 
Аватар для hoz
 
Регистрация: 29.06.2013
Сообщений: 132
По умолчанию Непонянка со свойствами Capacity и Count в ArrayList ?

У ArrayList имеются 2 свойства Count и Capacity.
Count - возвращает число элементов, содержащихся в списке ArrayList.
Capacity - возвращает или задаёт число элементов, которое может содержать список ArrayList.
В простом примере:
Код:
using System;
using System.Collections;
public class SamplesArrayList
{

    public static void Main()
    {

        // Creates and initializes a new ArrayList.
        ArrayList myAL = new ArrayList();
        myAL.Add("Hello");
        myAL.Add("World");
        myAL.Add("!");

        // Displays the properties and values of the ArrayList.
        Console.WriteLine("myAL");
        Console.WriteLine("    Count:    {0}", myAL.Count);
        Console.WriteLine("    Capacity: {0}", myAL.Capacity);
        Console.Write("    Values:");
        PrintValues(myAL);
    }

    public static void PrintValues(IEnumerable myList)
    {
        foreach (Object obj in myList)
            Console.Write("   {0}", obj);
        Console.WriteLine();
        Console.ReadKey();
    }

}
Видно, что тут, что-то не так.
Как я понял, в данном списке может содержаться 4 элемента, т.к. Capacity =4, но, на данный момент присутствует 3 элемента т.к. Count = 3.
Почему так? Ведь явно количество элементов не задано в коде?
hoz вне форума Ответить с цитированием
Старый 01.04.2016, 19:01   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Почему так? Ведь явно количество элементов не задано в коде?
Чего? У вас был пустой контейнер, вы добавили три элемента... что вы ожидали увидеть?
p51x вне форума Ответить с цитированием
Старый 01.04.2016, 19:02   #3
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Capacity — под сколько памяти выделено, Count — сколько добавлено (через Add и т.п.).
Когда надо будет (при добавлении с Count == Capacity) оно выделит больше памяти и увеличит Capacity, например в 2 раза.

В конструкторе можно задать начальное Capacity (если известно сколько надо).
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 01.04.2016, 19:47   #4
hoz
Форумчанин
 
Аватар для hoz
 
Регистрация: 29.06.2013
Сообщений: 132
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Чего? У вас был пустой контейнер, вы добавили три элемента... что вы ожидали увидеть?
Так я думал, тут какая-то линейная логика.
Ведь если изменить поле, где добавляем элементы, то получаются совсем разные результаты возможной вместимости, хотя количество то понятно... оно такое, сколько добавили. Вот 2 варианта:
1. Добавлено 4 элемента
Код:
// Creates and initializes a new ArrayList.
        ArrayList myAL = new ArrayList();
        myAL.Add("Hello");
        myAL.Add("World");
        myAL.Add("!");
        myAL.Add("qwewe");
На выходе вижу: Count = 4, Capacity = 4.
Замечу, что значение Capacity такое же как и в том случае, как и первый раз.
2. Добавлено 5 элементов
Код:
// Creates and initializes a new ArrayList.
        ArrayList myAL = new ArrayList();
        myAL.Add("Hello");
        myAL.Add("World");
        myAL.Add("!");
        myAL.Add("qwewe");
        myAL.Add("Last element");
На выходе вижу: Count = 5, Capacity = 8.
Замечу, что значение Capacity резко увеличилось до 8. Хотя предыдущий раз, когда добавляли на 1 элемент меньше, значение было 4, а тут 8 ! Получается, данное свойство меняется как-то нелинейно?
Я чего спрашиваю... Думал, что добавили элемент, количество элементов равно x, тогда Capacity = x + 1. А тут как-то не так.
hoz вне форума Ответить с цитированием
Старый 01.04.2016, 19:55   #5
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Перевыделять память при каждом добавлении не эффективно.

http://referencesource.microsoft.com...f2bbf8d237742e
Код:
        // Adds the given object to the end of this list. The size of the list is
        // increased by one. If required, the capacity of the list is doubled
        // before adding the new element.
        //
        public virtual int Add(Object value) {
            Contract.Ensures(Contract.Result<int>() >= 0);
            if (_size == _items.Length) EnsureCapacity(_size + 1);
            _items[_size] = value;
            _version++;
            return _size++;
        }
Код:
        // Ensures that the capacity of this list is at least the given minimum
        // value. If the currect capacity of the list is less than min, the
        // capacity is increased to twice the current capacity or to min,
        // whichever is larger.
        private void EnsureCapacity(int min) {
            if (_items.Length < min) {
                int newCapacity = _items.Length == 0? _defaultCapacity: _items.Length * 2;
                // Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
                // Note that this check works even when _items.Length overflowed thanks to the (uint) cast
                if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
                if (newCapacity < min) newCapacity = min;
                Capacity = newCapacity;
            }
        }
Код:
       
         public virtual int Capacity {
            get {
                Contract.Ensures(Contract.Result<int>() >= Count);
                return _items.Length;
            }
            set {
                if (value < _size) {
                    throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
                }
                Contract.Ensures(Capacity >= 0);
                Contract.EndContractBlock();
                // We don't want to update the version number when we change the capacity.
                // Some existing applications have dependency on this.
                if (value != _items.Length) {
                    if (value > 0) {
                        Object[] newItems = new Object[value];
                        if (_size > 0) { 
                            Array.Copy(_items, 0, newItems, 0, _size);
                        }
                        _items = newItems;
                    }
                    else {
                        _items = new Object[_defaultCapacity];
                    }
                }            
            }
        }
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 01.04.2016 в 19:57.
Alex11223 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
управление свойствами книги maxvip Microsoft Office Excel 1 26.11.2014 11:46
Чем отличается ListBox.Count от ListBox.Items.Count bakanaev Общие вопросы Delphi 5 16.08.2012 12:35
TObjectList.Capacity - принцип работы kefir Общие вопросы Delphi 1 02.05.2011 17:03
Кнопка с её свойствами Golovastik HTML и CSS 7 16.07.2010 19:30
Ошибка: The DecisionCube Capacity is low Tanya2008 Общие вопросы Delphi 1 30.04.2009 15:28