Pergunta

Dada uma série de n Objetos, vamos dizer que é um array de strings , e tem os seguintes valores:

foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";

O que eu tenho que fazer para eliminar / remover todas as cordas / objetos igual a "a" na matriz?

Foi útil?

Solução

[Se você quiser algum código ready-to-use, por favor, vá para o meu "Edit3" (após o corte). O resto está aqui para a posteridade.]

Para aperfeiçoar a do Dustman ideia :

List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);

Edit: eu estou usando agora Arrays.asList vez de Collections.singleton: singleton é limitada a uma entrada, enquanto que a abordagem asList permite adicionar outras cordas para filtrar mais tarde:. Arrays.asList("a", "b", "c")

Edit2: A abordagem acima mantém a mesma matriz (de modo que a matriz é ainda o mesmo comprimento); o elemento após o último é definido como nulo. Se você quer um new matriz de tamanho exatamente como necessário, use esta em vez disso:

array = list.toArray(new String[0]);

Edit3: Se você usar esse código em uma base freqüente na mesma classe, você pode querer considerar adicionar esta a sua classe:

private static final String[] EMPTY_STRING_ARRAY = new String[0];

Em seguida, a função torna-se:

List<String> list = new ArrayList<>();
Collections.addAll(list, array);
list.removeAll(Arrays.asList("a"));
array = list.toArray(EMPTY_STRING_ARRAY);

Este, então, parar de jogar lixo sua pilha com matrizes de cadeia vazios inúteis que de outra forma seriam newed cada vez que sua função é chamada.

A sugestão de cynicalman (ver comentários) também ajuda com o lixo amontoado, e para a equidade estava devem mencionar:

array = list.toArray(new String[list.size()]);

Eu prefiro a minha abordagem, porque ele pode ser mais fácil de obter o errado tamanho explícita (por exemplo, chamando size() na lista errada).

Outras dicas

Uma alternativa em Java 8:

String[] filteredArray = Arrays.stream(array)
    .filter(e -> !e.equals(foo)).toArray(String[]::new);

Faça um List fora da matriz com Arrays.asList() e remove() chamada em todos os elementos adequados. Em seguida, chamar toArray() na 'Lista' para fazer volta em uma matriz novamente.

Não terrivelmente alto desempenho, mas se você encapsular-lo corretamente, você sempre pode fazer algo mais rápido mais tarde.

Você sempre pode fazer:

int i, j;
for (i = j = 0; j < foo.length; ++j)
  if (!"a".equals(foo[j])) foo[i++] = foo[j];
foo = Arrays.copyOf(foo, i);

Você pode usar biblioteca externa:

org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)

É no projeto Apache Commons Lang http://commons.apache.org/lang/

Veja código abaixo

ArrayList<String> a = new ArrayList<>(Arrays.asList(strings));
a.remove(i);
strings = new String[a.size()];
a.toArray(strings);

Se você precisar remover vários elementos do array sem convertê-lo para List nem a criação de gama adicional, você pode fazê-lo em O (n) não depende de contagem de itens para remover.

Aqui, a é matriz inicial, int... r são índices distintos ordenados (posições) de elementos a serem removidos:

public int removeItems(Object[] a, int... r) {
    int shift = 0;                             
    for (int i = 0; i < a.length; i++) {       
        if (shift < r.length && i == r[shift])  // i-th item needs to be removed
            shift++;                            // increment `shift`
        else 
            a[i - shift] = a[i];                // move i-th item `shift` positions left
    }
    for (int i = a.length - shift; i < a.length; i++)
        a[i] = null;                            // replace remaining items by nulls

    return a.length - shift;                    // return new "length"
}  

teste pequeno:

String[] a = {"0", "1", "2", "3", "4"};
removeItems(a, 0, 3, 4);                     // remove 0-th, 3-rd and 4-th items
System.out.println(Arrays.asList(a));        // [1, 2, null, null, null]

Na sua tarefa, você pode primeira matriz de digitalização para posições de coleta de "a", em seguida, chamar removeItems().

