Aggiungi oggetto a ArrayList in corrispondenza dell'indice specificato


142

Penso che sia una domanda abbastanza semplice, ma non riesco a capire come farlo correttamente.

Ho un arraylist vuoto:

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

Ho alcuni oggetti che voglio aggiungere e ogni oggetto deve trovarsi in una certa posizione. È necessario tuttavia che possano essere aggiunti in ogni possibile ordine. Quando provo questo, non funziona e ottengo un IndexOutOfBoundsException:

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

Quello che ho provato è riempire ArrayListcon nulle quindi fare quanto sopra. Funziona, ma penso che sia una soluzione orribile. c'è un altro modo per fare ciò?


7
Ottieni IndexOutOfBoundsException perché l'elenco è vuoto e non puoi accedere a una posizione dell'elenco che non esiste ...
Vic

1
C'è un modo per creare quella posizione senza riempire l'elenco con oggetti null? A me sembra una soluzione davvero strana.
J. Maes,

1
Non credo ... Se devi aggiungere gli oggetti in un ordine casuale, dovresti cercare un altro modo di farlo. Ad esempio con un array tipico: "Object []" e quindi non dovresti non devi riempirlo, basta inizializzarlo
Vic

1
@Maethortje non è davvero un problema strano. Cerca elenchi sparsi, reference.wolfram.com/mathematica/tutorial/… sembra un buon articolo. In Java, tuttavia, una mappa con indice come chiave potrebbe essere l'approccio più semplice.
Miserabile variabile,

2
@Pan Anche se dichiari la dimensione .. Semplicemente non inizializza la lista, ma dichiara quanti spazi vuoi conservare in memoria .. A mio avviso, una lista è un array di elementi che ha anche un puntatore al elemento successivo. Se provi ad aggiungere un elemento in terza posizione quando hai il secondo vuoto (o null) non hai un puntatore per aiutarti a sapere che è il terzo elemento ..: 1-> 2-> 3 è OK, ma 1- > * -> 3 qui hai un problema ...
Vic

Risposte:


209

Puoi farlo in questo modo:

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

Dopo aver aggiunto object2 in posizione 2, sposta object3 in posizione 3.

Se vuoi che object3 sia sempre in position3, ti suggerisco di usare una HashMap con posizione come chiave e oggetto come valore.


3
Una hashmap sarebbe davvero in grado di risolvere questo problema. Penso che andrò per quello poiché non mi sembra di poter aggiungere qualcosa nella posizione 3 quando non ci sono oggetti nella posizione 2.
J. Maes,

breve ma la maggior parte delle risposte. Altri sono sulla strada sbagliata
Shabbir Dhangot il

Una logica costruttiva!
Arsal Imam,

31

Puoi usare la matrice di oggetti e convertirla in matrice-

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

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

ArrayList sarà- [1, null, 2, 3, null, null, null, 7, null, null]


2
Uno svantaggio è che devi conoscere le dimensioni in anticipo.
Daniel Hári,

17

In tal caso, perché non prendere in considerazione l'utilizzo di un array normale, inizializzare la capacità e posizionare gli oggetti sull'indice desiderato.

Object[] list = new Object[10];

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

Si inattiva la capacità, ma non la dimensione dell '"ArrayList". La dimensione è definita come numero di elementi e quando l'indice è> dimensione, l'eccezione arriva ...
Vic

@Vic, all'inizio ho letto male la domanda, ma grazie per il suggerimento.
medopal,

Ho inizializzato la capacità a 10, ma ottengo ancora un IndexOutOfBoundsExceptopn quando aggiungo un oggetto. Lo stesso con la modifica della capacità con sureCapacity. L'unica cosa che funziona è riempirsi di null al momento ...
J. Maes,

@Maethortje Cerca la differenza tra "dimensione" e "capacità" ... L'eccezione arriva quando l'indice è> la dimensione, non quando lo è> capacità .....
Vic

Come menzionato dai ragazzi, stai aggiungendo un oggetto all'indice 3, mentre la dimensione dell'elenco è ancora 1. Non è possibile. L'aggiunta a un indice specifico è consentita purché questo indice sia all'interno dei limiti dell'elenco, ad esempio se l'elenco contiene 3 oggetti, non è possibile aggiungere un oggetto all'indice 100.
medopal

14

È inoltre possibile sovrascrivere ArrayList per inserire valori null tra la dimensione e l'elemento che si desidera aggiungere.

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

Quindi è possibile aggiungere in qualsiasi momento in ArrayList. Ad esempio, questo metodo principale:

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

