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


111

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

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

Обновить

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


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()) {
    ...
}

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


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;
}

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'
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.