Додайте об’єкт до ArrayList за вказаним індексом


142

Я думаю, що це досить просте питання, але я не можу зрозуміти, як це зробити правильно.

У мене порожній масив:

ArrayList<object> list = new ArrayList<object>();

У мене є кілька об'єктів, які я хочу додати, і кожен об'єкт повинен знаходитися на певній позиції. Однак необхідно, щоб вони могли додаватися в кожному можливому порядку. Коли я спробую це, це не працює, і я отримую IndexOutOfBoundsException:

list.add(1, object1)
list.add(3, object3)
list.add(2, object2)

Те , що я намагався це заповнення ArrayListз , nullа потім робити вище. Це працює, але я думаю, що це жахливе рішення. Чи є інший спосіб зробити це?


7
Ви отримуєте IndexOutOfBoundsException, оскільки список порожній і ви не можете отримати доступ до позиції списку, яка не існує ...
Вік,

1
Чи є спосіб створити цю позицію без заповнення списку нульовими об'єктами? Мені здається, це дійсно дивне рішення.
Дж. Мейс

1
Я не думаю, що так ... Якщо вам потрібно додати об'єкти у випадковому порядку, вам доведеться шукати інший спосіб зробити це. Наприклад, із типовим масивом: 'Object []', а потім не слід Вам не доведеться заповнювати його, просто ініціалізуйте
Вік,

1
@Maethortje - це насправді не дивна проблема. Подивіться рідкісні списки, посилання на reference.wolfram.com/mathematica/tutorial/… здається гарною статтею. Однак у Java найпростішим підходом може стати Карта з індексом як ключовим.
Жалюгідна змінна

2
@Pan Навіть якщо ви оголосите розмір .. Він просто не ініціалізує список, але оголошує, скільки місця ви хочете залишити в пам'яті. Як я бачу, список - це масив елементів, який також має вказівник на наступний елемент. Якщо ви спробуєте додати елемент у третю позицію, коли у вас є другий порожній (або нульовий), у вас немає вказівника, який би допомагав вам знати, що це третій елемент ..: 1-> 2-> 3 це нормально, але 1- > * -> 3 ось у вас проблема ...
Вік

Відповіді:


209

Ви можете це зробити так:

list.add(1, object1)
list.add(2, object3)
list.add(2, object2)

Після того, як ви додасте object2 до позиції 2, він перемістить object3 в позицію 3.

Якщо ви хочете, щоб object3 постійно знаходився в положенні3, я б запропонував вам використовувати HashMap з позицією як ключ, а об'єкт як значення.


3
Хешмап дійсно міг би вирішити цю проблему. Я думаю, що я піду для цього, оскільки, схоже, я не можу додати щось у 3-му місці, коли в місці немає об’єкта 2.
Дж. Мейс,

короткий, але більшість відповідей. Інші йдуть неправильно
Шаббір Дханго

Конструктивна логіка!
Арсам Імам

31

Ви можете використовувати масив об'єктів і перетворювати його в ArrayList-

Object[] array= new Object[10];
array[0]="1";
array[3]= "3";
array[2]="2";
array[7]="7";

List<Object> list= Arrays.asList(array);

ArrayList буде [1, null, 2, 3, null, null, null, 7, null, null]


2
Один недолік - ви повинні знати розмір заздалегідь.
Даніель Харі

17

Якщо це так, то чому ви не подумаєте використовувати звичайний масив, ініціалізуйте ємність і поставте об'єкти в потрібний індекс.

Object[] list = new Object[10];

list[0] = object1;
list[2] = object3;
list[1] = object2;

Ви ініціалізуєте ємність, але не розмір "ArrayList". Розмір визначається як кількість елементів, а коли індекс> розмір, виходить виняток ...
Vic

@Vic, спочатку я неправильно прочитав питання, але дякую за пораду.
медопал