produce questo risultato dalla console:

0: zero

1 uno

2: due

3: null

4: null

5: cinque


9

Attiro la tua attenzione sulla ArrayList.adddocumentazione , che dice che genera IndexOutOfBoundsException- se l'indice è fuori portata ( index < 0 || index > size())

Controlla il size()tuo elenco prima di chiamarelist.add(1, object1)


Hai ragione @Hemal, @Maethortje Perché non controlli le dimensioni dell'elenco prima di aggiungere l'elemento all'elenco? controlla se la posizione che stai cercando di aggiungere è inferiore alla dimensione della lista, altrimenti puoi semplicemente fare una cosa normalelist.add("element");
Rakesh

1
Da quanto ho capito, il "problema" è aggiungere l'elemento in posizione 3 anche se non c'è un elemento in posizione 2 ...
Vic

@Vis che è un elenco sparso - vedi il mio commento alla domanda.
Miserabile variabile,

5

È necessario popolare gli indici vuoti con valori nulli.

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 

durante il tentativo di aggiungere un elemento nella posizione specificata hai IndexOutOfBound, quindi l'elenco dovrebbe avere alcuni elementi nella loro posizione.

Per favore prova a seguire

/*
  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

*/

Capisco il problema che causa il mio errore. Sembra che devo aggiungere oggetti alle posizioni successive prima di poter aggiungere un oggetto a quella posizione. Nel momento in cui sto aggiungendo, non sto eliminando tutti gli oggetti che voglio aggiungere. Pensi che l'aggiunta di oggetti null sia una soluzione adeguata?
J. Maes,

@Maethortje Non sarà molto giusto farlo, dato che è solo un trucco :)
Sankalp

è necessario rimuovere le virgolette di esempio del codice dal primo paragrafo.
Jalal Sordo,

2

Che ne dici di questo piccolo whileloop come soluzione?

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)

2

Questa è una possibile soluzione:

list.add(list.size(), new Object());

1

Penso che la soluzione di medopal sia quella che stai cercando.

Ma un'altra soluzione alternativa è usare una HashMap e usare il tasto (intero) per memorizzare le posizioni.

In questo modo non sarà necessario popolarlo con null ecc. Inizialmente, basta incollare la posizione e l'oggetto nella mappa mentre si procede. Puoi scrivere un paio di righe alla fine per convertirlo in un Elenco se ne hai bisogno in quel modo.


TreeMap non è migliore dal momento che è ordinata dalle chiavi?
Daniel Hári,

1

Supponiamo di voler aggiungere un elemento in una posizione, quindi la dimensione dell'elenco deve essere superiore alla posizione.

add(2, item): questa sintassi significa, spostare l'elemento precedente nella posizione 2 all'indice successivo e aggiungere l'elemento nella seconda posizione.

Se non ci sono oggetti in seconda posizione, non funzionerà, genererà un'eccezione.

Ciò significa che se vuoi aggiungere qualcosaposition 2,

la dimensione della tua lista deve essere almeno (2 + 1) =3,così gli articoli sono disponibili su0,1,2 Position.

in tal modo si garantisce che la posizione 2 sia accessibile in modo sicuro e non vi sarebbero eccezioni.


2
sto solo passando quando ho notificato la tua risposta ... in realtà, l'indice deve essere inferiore o uguale alla lunghezza reale dell'elenco nel momento in cui stiamo inserendo un nuovo elemento. esempio: la dimensione dell'elenco è 2: l'aggiunta nell'indice 2 funzionerà. l'aggiunta nell'indice 3 genererà un'eccezione. (È stato testato)
Houssem Chlegou,

0

Se stai usando il sapore Android di Java, potrei suggerire di usare uno SparseArray . È una mappatura più efficiente della memoria degli interi sugli oggetti e più facile da ripetere rispetto a una mappa


0

Un po 'tardi, ma spero che possa ancora essere utile a qualcuno.

2 passaggi per aggiungere elementi a una posizione specifica in un ArrayList

  1. add elementi nulli in un indice specifico in un ArrayList
  2. Quindi setle posizioni come e quando richiesto.

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

In questo modo non sono presenti elementi ridondanti, ad ArrayListes. Se si dovessero aggiungere elementi come,

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

Questo non sovrascriverebbe semplicemente gli elementi esistenti nella posizione, spostando quelli esistenti a destra di uno - quindi hai una ArrayList con il doppio delle indicazioni.


0

È necessario impostare invece di aggiungere per sostituire il valore esistente all'indice.

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

L'elenco conterrà [oggetto1, oggetto2]

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.