Нужно ли делать setSize () для вектора перед его использованием? - PullRequest
0 голосов
/ 15 ноября 2009

Дано

private final Vector v = new Vector();  //instance variable

следующие 3 строки находятся в методе экземпляра в том же классе.

1.    int length = v.capacity();   
2.    int size = v.size();
3.    Object o = v.getElementAt(0);

Я получаю ArrayIndexOutOfBoundsException в строке 3.

Отладчик показывает, что Vector имеет 10 элементов.
length показывает 10.
size показывает 0.

Почему выдается это исключение, мне нужно сделать setSize(), чтобы использовать Vector v?

Ответы [ 5 ]

2 голосов
/ 15 ноября 2009

Метод Capacity () говорит, что у вас есть много элементов, которые может взять Вектор, прежде чем он увеличит свою емкость. Он не говорит о том, что у вас есть много элементов, которые в данный момент находятся в векторе, это то, для чего назначен size (). И в вашем случае это так, поскольку Вектор пуст.

Вы можете указать емкость, указав параметры для конструктора:

Vector v = new Vector(20);
/* This vector will have the starting capacity
   of 20 elements, before it has to increase
   its capacity */


Vector v = new Vector(10, 5);
/* This vector will have an initial capacity
   of 10 elements, and when it overflows the
   second parameter tells the vector to increase
   its capacity by 5. */

Редактировать

Судя по вашим комментариям к другим постам, у вас в приложении два потока - где один помещает материал в вектор, а другой читает вектор?

Затем вы должны добавить управляющую структуру, чтобы проверить, является ли вектор пустым или нет, прежде чем пытаться получить элементы из него.

Грязный пример:

/* Vector instantiation goes here */

boolean keepRunningFlag = true;
while(keepRunningFlag) {
    if (!vector.isEmpty()) {
        Object o = vector.remove(vector.size() - 1);
        keepRunningFlag = doStuffWithVectorElement(o);
    }
}
2 голосов
/ 15 ноября 2009

Нет, но вы должны добавить элемент, прежде чем получите его.

Вектор - это старая школа Java 1.0. Он использует синхронизацию по умолчанию, что может повлиять на вашу производительность. Почему вы не рассматриваете более новые классы java.util.List и java.util.ArrayList?

1 голос
/ 15 ноября 2009

Как уже упоминали несколько человек, вы не хотите смотреть на емкость вектора или (эквивалентно) длину его внутреннего массива. На практике вы почти никогда не хотите смотреть на возможности вектора. Вам нужно использовать size () (или isEmpty (), который возвращает true, если и только если size () возвращает 0).

Попытка вызова getElementAt (x) для элемента, которого там нет, не возвращает ноль. Выдает исключение.

Поскольку у вас есть другой поток, вставляющий элементы, вы, вероятно, захотите проверить размер и получить элемент атомарно. На самом деле, похоже, что вы пытаетесь реализовать очередь производителя / потребителя, и в этом случае вы также хотите удалить элемент как часть той же самой атомарной операции. Самый простой способ сделать это - синхронизироваться с вектором. например:

Object o = null;
synchronized(v) {
    if (!v.isEmpty()) {
        o = v.getElementAt(0);
        v.removeElementAt(0);
    }
}
// at this point the first element of the vector will be removed
// (if there was one) and o be pointing at that first element. If
// the Vector was empty, o will still be null.

Несколько предостережений с этим кодом:

  • если v становится большим, это становится неэффективным, потому что удаление первого элемента в векторе сдвигает все оставшиеся элементы на один. Если это проблема для вас, вы можете найти или написать класс очереди.
  • Если в Вектор введен нуль, o также будет иметь значение ноль. Это может или не может быть проблемой для вас.
1 голос
/ 15 ноября 2009

Емкость - это пространство, выделенное для текущих и будущих элементов, внутренний (для вектора) номер, который предоставляется по соображениям производительности. Емкость равна или превышает количество содержащихся в ней элементов.

Размер () показывает, сколько элементов вы поместили в вектор. Емкость больше в природе внутренней бухгалтерии вектора. Вы можете получить только элементы 0 ... getSize () -1 из вектора.

Тем не менее, если вы не используете данные в нескольких потоках, вероятно, лучше использовать ArrayList.

Вы можете проверить, является ли вектор пустым, используя isEmpty (), который должен делать что-то вроде getSize () == 0.

1 голос
/ 15 ноября 2009

Нет. Вектор зарезервировал пространство для 10 элементов. Но он пока не содержит ни одного из тех элементов, которые вам нужны, чтобы что-то добавить к вектору с помощью 'put'

Длина скажет вам количество зарезервированного пространства, размер скажет вам, сколько вы действительно можете использовать.

Векторы обычно резервируют больше места, чем нужно для оптимизации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...