Я ініціалізував ємність у 10, але все одно отримую IndexOutOfBoundsExceptopn при додаванні об'єкта. Те саме із зміною ємності із забезпеченням ємності. Єдине, що працює - це заповнення нуля на даний момент ...
Дж. Мейс

@Maethortje Шукайте різницю між "розміром" та "місткістю" ... Виняток виникає, коли індекс> розмір, а не коли він є> місткість .....
Вік,

Як згадували хлопці, ви додаєте об’єкт в індексі 3, тоді як розмір списку все ще 1. Це неможливо. Додавання певного індексу дозволено до тих пір, поки цей індекс знаходиться у межах списку, наприклад, якщо у вашому списку є 3 об’єкти, ви не можете додати об’єкт у індексі 100.
medopal

14

Ви також можете замінити ArrayList, щоб вставити нулі між вашим розміром та елементом, який ви хочете додати.

import java.util.ArrayList;


public class ArrayListAnySize<E> extends ArrayList<E>{
    @Override
    public void add(int index, E element){
        if(index >= 0 && index <= size()){
            super.add(index, element);
            return;
        }
        int insertNulls = index - size();
        for(int i = 0; i < insertNulls; i++){
            super.add(null);
        }
        super.add(element);
    }
}

Потім ви можете додати в будь-яку точку ArrayList. Наприклад, цей основний метод:

public static void main(String[] args){
    ArrayListAnySize<String> a = new ArrayListAnySize<>();
    a.add("zero");
    a.add("one");
    a.add("two");
    a.add(5,"five");
    for(int i = 0; i < a.size(); i++){
        System.out.println(i+": "+a.get(i));
    }
}   

дає такий результат від консолі:

0: нуль

1: один

2: два

3: null

4: null

5: п’ять


9

Звертаю вашу увагу на ArrayList.addдокументацію , в якій сказано, що вона кидає IndexOutOfBoundsException- якщо індекс знаходиться поза діапазоном ( index < 0 || index > size())

Перевірте size()список свого списку, перш ніж дзвонитиlist.add(1, object1)


Ви праві @Hemal, @Maethortje Чому ви не перевіряєте розмір списку, перш ніж додавати елемент до списку? перевірте, чи позиція, яку ви намагаєтеся додати, менша за розмір списку, якщо ні, то ви можете просто зробити нормальнуlist.add("element");
Ракеш

1
Як я розумію, "проблема" полягає в тому, щоб додати елемент у позиції 3, навіть якщо немає елемента в позиції 2 ...
Вік,

@Ви це рідкісний список - дивіться мій коментар до питання.
Жалюгідна змінна

5

Потрібно заповнити порожні індекси нулями.

while (arraylist.size() < position)
{
     arraylist.add(null);
}

arraylist.add(position, object);

2
@Maethortje 

The problem here is java creates an empty list when you called new ArrayList and 

під час спроби додати елемент у вказаній позиції ви отримали IndexOutOfBound, тому список повинен мати деякі елементи у їхньому положенні.

Спробуйте виконати наступне

/*
  Add an element to specified index of Java ArrayList Example
  This Java Example shows how to add an element at specified index of java
  ArrayList object using add method.
*/

import java.util.ArrayList;

public class AddElementToSpecifiedIndexArrayListExample {

  public static void main(String[] args) {
    //create an ArrayList object
    ArrayList arrayList = new ArrayList();

    //Add elements to Arraylist
    arrayList.add("1");
    arrayList.add("2");
    arrayList.add("3");

    /*
      To add an element at the specified index of ArrayList use
      void add(int index, Object obj) method.
      This method inserts the specified element at the specified index in the
      ArrayList.  
    */
    arrayList.add(1,"INSERTED ELEMENT");

    /*
      Please note that add method DOES NOT overwrites the element previously
      at the specified index in the list. It shifts the elements to right side
      and increasing the list size by 1.
    */

    System.out.println("ArrayList contains...");
    //display elements of ArrayList
    for(int index=0; index < arrayList.size(); index++)
      System.out.println(arrayList.get(index));

  }
}

