Qual é a melhor maneira de remover o primeiro elemento de uma matriz?

86

Eu tenho string array ( String[]) e preciso remover o primeiro item. Como posso fazer isso com eficiência?

NullVoxPopuli
fonte
4
Não é um idiota. A pergunta anterior é sobre a remoção de itens por valor; trata-se de remover um item por índice.
james.garriss

Respostas:

154

O tamanho dos arrays em Java não pode ser alterado. Portanto, tecnicamente você não pode remover nenhum elemento do array.

Uma maneira de simular a remoção de um elemento da matriz é criar uma nova matriz menor e, a seguir, copiar todos os elementos da matriz original para a nova matriz menor.

String[] yourArray = Arrays.copyOfRange(oldArr, 1, oldArr.length);

No entanto , eu não sugeriria o método acima. Você realmente deveria estar usando um List<String>. As listas permitem adicionar e remover itens de qualquer índice. Isso seria semelhante ao seguinte:

List<String> list = new ArrayList<String>(); // or LinkedList<String>();
list.add("Stuff");
// add lots of stuff
list.remove(0); // removes the first item
jjnguy
fonte
32
É importante notar que remover o primeiro elemento de an ArrayListé O (n).
Matthew Flaschen,
1
@Matt, para um array e a lista. Mas, o código é muito mais fácil para a lista.
jjnguy
16
Para um array e um ArrayList, mas não para LinkedList.
Matthew Flaschen,
4
Em) ? bem .. em uma matriz C? para remover o primeiro elemento você pode simplesmente incrementar o ponteiro O (1)
Hernán Eche
2
Para aqueles que usam Java para Android como eu, Arrays.copyOfRange()é para API9 +
Sdghasemi
14

A maneira mais simples é provavelmente a seguinte - você basicamente precisa construir um novo array que seja um elemento menor e, em seguida, copiar os elementos que deseja manter nas posições corretas.

int n=oldArray.length-1;
String[] newArray=new String[n];
System.arraycopy(oldArray,1,newArray,0,n);

Observe que, se você se pega fazendo esse tipo de operação com frequência, pode ser um sinal de que deveria estar usando um tipo diferente de estrutura de dados, por exemplo, uma lista vinculada. Construir um novo array toda vez é uma operação O (n), que pode sair caro se o seu array for grande. Uma lista encadeada daria a você O (1) remoção do primeiro elemento.

Uma ideia alternativa é não remover o primeiro item, mas apenas incrementar um número inteiro que aponta para o primeiro índice que está em uso. Os usuários do array precisarão levar esse deslocamento em consideração, mas essa pode ser uma abordagem eficiente. A classe Java String, na verdade, usa esse método internamente ao criar substrings.

Mikera
fonte
4
Esta não é tecnicamente a maneira mais fácil. Arrays.copyOfRange()é.
jjnguy
4
Como ele está usando Java6, ele pode usar o mais compacto Arrays.copyOfRange
Thilo
1
@ Justin - claro, mas apenas se você estiver direcionando o Java 1.6 ou superior
mikera
1
verdadeiro. Nem sempre é aplicável.
jjnguy
6
o título da pergunta deixa claro que o OP está interessado em respostas para Java 1.6 e superior.
Stephen C,
5

Você não pode fazer nada, muito menos rapidamente. Arrays em Java são de tamanho fixo. Duas coisas que você pode fazer são:

  1. Mude cada elemento um para cima e defina o último elemento como nulo.
  2. Crie uma nova matriz e copie-a.

Você pode usar System.arraycopypara qualquer um deles. Ambos são O (n), uma vez que copiam todos, exceto 1 elemento.

Se você for remover o primeiro elemento com frequência, considere usá-lo LinkedList. Você pode usar LinkedList.remove, que é da Queueinterface, por conveniência. Com LinkedList, a remoção do primeiro elemento é O (1). Na verdade, remover qualquer elemento é O (1), uma vez que você tenha um ListIteratorpara essa posição. No entanto, acessar um elemento arbitrário por índice é O (n).

Matthew Flaschen
fonte
2

Mantenha um índice do primeiro elemento "ativo" da matriz. Remover (fingir remover) o primeiro elemento torna-se então uma O(1)operação de complexidade de tempo.

msw
fonte
0

Para resumir, o método de lista vinculada rápida:

List<String> llist = new LinkedList<String>(Arrays.asList(oldArray));
llist.remove(0);
mjad-org
fonte
-8

Um método alternativo feio:

   String[] a ={"BLAH00001","DIK-11","DIK-2","MAN5"};
   String[] k=Arrays.toString(a).split(", ",2)[1].split("]")[0].split(", ");
Emil
fonte
2
Por favor, alguém com reputação suficiente votou negativamente nesta resposta - é exatamente o que diz que é - feia! Sem intenção de ser rude, mas no interesse da codeabilidade, não poste esse tipo de coisa!
Hack5
se você já estiver usando Arrays, seria melhor usar Arrays.copyOfRange
Bishal Gautam
Ele pediu a melhor maneira.
Sapphire_Brick
exclua-o e veja quanta reputação você ganhará.
Sapphire_Brick