2013-10-18 11 views
5

ci viene dato un elenco di parole in forma di un ArrayList come segue:Rimozione di stringhe di lunghezza determinata da un ArrayList?

public ArrayList<String> getListOfStrings(){ 
    ArrayList<String> list = new ArrayList<String>(); 
    list.add("This"); 
    list.add("is"); 
    list.add("an"); 
    list.add("exercise"); 
    list.add("to"); 
    list.add("illustrate"); 
    list.add("the"); 
    list.add("use");   
    list.add("of"); 
    list.add("ArrayLists");   
    list.add("."); 
    return list; 
    } 

Come faccio a scrivere un metodo che rimuove tutte le parole in quella lista (cioè tutti gli oggetti nel ArrayList) che hanno il lunghezza "len" inserita dall'utente?

ho già scritto un metodo che elenca tutte le parole di lunghezza "LEN" inserito dall'utente, e funziona, è come segue:

public ArrayList<String>getWordsWithLength(int len, ArrayList<String> lijst){ 
    ArrayList<String> list = new ArrayList<String>(); 
    for(String woord: lijst){ 
     if(woord.length()==len){ 
      list.add(woord); 
     } 
    } 
    return(list); 

} 

Ma, come un principiante in java, mi sono bloccato su come rimuovere le parole di lunghezza "len". Per favore aiuto! (Ho l'impressione che si inizi rimuovendoli dalla fine dell'elenco, in modo immediato)

+0

Si _remove_ non aggiungendoli alla nuova lista di ritorno. –

+5

cambia '==' a '! =' – Cruncher

+1

Anche all'indietro funzionerebbe, ma solo con un ciclo tradizionale 'for' (di' for (int i = list.size-1; i> = 0; i--) 'varietà.E 'preferibile la soluzione di AbstractChaos –

risposta

7

Il modo in cui l'iterazione corrente tramite l'elenco non consente di rimuoverlo con un'eccezione ma un iteratore lo farebbe.

Iterator<String> it = list.iterator(); 
while(it.hasNext()) { 
if([Condition]) { 
    it.remove(); 
    } 
} 
+1

Sei corretto, ma l'assegnazione specifica di utilizzare un semplice ciclo "for" come specificato da Richard Tingle in alto: "Funzionerebbe anche all'indietro, ma solo con un ciclo for tradizionale (della varietà for (int i = list.size-1; i> = 0; i--). La soluzione di AbstractChaos è pr tuttavia - " – user2895102

+1

@ user2895102 - Puoi tradurre il ciclo in alto anche in un ciclo for:' for (Iterator it = list.iterator(); it.hasNext();) ... ' – DaoWen

1

è necessario rimuovere valori da un List utilizzando un Iterator per prevenire un ConcurrentModificationException.

List<String> myList = getListOfStrings(); 
Iterator<String> it = myList.iterator(); 
while (it.hasNext()) { 
    if(it.next().length() == 3){ 
    it.remove(); 
    } 
} 
4

Il tuo metodo può già servire come una rimozione, basta cambiare il == ad un !=

public ArrayList<String> getStringsWithoutEqualLength(int len, ArrayList<String> lijst){ 
    ArrayList<String> list = new ArrayList<String>(); 
    for(String woord: lijst){ 
     if(woord.length() != len){ 
      list.add(woord); 
     } 
    } 
    return(list); 
} 

Se si sta tentando di fare è rimuovere gli elementi da lijst, poi basta riassegnare la lista restituita ad esso.

ArrayList<String> yourList = ...; 
yourList = instance.getStringsWithoutEqualLength(someLength, yourList); 

Hai efficacemente rimossi gli elementi più lunghi e fatto più velocemente di quanto se si fosse usato un Iterator. Ogni volta che rimuovi con un Iterator, devi ridimensionare l'array di backup.

+0

È davvero più veloce dell'uso di un' Iterator'? Li avrei calcolati all'incirca alla stessa velocità. 'Iterator' dovrebbe essere in grado di fare traslochi in tempo costante, giusto? O è solo per le liste collegate? – Cruncher

+0

@Cruncher Questo sarebbe per 'LinkedList'. Il 'ArrayList $ Itr' chiama' ArrayList # remove() 'che fa un' System.arraycopy' per l'array sottostante. –

+0

@SotiriosDelimanolis ma in realtà non è quello che stai facendo? Copiare l'ArrayList meno uno sarebbe simile a System.arraycopy eccetto che anche istanziate una gerarchia più profonda di classi? – AbstractChaos

0

È anche possibile utilizzare lo stesso metodo aggiungendo un parametro booleano.

public ArrayList<String>getWordsWithLength(int len, ArrayList<String> lijst, boolean complement){ 
    ArrayList<String> list = new ArrayList<String>(); 
    for(String woord: lijst){ 
     if((woord.length()==len) != complement){ 
      list.add(woord); 
     } 
    } 
    return(list); 

} 

se si passa in complement come true, se vi darà tutto con che non dispone di length == len. complement come false si comporterà come al solito.

0

Mentre penso che @ di SotiriosDelimanolis risposta è probabilmente quello che si dovrebbe usare, ho anche voluto sottolineare che con Java 8 si può facilmente farlo utilizzando un Stream e un Predicate per filtrare il:

List<String> list2 = list.stream() 
         .filter(s -> s.length() != 3) 
         .collect(Collectors.toList()); 

Ecco una classe di test completa:

import java.util.*; 
import java.util.stream.*; 

class Test { 
    public static void main(String args[]) { 
    ArrayList<String> list = new ArrayList<String>(); 
    list.add("This"); 
    list.add("is"); 
    list.add("an"); 
    list.add("exercise"); 
    list.add("to"); 
    list.add("illustrate"); 
    list.add("the"); 
    list.add("use"); 
    list.add("of"); 
    list.add("ArrayLists"); 
    list.add("."); 
    System.out.println(list); 
    List<String> list2 = list.stream() 
          .filter(s -> s.length() != 3) 
          .collect(Collectors.toList()); 
    System.out.println(list2); 
    } 
} 

e la mia uscita di test:

$ java Test 
[This, is, an, exercise, to, illustrate, the, use, of, ArrayLists, .] 
[This, is, an, exercise, to, illustrate, of, ArrayLists, .] 
0

in Scala, basta fare

list.filter(_.length != len) 
+0

In [Clojure] (http://clojure.org/) devi semplicemente fare '(rimuovere # (= (count%) len) my-list)' -ma il OP non ha chiesto di Scala o Clojure. Tuttavia, Java 8 _aggiunge_ aggiunge un pacchetto 'stream' di Scala-esque, che è quello che ho usato nella mia risposta. Peccato che non saremo in grado di aspettarci che le persone abbiano Java 8 per un altro anno o due ... – DaoWen