Algo sobre a fazer uma lista dos que, em seguida, remover, em seguida, volta para uma matriz me parece errado. Não testei, mas eu acho o seguinte terá um desempenho melhor. Sim, eu sou provavelmente indevidamente pré-otimizar.

boolean [] deleteItem = new boolean[arr.length];
int size=0;
for(int i=0;i<arr.length;i==){
   if(arr[i].equals("a")){
      deleteItem[i]=true;
   }
   else{
      deleteItem[i]=false;
      size++;
   }
}
String[] newArr=new String[size];
int index=0;
for(int i=0;i<arr.length;i++){
   if(!deleteItem[i]){
      newArr[index++]=arr[i];
   }
}

Sei que este é um post muito antiga, mas algumas das respostas aqui me ajudou a sair, então aqui está a minha tuppence' o valor do ha'penny!

Lutei começar este trabalho por um bom tempo antes de antes twigging que a matriz que eu estou escrevendo de volta para precisava ser redimensionada, a menos que as alterações feitas no ArrayList deixar o tamanho da lista inalterada.

Se o ArrayList que você está modificando termina com maior ou menos elementos do que começou com o List.toArray() linha irá causar uma exceção, então você precisa de algo como List.toArray(new String[] {}) ou List.toArray(new String[0]), a fim de criar uma matriz com o novo (correta ) tamanho.

Parece óbvio agora que eu sei. Não tão óbvio para um novato Android / Java quem chegar ao confronto com novas e desconhecidas construções de código e não óbvias de alguns dos posts anteriores aqui, então só queria fazer este ponto muito claro para qualquer outra pessoa a coçar a cabeça por horas como se eu fosse !

Existem muitas respostas aqui - o problema que eu vejo é que você não disse porque você está usando uma matriz em vez de uma coleção, então deixe-me sugerir algumas razões e quais soluções seriam aplicáveis ??(maioria as soluções já foram respondidas em outras questões aqui, então eu não vou entrar em muito detalhe):

razão: Você não sabia que o pacote de coleta existiu ou não confiar nele

solução: Use uma coleção.

Se você está pensando em adicionar / excluir a partir do meio, use um LinkedList. Se você está realmente preocupado com o tamanho ou muitas vezes indicador direito para o meio da coleta usar um ArrayList. Ambos devem ter operações de exclusão.

motivo: Você está preocupado com o tamanho ou quer controle sobre a alocação de memória

solução:. Use um ArrayList com um tamanho inicial específicos

Um ArrayList é simplesmente uma matriz que pode expandir-se, mas nem sempre é necessário para fazê-lo. Vai ser muito inteligente sobre adição / remoção de itens, mas novamente se você inserir / remover um lote a partir do meio, use um LinkedList.

motivo: você tiver uma matriz entrando e uma variedade de sair - assim que você quer operar em um array

Solução: Converter-lo para um ArrayList, excluir o item e convertê-lo de volta

motivo: Você acha que pode escrever um código melhor se você fazê-lo sozinho

solução:. Você não pode, usar uma Matriz ou lista Linked

razão: esta é uma atribuição de classe e você não tem permissão ou você não tem acesso às APIs de coleta por alguma razão

suposição: Você precisa da nova matriz para ser o "tamanho" correta

solução: Digitalizar a matriz para artigos de harmonização e contá-los. Criar uma nova matriz do tamanho correto (tamanho original - número de jogos). uso System.arraycopy repetidamente para copiar cada grupo de itens que você deseja manter em sua nova matriz. Se esta é uma atribuição de classe e você não pode usar System.arraycopy, apenas copiá-los um de cada vez com a mão em um loop, mas não nunca fazer isso no código de produção, porque é muito mais lento. (Estas soluções são ambos detalhado em outras respostas)

motivo: você precisa executar bare metal

suposição: Você não deve alocar espaço desnecessariamente ou demorar demais

suposição:. Você está controlando o tamanho utilizado na matriz (comprimento) separadamente porque senão você teria que realocar sua matriz para exclusões / inserções

