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.