java: ArrayList - как я могу проверить, существует ли индекс?

111

Я использую ArrayList<String>и добавляю данные по определенным индексам, как я могу проверить, существует ли определенный индекс?

Должен ли я просто get()проверить значение? Или мне ждать исключения? Есть другой способ?

Обновить

Спасибо за ответы, но поскольку я добавляю материалы только по определенным индексам, длина списка не покажет мне, какие из них доступны.

ufk
источник
2
Взгляните на набор, возможно, он больше подходит для того, что вам нужно?
Пол Уилан
3
Тогда вам придется get()проверить null- не полагайтесь на исключения. Рассмотрите возможность использования HashTableвместо этого java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html
Amarghosh
здорово!! Я буду использовать HashTable, спасибо
ufk

Ответы:

159

Метод arrayList.size() возвращает количество элементов в списке, поэтому, если индекс больше или равен size(), он не существует.

if(index >= myList.size()){
  //index not exists
}else{
 // index exists
}
Амаргош
источник
10
Это должно быть «больше или равно size()», поскольку это индекс, отсчитываемый от нуля.
McDowell
1
Также стоит упомянуть, что для того, чтобы сделать это атомарным, вам, вероятно, следует выполнить проверку size () и соответствующий поиск на основе условного индекса при блокировке списка.
Adamski
3
Обратите внимание, что я помечу этот ответ как правильный, потому что владелец (Amarghosh) ответил на мой вопрос в комментарии к моему вопросу. HashTable намного лучше удовлетворит мои потребности.
ufk
что, если вы устанавливаете элементы в массиве с идентификатором элемента? напр. mylist.set (1, элемент1); mylist.set (3, элемент3); // пропускаем 2. Думаю, для этого сценария больше подходит HashMap?
yeahman
это не совсем удовлетворяет меня ... если я хочу что-то сделать в списке, если индекс уже есть, но в противном случае подготовить его ... с новым списком, с которого я собираюсь начать, index = 0и моим list.size() == 0тоже. так что в первый раз я проверю, что это правда, и я подготовлю список, чтобы что-то сделать. но в следующий раз в этом индексе мой индекс все еще будет таким, index = 0и теперь я повторно инициализирую этот элемент в списке, когда я должен был что-то делать. Первая мысль относится ко &&второму условию, list.get(index) == nullно это не работает, поэтому есть такие вопросы, как этот
Роберто Томас
69

Хотя у вас есть дюжина предложений об использовании размера вашего списка, которые подходят для списков с линейными записями, похоже, никто не прочитал ваш вопрос.

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

Использование if (list.get (index) == null) также не будет работать, поскольку get () выдает исключение вместо возврата null.

Попробуй это:

try {
    list.get( index );
} catch ( IndexOutOfBoundsException e ) {
    list.add( index, new Object() );
}

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

пли
источник
2
Спасибо, нужна была эта техника для модульного тестирования, существуют ли индексы массива.
Noumenon
11
Не забывайте избегать использования try/catchдля такого рода работы, это замедлит вашу программу на 50% или, может быть, больше .. проверка ошибок добавляет как ремешок к существующему коду, чтобы замедлить его ... лучше избегать этого в критических областях. Проверка lengthв этом случае - лучшее, что вы можете сделать, так как indexвсегда будет меньше length, чем старые index, будут сдвинуты и станут новыми index, если вы removeих, поэтому проверка правила lengthвсегда будет работать.
SSpoke
1
@SSpoke ... Хотя я согласен, попытка / поймать - далеко не "хороший" ответ; он решит проблему, когда список разрежен. Я предпочитаю использовать массив: Object [] ary; ниже или хеш.
будет
12

Это то, что вам нужно ...

public boolean indexExists(final List list, final int index) {
    return index >= 0 && index < list.size();
}

Почему бы не использовать простой старый массив? Я думаю, что индексированный доступ к списку - это запах кода.

Пол Маккензи
источник
3
Не всегда, поскольку он может захотеть, чтобы ArrayList со временем увеличивался, а массив этого сделать не может.
Coyote21
7

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

if (index < list.size()) {
    ...
}

Если вас также беспокоит отрицательное значение индекса, используйте следующие

