Adicionar objeto a ArrayList no índice especificado

142

Eu acho que é uma pergunta bastante simples, mas não consigo descobrir como fazer isso corretamente.

Eu tenho uma lista de matriz vazia:

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

Eu tenho alguns objetos que quero adicionar e cada objeto deve estar em uma determinada posição. É necessário, no entanto, que eles possam ser adicionados em cada ordem possível. Quando tento isso, ele não funciona e recebo um IndexOutOfBoundsException:

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

O que eu tentei é enchendo o ArrayListcom nulle, em seguida, fazer o acima. Funciona, mas acho que é uma solução horrível. Há outra maneira de fazer isso?

J. Maes
fonte
7
Você recebe uma IndexOutOfBoundsException porque a lista está vazia e você não pode acessar uma posição da lista que não existe ...
Vic
1
Existe uma maneira de criar essa posição sem preencher a lista com objetos nulos? Para mim, parece que é uma solução realmente estranha.
J. Maes
1
Eu acho que não ... Se você precisar adicionar os objetos em uma ordem aleatória, teria que procurar outra maneira de fazê-lo. Por exemplo, com uma matriz típica: 'Object []' e então você deveria 't tem que preenchê-lo, apenas initialize
Vic
1
@Maethortje não é realmente um problema estranho. Procure listas esparsas, reference.wolfram.com/mathematica/tutorial/… parece um bom artigo. No entanto, em Java, um mapa com índice como chave pode ser a abordagem mais fácil.
Variável miserável
2
@ Pan Mesmo se você declarar o tamanho .. Ele simplesmente não inicializa a lista, mas declara quanto espaço você deseja reservar na memória .. A meu ver, uma lista é uma matriz de elementos que também possui um ponteiro para o próximo elemento. Se você tentar adicionar um elemento à terceira posição quando tiver o segundo vazio (ou nulo), não terá ponteiro para ajudá-lo a saber que é o terceiro elemento.: 1-> 2-> 3 está OK, mas 1- > * -> 3 aqui você tem um problema ...
Vic

Respostas:

209

Você pode fazer assim:

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

Depois de adicionar o objeto2 à posição 2, ele moverá o objeto3 para a posição 3.

Se você quiser que o objeto3 esteja na posição3 o tempo todo, sugiro que você use um HashMap com posição como chave e objeto como valor.

superM
fonte
3
Um hashmap seria realmente capaz de resolver esse problema. Acho que vou ir para que uma vez que não parece que eu posso acrescentar algo na posição 3, quando não há nenhum objeto na posição 2.
J. Maes
Resposta curta, mas mais. Outros são apenas na pista errada
Shabbir Dhangot
Uma lógica construtiva!
Arsal Imam
31

Você pode usar Array of objects e convertê-lo em 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 será- [1, nulo, 2, 3, nulo, nulo, nulo, 7, nulo, nulo]

user3484940
fonte
2
Uma desvantagem é que você precisa saber o tamanho com antecedência.
Daniel Hári
17

Se for esse o caso, por que você não considera usar uma matriz comum, inicialize a capacidade e coloque objetos no índice desejado.

Object[] list = new Object[10];

list[0] = object1;
list[2] = object3;
list[1] = object2;
medopal
fonte
Você inicializa a capacidade, mas não o tamanho do 'ArrayList'. O tamanho é definido como o número de elementos, e quando o índice é> tamanho exceção vem ...
Vic
@ Vic, eu li mal a pergunta em primeiro lugar, mas obrigado pela dica.
medopal 12/09/11
Inicializei a capacidade em 10, mas ainda recebo um IndexOutOfBoundsExceptopn ao adicionar um objeto. O mesmo acontece com a alteração da capacidade com o allowCapacity. Única coisa que funciona é o preenchimento com nulo no momento ...
J. Maes
@Maethortje olhar para a diferença entre o "tamanho" e "capacidade" ... A exceção ocorre quando o índice é> o tamanho, não quando ele é> capacidade .....
Vic
Como os caras mencionaram, você está adicionando um objeto no índice 3, enquanto o tamanho da lista ainda é 1. Isso não é possível. Adicionando no índice específico é permitida, desde que este índice está dentro dos limites da lista, por exemplo, se a sua lista tem 3 objetos, você não pode adicionar um objeto no índice 100.
medopal
14

Você também pode substituir ArrayList para inserir nulos entre o seu tamanho e o elemento que deseja adicionar.

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

Em seguida, você pode adicionar a qualquer momento da ArrayList. Por exemplo, este método principal:

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

