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

Відповіді:


158

Метод arrayList.size() повертає кількість елементів у списку - тому, якщо індекс більший або дорівнює size(), він не існує.

if(index >= myList.size()){
  //index not exists
}else{
 // index exists
}

10
Це має бути "більшим або рівним size()", оскільки це нульовий індекс.
МакДауелл

1
Також варто згадати, що для створення цього атома слід, мабуть, виконати перевірку розміру () та відповідний умовний показник на основі пошуку, блокуючи список.
Адамські

3
зауважте, що я позначаю цю відповідь правильно, оскільки власник (Amarghosh) як відповів на моє запитання в коментарі до мого запитання. HashTable набагато краще задовольнить мої потреби.
ufk

що робити, якщо ви встановлюєте елементи в масиві з ідентифікатором елемента? колишній mylist.set (1, item1); mylist.set (3, item3); // Пропуск 2 Я думаю, що HashMap більше підходить для цього сценарію?
агаман

це не зовсім мене задовольняє .. якщо я хочу зробити щось у списку, якщо індекс вже є, але в іншому випадку, щоб підготувати його .. з новим списком, я збираюся розпочати з 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
Дякую, потрібна була ця методика для тестування одиниць, чи існують індекси масиву.
Номенон

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
Як це дає якусь цінність у порівнянні з прийнятим Відповіддю кілька років тому?
Василь Бурк

2
Я думаю, на вашу думку, це не надає ніякої цінності, але я побачив коментар Роберто Томаша щодо прийнятої відповіді, припускаючи, що він не зовсім зрозумів прийняту відповідь. перевірити це "з новим списком. Я почну з індексу = 0 і свого списку.size () == 0. Так що перший раз, коли я перевіряю, це буде правдою", я вирішив опублікувати окрему відповідь, щоб допомогти будь-яка майбутня плутанина.
АамірР

6

Щодо вашого оновлення (яке, мабуть, має бути іншим питанням). Ви повинні використовувати масив цих об'єктів замість ArrayList, щоб ви могли просто перевірити значення null:

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

Найкраща практика

Якщо у вашому масиві немає сотень записів, слід розглянути організацію цього класу, щоб позбутися від магічних чисел 3,8 тощо.

Контроль потоку за допомогою винятку є поганою практикою.


1
Якщо масив [8] не існує, ви зіткнетеся з ArrayIndexOutOfBoundException.
Нітеш Кумар Ананд

4

Оскільки java-9існує стандартний спосіб перевірити, чи належить індекс масиву - Object # 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;
}

або для двовимірних списків масивів ...

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
Виклик secureCapacity (int) не збільшить розмір списку, а лише ємність; тобто "потенційний розмір", тож огляд поза межами індексу все ще не вдасться.
Адамські

Крім того, навіщо взагалі викликати secureCapacity (int)? Це може бути неймовірно дорогою операцією, якщо, наприклад, поточний розмір списку становить 5 і ви хочете визначити значення елемента №: 100 000 000.
Адамські

Я мав на увазі, що індекси, менші за розмір (), завжди існують, а ті, що є> = size (), не мають, і ніхто не може їх використовувати (== set set ()), поки список не стане досить великим. Виклик secureCapacity насправді недостатній, потрібно змінити розмір, додавши елементи.
Дмитро

Неправильне пояснення того, що насправді забезпечує Cacpacity (int). З розміром ArrayList це нічого не робить.
Мохсен

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.