/*
Output would be
ArrayList contains...
1
INSERTED ELEMENT
2
3

*/

Я розумію проблему, яка викликає мою помилку. Здається, що я повинен додати об'єкти до наступних позицій, перш ніж я можу додати об'єкт до цієї позиції. У момент додавання я не розпоряджаюся всіма об'єктами, які хочу додати. Ви вважаєте, що тоді додавання нульових об'єктів є правильним рішенням?
Дж. Мейс

@Maethortje Це робити не буде дуже справедливо, оскільки це просто хак :)
Sankalp

вам потрібно вилучити цитати з кодового зразка з першого пункту.
Джалал Сордо

2

Як щодо цієї маленької whileпетлі як рішення?

private ArrayList<Object> list = new ArrayList<Object>();

private void addObject(int i, Object object) {
    while(list.size() < i) {
        list.add(list.size(), null);
    }
    list.add(i, object);
}
....

addObject(1, object1)
addObject(3, object3)
addObject(2, object2)


1

Я думаю, що рішення від медопалу - це те, що ти шукаєш.

Але ще одне альтернативне рішення - використовувати HashMap і використовувати ключ (Integer) для зберігання позицій.

Таким чином, вам не потрібно буде заповнювати його нулями тощо спочатку, просто дотримуйтесь положення та об'єкта на карті, коли ви йдете разом. Ви можете написати кілька рядків наприкінці, щоб перетворити їх у Список, якщо вам це потрібно.


Хіба TreeMap не є кращим, оскільки замовляють клавіші?
Даніель Харі

1

Припустимо, ви хочете додати елемент у позицію, тоді розмір списку повинен бути більше позиції.

add(2, item): цей синтаксис означає, що перемістіть старий елемент у позиції 2 до наступного індексу та додайте елемент на 2-у позицію.

Якщо на другому місці немає елемента, то це не вийде, це викине виняток.

Це означає, що якщо ви хочете щось додатиposition 2,

розмір вашого списку повинен бути не менше, (2 + 1) =3,щоб товари були доступні за адресою0,1,2 Position.

таким чином забезпечується безпечний доступ до позиції 2 і не буде винятком.


2
Я просто проходжу повз, коли я повідомив вашу відповідь ... насправді індекс повинен бути нижчим або рівним реальній довжині списку в момент, коли ми вставляємо новий елемент. exhample: розмір списку - 2: додавання в індекс 2 буде працювати. додавання в індекс 3 призведе до виключення. (Було випробувано)
Houssem Chlegou

0

Якщо ви використовуєте Android на Java аромат, я можу запропонувати використовувати SparseArray . Це більш ефективне відображення в пам'яті цілих чисел на об'єкти і простіше переглядати їх, ніж карта


0

Трохи пізно, але, сподіваємось, хтось все-таки може бути корисним.

2 етапи для додавання елементів до певної позиції в ArrayList

  1. add нульові елементи до певного індексу в ArrayList
  2. Тоді setпозиції як і коли потрібно.

        list = new ArrayList();//Initialise the ArrayList
    for (Integer i = 0; i < mItems.size(); i++) {
        list.add(i, null); //"Add" all positions to null
    }
       // "Set" Items
        list.set(position, SomeObject);

Таким чином, у вас немає зайвих елементів, ArrayListтобто якщо ви повинні додати такі елементи, як,

list = new ArrayList(mItems.size());    
list.add(position, SomeObject);

Це не перезаписує існуючі елементи в позиції просто, зміщуючи існуючі вправо на один, тож у вас є ArrayList з вдвічі більшою кількістю індексів.


0

Вам слід встановити замість add для заміни наявного значення в індексі.

list.add(1, object1)
list.add(2, object3)
list.set(2, object2)

Список буде містити [object1, object2]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.