gera esse resultado do console:

0: zero

1 um

2: dois

3: nulo

4: nulo

5: cinco

EngineerWithJava54321
fonte
9

Chamo sua atenção para a ArrayList.adddocumentação , que diz que é lançada IndexOutOfBoundsException- se o índice estiver fora do intervalo ( index < 0 || index > size())

Verifique a size()lista antes de ligarlist.add(1, object1)

Variável miserável
fonte
Você está certo @Hemal, @Maethortje Por que você não verifica o tamanho da lista antes de adicionar o elemento à lista? verificar se a posição que você está tentando adicionar é menor que o tamanho da lista, se não, então você pode apenas fazer uma normaislist.add("element");
Rakesh
1
Pelo que entendi, o "problema" é adicionar o elemento na posição 3, mesmo se não houver um elemento na posição 2 ...
Vic
@Vis que é uma lista esparsa - veja o meu comentário para a pergunta.
Variável miserável
5

Você precisa preencher os índices vazios com valores nulos.

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

arraylist.add(position, object);
Miika Pakarinen
fonte
2
@Maethortje 

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

ao tentar adicionar um elemento na posição especificada, você obtém IndexOutOfBound, portanto a lista deve ter alguns elementos em sua posição.

Por favor, tente seguir

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

*/
Sankalp
fonte
Eu entendo o problema que causa o meu erro. Parece que tenho que adicionar objetos às posições subseqüentes antes de poder adicionar um objeto a essa posição. No momento em que estou adicionando, não estou descartando todos os objetos que quero adicionar. Você acha que adicionar objetos nulos é uma solução adequada?
J. Maes
@Maethortje Não será muito justo para fazer isso, como é apenas um hack :)
Sankalp
você precisa remover as citações de amostra de código do primeiro parágrafo.
Jalal Sordo #
2

Que tal esse pequeno whilelaço como solução?

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)
Stewart
fonte
2

Esta é uma solução possível:

list.add(list.size(), new Object());
Darius
fonte
1

Eu acho que a solução da medopal é o que você está procurando.

Mas apenas outra solução alternativa é usar um HashMap e usar a tecla (Inteiro) para armazenar posições.

Dessa forma, você não precisará preenchê-lo com valores nulos, etc. inicialmente, apenas mantenha a posição e o objeto no mapa à medida que avança. Você pode escrever algumas linhas no final para convertê-lo em uma lista, se precisar dessa maneira.

Ashkan Aryan
fonte
O TreeMap não é melhor desde que ordenado por chaves?
Daniel Hári
1

Suponha que você queira adicionar um item a uma posição, então o tamanho da lista deve ser maior que a posição.

add(2, item): essa sintaxe significa, mova o item antigo na posição 2 para o próximo índice e adicione o item na 2ª posição.

Se não houver nenhum item na 2ª posição, isso não funcionará, gerará uma exceção.

Isso significa que se você quiser adicionar algoposition 2,

o tamanho da sua lista deve ser pelo menos (2 + 1) =3,para que os itens estejam disponíveis em0,1,2 Position.

dessa maneira, garante-se que a posição 2 seja acessada com segurança e não haverá exceção.

Shamsul Arefin Sajib
fonte
2
Estou passando quando notifiquei sua resposta ... na verdade, o índice deve ser menor ou igual ao comprimento real da lista no momento em que estamos inserindo um novo item. exemplo: o tamanho da lista é 2: adicionar o índice 2 funcionará. a adição do índice 3 gerará uma exceção. (Foi testado)
Houssem Chlegou 17/11/19
0

Se você estiver usando o sabor Android do Java, posso sugerir o uso de um SparseArray . É um mapeamento mais eficiente da memória de números inteiros para objetos e mais fácil de iterar do que um Mapa

AllDayAmazing
fonte
0

Um pouco tarde, mas espero que ainda possa ser útil para alguém.

2 etapas para adicionar itens a uma posição específica em um ArrayList

  1. add itens nulos para um índice específico em um ArrayList
  2. Em seguida, setas posições como e quando necessário.

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

Dessa forma, você não possui itens redundantes no ArrayListie, se você deseja adicionar itens como,

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

Isso não sobrescreveria apenas os itens existentes na posição, deslocando os existentes para a direita por um - para que você tenha um ArrayList com o dobro de indicações.

Zain
fonte
0

Você deve definir em vez de adicionar para substituir o valor existente no índice.

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

A lista conterá [objeto1, objeto2]

Saurabh
fonte