Um exemplo de por que você pode querer fazer isso: uma única matriz de primitivos (int valores digamos de LET) está tomando uma parte significativa do seu carneiro - como 50%! Um ArrayList forçaria los em uma lista de ponteiros para objetos inteiro que usaria algumas vezes essa quantidade de memória.

solução: iterar sobre sua matriz e sempre que você encontrar um elemento para remover (vamos chamá-lo elemento n), o uso System.arraycopy para copiar a cauda da matriz sobre o "excluído" elemento (origem e destino são mesmo array) --é inteligente o suficiente para fazer a cópia na direção correta para que a memória não substituir-se:

 System.arraycopy(ary, n+1, ary, n, length-n) 
 length--;

Você provavelmente vai querer ser mais esperto do que isso, se estiver a eliminar mais de um elemento de cada vez. Você só iria mover a área entre um "jogo" e no próximo, em vez de toda a cauda e, como sempre, evite mover qualquer pedaço duas vezes.

Neste último caso, é absolutamente necessário fazer o trabalho sozinho, e usando System.arraycopy é realmente a única maneira de fazê-lo, uma vez que vai escolher o caminho melhor, possivelmente, para a memória movimento para sua arquitetura de computadores - deve ser muitas vezes mais rápido do que qualquer código que você poderia razoavelmente escrever-se.

EDIT:

O ponto com os valores nulos na matriz foi apagada. Desculpem-me por meus comentários.

Original:

Ehm ... a linha

array = list.toArray(array);

substitui todas as aberturas na matriz em que o elemento foi removido com nulo . Isso pode ser perigoso , porque os elementos são removidos, mas o comprimento da matriz continua a mesma!