if (index >= 0 && index < list.size()) {
    ...
}
AamirR
источник
1
Как это имеет какое-либо значение по сравнению с принятым ответом несколько лет назад?
Basil Bourque
2
Думаю, на ваш взгляд, это не представляет никакой ценности, но я видел комментарий Роберто Томаса к принятому ответу, предполагая, что он не совсем понял принятый ответ. проверьте это "с новым списком, я собираюсь начать с index = 0 и моего list.size () == 0 тоже. так что в первый раз, когда я проверю, это будет правда" Я решил опубликовать отдельный ответ, чтобы помочь любая путаница в будущем.
AamirR
5

По поводу вашего обновления (что, наверное, должно быть другим вопросом). Вы должны использовать массив этих объектов вместо ArrayList, чтобы вы могли просто проверить значение на null:

Object[] array = new Object[MAX_ENTRIES];
..
if ( array[ 8 ] == null ) {
   // not available
}
else {
   // do something
}

Лучшая практика

Если в вашем массиве нет сотен записей, вам следует подумать об организации его как класса, чтобы избавиться от магических чисел 3,8 и т. Д.

Поток управления с использованием исключения - плохая практика.

укладчик
источник
2
Если array [8] не существует, вы столкнетесь с ArrayIndexOutOfBoundException.
Нитеш Кумар Ананд
4

Поскольку java-9существует стандартный способ проверки принадлежности индекса к массиву - Objects # checkIndex () :

List<Integer> ints = List.of(1,2,3);
System.out.println(Objects.checkIndex(1,ints.size())); // 1
System.out.println(Objects.checkIndex(10,ints.size())); //IndexOutOfBoundsException
Антон Баланюк
источник
of()Метод также добавляется в Java 9 класса List : docs.oracle.com/javase/9/docs/api/java/util/List.html#of--
Orici
3

Вы можете проверить размер файла с ArrayListпомощью size()метода. Это вернет максимальный индекс +1

jwoolard
источник
2

простой способ сделать это:

try {
  list.get( index ); 
} 
catch ( IndexOutOfBoundsException e ) {
  if(list.isEmpty() || index >= list.size()){
    // Adding new item to list.
  }
}
Жозуе
источник
1

Быстрый и грязный тест, существует ли индекс или нет. в вашем списке замены реализации. Список, который вы тестируете.

public boolean hasIndex(int index){
    if(index < list.size())
        return true;
    return false;
}

или для 2D-списков массивов ...

public boolean hasRow(int row){
    if(row < _matrix.size())
        return true;
    return false;
}
t3dodson
источник
1
Список не .lengthимеет , list.size()но это не большая проблема , я ввернуть , как это все время , ха - ха , я полагаться на компилятор , чтобы направлять меня на том. Вы, наверное, думали о примитивных массивах
SSpoke
1
Спасибо, что уловили это. О количестве контейнеров легко забыть.
t3dodson
0

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

Если вы хотите проверить, является ли значение в вашем индексе nullили нет, позвонитеget()

Дмитрий
источник
1
Вызов sureCapacity (int) не увеличит размер списка, только его емкость; т.е. «потенциальный размер», поэтому поиск по индексу за пределами границ все равно не удастся.
Adamski
Кроме того, зачем вообще вызывать secureCapacity (int)? Это может быть невероятно дорогостоящая операция, если, например, текущий размер списка равен 5, и вы хотите определить значение элемента №: 100000000.
Adamski
Я имел в виду, что индексы меньше size () существуют всегда, а те, которые> = size () нет, и их нельзя использовать (== call set ()), пока список не станет достаточно большим. Вызова sureCapacity недостаточно, нужно изменить размер, добавив элементы.
Дмитрий
Неправильное объяснение того, что на самом деле делает sureCapacity (int). Он ничего не делает с размером ArrayList.
Mohsen
0

Вы можете проверить размер массива.

package sojava;
import java.util.ArrayList;

public class Main {
    public static Object get(ArrayList list, int index) {
        if (list.size() > index) { return list.get(index); }
        return null;
    }

    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(""); list.add(""); list.add("");        
        System.out.println(get(list, 4));
        // prints 'null'
    }
}
мику
источник