563 Stimmen

Wie kann ich wiederholte Elemente aus ArrayList entfernen?

Ich habe eine ArrayList<String> und ich möchte wiederholte Zeichenfolgen daraus entfernen. Wie kann ich das tun?

21voto

CarlJohn Punkte 727

Es ist möglich, Duplikate aus arraylist zu entfernen, ohne HashSet o eine weitere Arrayliste .

Versuchen Sie diesen Code.

    ArrayList<String> lst = new ArrayList<String>();
    lst.add("ABC");
    lst.add("ABC");
    lst.add("ABCD");
    lst.add("ABCD");
    lst.add("ABCE");

    System.out.println("Duplicates List "+lst);

    Object[] st = lst.toArray();
      for (Object s : st) {
        if (lst.indexOf(s) != lst.lastIndexOf(s)) {
            lst.remove(lst.lastIndexOf(s));
         }
      }

    System.out.println("Distinct List "+lst);

Die Ausgabe ist

Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]

12voto

volley Punkte 6555

Wahrscheinlich ist das ein bisschen übertrieben, aber ich mag diese Art von isolierten Problemen :)

Dieser Code verwendet ein temporäres Set (für die Eindeutigkeitsprüfung), entfernt aber die Elemente direkt aus der ursprünglichen Liste. Da das Entfernen von Elementen innerhalb einer ArrayList eine große Menge an Array-Kopien verursachen kann, wird die remove(int)-Methode vermieden.

public static <T> void removeDuplicates(ArrayList<T> list) {
    int size = list.size();
    int out = 0;
    {
        final Set<T> encountered = new HashSet<T>();
        for (int in = 0; in < size; in++) {
            final T t = list.get(in);
            final boolean first = encountered.add(t);
            if (first) {
                list.set(out++, t);
            }
        }
    }
    while (out < size) {
        list.remove(--size);
    }
}

Wenn wir schon dabei sind, hier ist eine Version für LinkedList (viel schöner!):

public static <T> void removeDuplicates(LinkedList<T> list) {
    final Set<T> encountered = new HashSet<T>();
    for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
        final T t = iter.next();
        final boolean first = encountered.add(t);
        if (!first) {
            iter.remove();
        }
    }
}

Verwenden Sie die Marker-Schnittstelle, um eine einheitliche Lösung für List zu präsentieren:

public static <T> void removeDuplicates(List<T> list) {
    if (list instanceof RandomAccess) {
        // use first version here
    } else {
        // use other version here
    }
}

EDIT: Ich schätze, dass das generische Zeug hier keinen wirklichen Mehrwert bringt. Tja. :)

12voto

public static void main(String[] args){
    ArrayList<Object> al = new ArrayList<Object>();
    al.add("abc");
    al.add('a');
    al.add('b');
    al.add('a');
    al.add("abc");
    al.add(10.3);
    al.add('c');
    al.add(10);
    al.add("abc");
    al.add(10);
    System.out.println("Before Duplicate Remove:"+al);
    for(int i=0;i<al.size();i++){
        for(int j=i+1;j<al.size();j++){
            if(al.get(i).equals(al.get(j))){
                al.remove(j);
                j--;
            }
        }
    }
    System.out.println("After Removing duplicate:"+al);
}

5voto

Craig P. Motlin Punkte 26028

Wenn Sie bereit sind, eine Bibliothek eines Drittanbieters zu verwenden, können Sie die Methode distinct() en Eclipse-Kollektionen (ehemals GS Sammlungen).

ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
    FastList.newListWith(1, 3, 2),
    integers.distinct());

Der Vorteil der Verwendung von distinct() anstelle der Umwandlung in eine Menge und dann zurück in eine Liste ist, dass distinct() behält die Reihenfolge der ursprünglichen Liste bei, wobei das erste Vorkommen jedes Elements beibehalten wird. Sie wird durch die Verwendung einer Menge und einer Liste implementiert.

MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
    T item = list.get(i);
    if (seenSoFar.add(item))
    {
        targetCollection.add(item);
    }
}
return targetCollection;

Wenn Sie Ihre ursprüngliche Liste nicht in einen Eclipse Collections-Typ konvertieren können, können Sie ListAdapter verwenden, um die gleiche API zu erhalten.

MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();

Anmerkung: Ich bin ein Committer für Eclipse Collections.

5voto

Wenn Sie den Modelltyp List< T>/ArrayList< T> verwenden, wird Ihnen das hoffentlich helfen.

Hier ist mein Code ohne Verwendung einer anderen Datenstruktur wie set oder hashmap

for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {       
 if (Models.get(i).getName().equals(Models.get(j).getName())) {    
 Models.remove(j);
   j--;
  }
 }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X