Java ArrayList como adicionar elementos no início


183

Eu preciso adicionar elementos a um ArrayList fila, mas quando chamo a função para adicionar um elemento, quero que adicione o elemento no início da matriz (para que tenha o índice mais baixo) e se a matriz tiver 10 elementos adicionando um novo resulta na exclusão do elemento mais antigo (aquele com o índice mais alto).

Alguém tem alguma sugestão?


Você quer dizer como removee add?
— 22412 Peter Lawrey

O que você está usando arraylist stack queue whateverpara adicionar ao início de uma matriz é melhor evitar e parece que você deve usar uma coleção diferente.
— 22412 Peter Lawrey

Primeiro, você deve fazer algo você mesmo. O que você fez até agora?
— Yegoshin Maxim 18/10/12

Respostas:


301

Listtem o método add(int, E), então você pode usar:

list.add(0, yourObject);

Depois, você pode excluir o último elemento com:

if(list.size() > 10)
    list.remove(list.size() - 1);

No entanto, convém repensar seus requisitos ou usar uma estrutura de dados diferente, como um Queue

EDITAR

Talvez dê uma olhada no Apache CircularFifoQueue:

CircularFifoQueue é uma fila primeiro a entrar, primeiro a sair, com um tamanho fixo que substitui o elemento mais antigo, se estiver cheio.

Apenas inicialize com seu tamanho máximo:

CircularFifoQueue queue = new CircularFifoQueue(10);

10
Eu não tocaria em nenhuma biblioteca apache com um poste de três metros, principalmente porque existem classes de coleção de goiaba. O EvictingQueue da Guava pode ser uma boa escolha aqui.
— DPM

26

Usando estruturas de dados específicas

Existem várias estruturas de dados que são otimizadas para adicionar elementos no primeiro índice. No entanto, lembre-se de que, se você converter sua coleção para uma delas, a conversa provavelmente precisará de uma complexidade de tempo e espaço deO(n)

Deque

O JDK inclui a Dequeestrutura que oferece métodos como addFirst(e)eofferFirst(e)

Deque<String> deque = new LinkedList<>();
deque.add("two");
deque.add("one");
deque.addFirst("three");
//prints "three", "two", "one"

Análise

A complexidade do espaço e do tempo de inserção é LinkedListconstante ( O(1)). Veja a folha de dicas do Big-O .

Invertendo a lista

Um método muito fácil, mas ineficiente, é usar reverse:

 Collections.reverse(list);
 list.add(elementForTop);
 Collections.reverse(list);

Se você usa fluxos Java 8, esta resposta pode lhe interessar.

Análise

  • Complexidade temporal: O(n)
  • Complexidade espacial: O(1)

Olhando para a implementação do JDK, isso tem uma O(n)complexidade de tempo, sendo adequado apenas para listas muito pequenas.


Invertendo uma lista duas vezes. Adicionará o tempo de execução do algoritmo por uma grande margem em comparação com a solução aceita acima?
— 21817 Samyak Upadhyay

Acrescenta 2N, então sim, mas se você tem lista de <50 você não seria capaz de micro referência a diferença na maioria das máquinas modernas
— Patrick Favre

8

Você pode dar uma olhada no add (int index, elemento E) :

Insere o elemento especificado na posição especificada nesta lista. Desloca o elemento atualmente nessa posição (se houver) e quaisquer elementos subsequentes para a direita (adiciona um aos seus índices).

Depois de adicionar, você pode verificar o tamanho do ArrayList e removê-los no final.


4

Você pode querer olhar para Deque. fornece acesso direto ao primeiro e ao último itens da lista.


1
Estou surpreso que você seja a única resposta falando sobre o Deque, essa é obviamente a melhor solução ideal.
— Guillaume F.

3

O que você está descrevendo é uma situação apropriada para usar Queue .

Desde que você deseja addnovo elemento, eremove o antigo. Você pode adicionar no final e remover do início. Isso não fará muita diferença.

A fila possui métodos add(e)e remove()que adiciona ao final o novo elemento e remove desde o início o elemento antigo, respectivamente.

Queue<Integer> queue = new LinkedList<Integer>();
queue.add(5);
queue.add(6);
queue.remove();  // Remove 5

Portanto, toda vez que você adiciona um elemento ao queuevocê pode fazer backup com uma removechamada de método.


ATUALIZAÇÃO : -

E se você quiser corrigir o tamanho doQueue , poderá dar uma olhada em: -ApacheCommons#CircularFifoBuffer

Desde documentation: -

O CircularFifoBuffer é um buffer primeiro a entrar, com um tamanho fixo que substitui o elemento mais antigo se estiver cheio.

Buffer queue = new CircularFifoBuffer(2); // Max size

queue.add(5);
queue.add(6);
queue.add(7);  // Automatically removes the first element `5`

Como você pode ver, quando o tamanho máximo é atingido, a adição de um novo elemento remove automaticamente o primeiro elemento inserido.


1

Eu acho que o implemento deve ser fácil, mas considerando a eficiência, você deve usar o LinkedList, mas não o ArrayList como contêiner. Você pode consultar o seguinte código:

import java.util.LinkedList;
import java.util.List;

public class DataContainer {

    private List<Integer> list;

    int length = 10;
    public void addDataToArrayList(int data){
        list.add(0, data);
        if(list.size()>10){
            list.remove(length);
        }
    }

    public static void main(String[] args) {
        DataContainer comp = new DataContainer();
        comp.list = new LinkedList<Integer>();

        int cycleCount = 100000000;

        for(int i = 0; i < cycleCount; i ++){
            comp.addDataToArrayList(i);
        }
    }
}


0

você pode usar esse código

private List myList = new ArrayList();
private void addItemToList(Object obj){
    if(myList.size()<10){
      myList.add(0,obj);
    }else{
      myList.add(0,obj);
      myList.remove(10);
    }
}

0

Você pode usar métodos de lista, remover e adicionar

list.add(lowestIndex, element);
list.remove(highestIndex, element);

0

Veja este exemplo: -

List<String> element1 = new ArrayList<>();
element1.add("two");
element1.add("three");
List<String> element2 = new ArrayList<>();
element2.add("one");
element2.addAll(element1);

-1

Você pode usar

public List<E> addToListStart(List<E> list, E obj){
list.add(0,obj);
return (List<E>)list;

}

Mude E com seu tipo de dados

Se a exclusão do elemento mais antigo for necessária, você poderá adicionar:

list.remove(list.size()-1); 

antes da declaração de retorno. Caso contrário, a lista adicionará seu objeto no início e também manterá o elemento mais antigo.

Isso excluirá o último elemento da lista.


-1
import java.util.*:
public class Logic {
  List<String> list = new ArrayList<String>();
  public static void main(String...args) {
  Scanner input = new Scanner(System.in);
    Logic obj = new Logic();
      for (int i=0;i<=20;i++) {
        String string = input.nextLine();
        obj.myLogic(string);
        obj.printList();
      }
 }
 public void myLogic(String strObj) {
   if (this.list.size()>=10) {
      this.list.remove(this.list.size()-1);
   } else {
     list.add(strObj); 
   }
 }
 public void printList() {
 System.out.print(this.list);
 }
}

-2

Eu tive um problema semelhante, tentando adicionar um elemento no início de uma matriz existente, mudar os elementos existentes para a direita e descartar o mais antigo (matriz [comprimento-1]). Minha solução pode não ter muito desempenho, mas funciona para meus propósitos.

 Method:

   updateArray (Element to insert)

     - for all the elements of the Array
       - start from the end and replace with the one on the left; 
     - Array [0] <- Element

Boa sorte

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.