Se você quiser evitar isso, use um new Array como parâmetro para toArray (). Se você don `t quer usar removeAll, um conjunto seria uma alternativa:

        String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

        System.out.println(Arrays.toString(array));

        Set<String> asSet = new HashSet<String>(Arrays.asList(array));
        asSet.remove("a");
        array = asSet.toArray(new String[] {});

        System.out.println(Arrays.toString(array));

Dá:

[a, bc, dc, a, ef]
[dc, ef, bc]

Onde como a resposta aceita atual de Chris Yester Jovens saídas:

[a, bc, dc, a, ef]
[bc, dc, ef, null, ef]

com o código

    String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

    System.out.println(Arrays.toString(array));

    List<String> list = new ArrayList<String>(Arrays.asList(array));
    list.removeAll(Arrays.asList("a"));
    array = list.toArray(array);        

    System.out.println(Arrays.toString(array));

sem quaisquer valores nulos deixado para trás.

A minha pequena contribuição para este problema.

public class DeleteElementFromArray {
public static String foo[] = {"a","cc","a","dd"};
public static String search = "a";


public static void main(String[] args) {
    long stop = 0;
    long time = 0;
    long start = 0;
    System.out.println("Searched value in Array is: "+search);
    System.out.println("foo length before is: "+foo.length);
    for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
    System.out.println("==============================================================");
    start = System.nanoTime();
    foo = removeElementfromArray(search, foo);
    stop = System.nanoTime();
    time = stop - start;
    System.out.println("Equal search took in nano seconds = "+time);
    System.out.println("==========================================================");
    for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
}
public static String[] removeElementfromArray( String toSearchfor, String arr[] ){
     int i = 0;
     int t = 0;
     String tmp1[] = new String[arr.length];     
         for(;i<arr.length;i++){
              if(arr[i] == toSearchfor){     
              i++;
              }
             tmp1[t] = arr[i];
             t++;
     }   
     String tmp2[] = new String[arr.length-t];   
     System.arraycopy(tmp1, 0, tmp2, 0, tmp2.length);
     arr = tmp2; tmp1 = null; tmp2 = null;
    return arr;
}

}

matriz inicial

   int[] array = {5,6,51,4,3,2};

Se você quiser remover 51, que é o índice 2, use o seguinte

 for(int i = 2; i < array.length -1; i++){
    array[i] = array[i + 1];
  }

Depende do que você entende por "Remover"? Uma matriz é uma construção tamanho fixo - você não pode alterar o número de elementos nele. Então você pode a) criar um novo, mais curto, array sem os elementos que você não quer ou b) atribuir as entradas que não querem algo que indica seu status 'vazio'; geralmente nulo se você não está trabalhando com primitivos.

No primeiro caso, criar uma lista a partir da matriz, remova os elementos e criar uma nova matriz da lista. Se o desempenho é iterate importante sobre a matriz atribuir quaisquer elementos que não devem ser removidos para uma lista e, em seguida, criar uma nova matriz da lista. No segundo caso, simplesmente passar e nulo atribuir às entradas da matriz.

Arrgh, eu não posso obter o código para mostrar corretamente. Desculpe, eu tenho que trabalhar. Desculpe novamente, eu não acho que eu li a pergunta corretamente.

String  foo[] = {"a","cc","a","dd"},
remove = "a";
boolean gaps[] = new boolean[foo.length];
int newlength = 0;

for (int c = 0; c<foo.length; c++)
{
    if (foo[c].equals(remove))
    {
        gaps[c] = true;
        newlength++;
    }
    else 
        gaps[c] = false;

    System.out.println(foo[c]);
}

String newString[] = new String[newlength];

System.out.println("");

for (int c1=0, c2=0; c1<foo.length; c1++)
{
    if (!gaps[c1])
    {
        newString[c2] = foo[c1];
        System.out.println(newString[c2]);
        c2++;
    }
}

Será que copiar todos os elementos, exceto aquele com o índice i:

if(i == 0){
                System.arraycopy(edges, 1, copyEdge, 0, edges.length -1 );
            }else{
                System.arraycopy(edges, 0, copyEdge, 0, i );
                System.arraycopy(edges, i+1, copyEdge, i, edges.length - (i+1) );
            }

Em uma matriz de strings como

String name = 'a b c d e um f b d e' // poderia ser como String name = 'aa bb c d e aa f bb d e'

I construir a seguinte classe

class clearname{
def parts
def tv
public def str = ''
String name
clearname(String name){
    this.name = name
    this.parts = this.name.split(" ")
    this.tv = this.parts.size()
}
public String cleared(){

        int i
        int k
        int j=0        
    for(i=0;i<tv;i++){
        for(k=0;k<tv;k++){
            if(this.parts[k] == this.parts[i] && k!=i){
               this.parts[k] = '';
                j++
            }
        }
    }
    def str = ''
    for(i=0;i<tv;i++){
        if(this.parts[i]!='')

           this.str += this.parts[i].trim()+' '
    } 
    return this.str    
}}



return new clearname(name).cleared()

obter este resultado

a b c d e f

Esperamos que este código ajuda ninguém Saudações

class sd 
{
 public static void main(String[ ] args)
 {
     System.out.println("Search and Delete");

    int key;
    System.out.println("Enter the length of array:");
    Scanner in=new Scanner(System.in);
    int n=in.nextInt();
    int numbers[]=new int[n];

      int i = 0;
      boolean found = false;  
      System.out.println("Enter the elements in Array :");
      for ( i = 0; i < numbers.length; i++)
      {
          numbers[i]=in.nextInt();
      }
      System.out.println("The elements in Array are:");
      for ( i = 0; i < numbers.length; i++)
      {
          System.out.println(numbers[i]);
      }
      System.out.println("Enter the element to be searched:");
      key=in.nextInt();
      for ( i = 0; i < numbers.length; i++)
      {
             if (numbers[ i ]  == key)
            {
                     found = true;      
                     break;
             }
       }
      if (found)   
      {
            System.out.println("Found " + key + " at index " + i + ".");
            numbers[i]=0;//haven't deleted the element in array
            System.out.println("After Deletion:");
        for ( i = 0; i < numbers.length; i++)
          {
              if (numbers[ i ]!=0)
            {   //it skips displaying element in array
                        System.out.println(numbers[i]);
            }
          }
      }
      else
      {
            System.out.println(key + "is not in this array.");
      }
  }
}//Sorry.. if there are mistakes.

Use:

list.removeAll(...);
//post what char you need in the ... section

Atribuir nulo para os locais de matriz.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top