wake-up-neo.com

Doppelte Werte aus ArrayList entfernen

Ich habe eine Arrayliste von String und habe einige doppelte Werte hinzugefügt. und ich möchte nur den doppelten Wert entfernen. So entfernen Sie ihn. 

Hier Beispiel Ich habe eine Idee.

List<String> list = new ArrayList<String>();
        list.add("Krishna");
        list.add("Krishna");
        list.add("Kishan");
        list.add("Krishn");
        list.add("Aryan");
        list.add("Harm");

        System.out.println("List"+list);

        for (int i = 1; i < list.size(); i++) {
            String a1 = list.get(i);
            String a2 = list.get(i-1);
            if (a1.equals(a2)) {
                list.remove(a1);
            }
        }

        System.out.println("List after short"+list);

Aber gibt es eine ausreichende Möglichkeit, die Liste der doppelten Formulare zu entfernen. ohne Verwendung der For-Schleife? Und ja, ich kann es mit HashSet oder auf andere Weise tun, aber nur mit der Array-Liste .... Möchte Ihren Vorschlag dazu haben. Vielen Dank für Ihre Antwort im Voraus.

18
Krishna

Sie können eine LinkedHashSet aus der Liste erstellen. Die Variable LinkedHashSet enthält jedes Element nur einmal und in derselben Reihenfolge wie die Variable List. Erstellen Sie dann eine neue List aus dieser LinkedHashSet. So effektiv ist es ein Einzeiler:

list = new ArrayList<String>(new LinkedHashSet<String>(list))

Jeder Ansatz, der List#contains oder List#remove beinhaltet, wird wahrscheinlich die asymptotische Laufzeit von O(n) (wie im obigen Beispiel) auf O (n ^ 2) reduzieren. 


EDITFür die im Kommentar erwähnte Anforderung: Wenn Sie doppelte Elemente entfernen möchten, die Strings jedoch als gleichwertig betrachten und den Fall ignorieren möchten, könnten Sie Folgendes tun:

Set<String> toRetain = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
toRetain.addAll(list);
Set<String> set = new LinkedHashSet<String>(list);
set.retainAll(new LinkedHashSet<String>(toRetain));
list = new ArrayList<String>(set);

Es wird eine Laufzeit von O (n * logn) haben, was immer noch besser ist als viele andere Optionen. Beachten Sie, dass dies etwas komplizierter aussieht, als es sein muss: Ich nahm an, dass die Reihenfolge der Elemente in der Liste nicht geändert werden dürfen. Wenn die Reihenfolge der Elemente in der Liste keine Rolle spielt, können Sie dies einfach tun

Set<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
set.addAll(list);
list = new ArrayList<String>(set);
58
Marco13

wenn Sie nur Arraylist verwenden möchten, bin ich besorgt, dass es keinen besseren Weg gibt, der einen enormen Leistungsvorteil schafft. Aber indem ich nur Arraylist verwende, würde ich das vor dem Hinzufügen in die Liste wie folgt überprüfen

void addToList(String s){
  if(!yourList.contains(s))
       yourList.add(s);
}

In diesen Fällen ist die Verwendung eines Sets geeignet.

11
stinepike

Sie können die unten gezeigten Google Guava-Dienstprogramme verwenden

 list = ImmutableSet.copyOf(list).asList(); 

Dies ist wahrscheinlich die effizienteste Methode, um die Duplikate aus der Liste zu entfernen, und interessanterweise erhält auch die Iterationsreihenfolge.

UPDATE

Wenn Sie Guava jedoch nicht einbeziehen möchten, können Sie Duplikate wie unten gezeigt entfernen.

ArrayList<String> list = new ArrayList<String>();
    list.add("Krishna");
    list.add("Krishna");
    list.add("Kishan");
    list.add("Krishn");
    list.add("Aryan");
    list.add("Harm");

System.out.println("List"+list);
HashSet hs = new HashSet();
hs.addAll(list);
list.clear();
list.addAll(hs);

Aber dies zerstört natürlich die Iterationsreihenfolge der Elemente in der ArrayList.

Shishir

9
Shishir Kumar

Java 8Streamfunktion 

Sie können die Funktion distinct wie oben verwenden, um die einzelnen Elemente der Liste abzurufen. 

stringList.stream().distinct();

Aus der Dokumentation 

Gibt einen Stream zurück, der aus den verschiedenen Elementen (gemäß Object.equals (Object)) dieses Streams besteht.


Wenn Sie die equals-Methode nicht verwenden möchten, verwenden Sie die Funktion collect wie folgt: 

stringList.stream()  
    .collect(Collectors.toCollection(() -> 
        new TreeSet<String>((p1, p2) -> p1.compareTo(p2)) 
));  

Aus der Dokumentation 

Führt mit dem Collector eine veränderliche Reduzierungsoperation für die Elemente dieses Streams durch. 

Hoffentlich hilft das.

5
List<String> list = new ArrayList<String>();
        list.add("Krishna");
        list.add("Krishna");
        list.add("Kishan");
        list.add("Krishn");
        list.add("Aryan");
        list.add("Harm");

HashSet<String> hs=new HashSet<>(list);

System.out.println("=========With Duplicate Element========");
System.out.println(list);
System.out.println("=========Removed Duplicate Element========");
System.out.println(hs);
3
RaviSoni
     public List<Contact> removeDuplicates(List<Contact> list) {
    // Set set1 = new LinkedHashSet(list);
    Set set = new TreeSet(new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
                 if(((Contact)o1).getId().equalsIgnoreCase(((Contact)2).getId()) ) {
                return 0;
            }
            return 1;
        }
    });
    set.addAll(list);
    final List newList = new ArrayList(set);
    return newList;
}

Einfache Funktion zum Entfernen von Duplikaten aus der Liste

private void removeDuplicates(List<?> list)
{
    int count = list.size();

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

Beispiel:
Eingabe: [1, 2, 2, 3, 1, 3, 3, 2, 3, 1, 2, 3, 3, 4, 4, 4, 1]
Ausgabe: [1, 2, 3, 4]

2
BRIJ

Ich glaube nicht, dass list = new ArrayList<String>(new LinkedHashSet<String>(list)) nicht der beste Weg ist, da wir das LinkedHashset verwenden (wir könnten direkt LinkedHashset anstelle von ArrayList verwenden), 

Lösung:

import Java.util.ArrayList;
public class Arrays extends ArrayList{

@Override
public boolean add(Object e) {
    if(!contains(e)){
        return super.add(e);
    }else{
        return false;
    }
}

public static void main(String[] args) {
    Arrays element=new Arrays();
    element.add(1);
    element.add(2);
    element.add(2);
    element.add(3);

    System.out.println(element);
}
}

Ausgabe: [1, 2, 3]

Hier erweitere ich die ArrayList, da ich sie mit einigen Änderungen verwende, indem ich die add-Methode überschreibe.

2
Manojkumar
public static void main(String[] args) {
    @SuppressWarnings("serial")
    List<Object> lst = new ArrayList<Object>() {
        @Override
        public boolean add(Object e) {
            if(!contains(e))
            return super.add(e);
            else
            return false;
        }
    };
    lst.add("ABC");
    lst.add("ABC");
    lst.add("ABCD");
    lst.add("ABCD");
    lst.add("ABCE");
    System.out.println(lst);

}

Das ist der bessere Weg

1

list = list.stream().distinct().collect(Collectors.toList());
Dies könnte eine der Lösungen sein, die die Java8-Stream-API verwenden. Hoffe das hilft.

1
Nisarg Patil

Dies wird der beste Weg sein

    List<String> list = new ArrayList<String>();
    list.add("Krishna");
    list.add("Krishna");
    list.add("Kishan");
    list.add("Krishn");
    list.add("Aryan");
    list.add("Harm");

    Set<String> set=new HashSet<>(list);

Ohne Schleife, Nein ! Da ArrayList nach Reihenfolge und nicht nach Schlüssel indiziert wird, können Sie das Zielelement nicht ohne die gesamte Liste durchlaufen.

Eine gute Programmiermethode besteht darin, die richtige Datenstruktur für Ihr Szenario auszuwählen. Wenn also Set am besten zu Ihrem Szenario passt, ist die Diskussion über die Implementierung mit List und die Suche nach dem schnellsten Weg, eine ungeeignete Datenstruktur zu verwenden, nicht sinnvoll.

1
Weibo Li

Es ist besser, HastSet zu verwenden.

1-a) Ein HashSet enthält eine Menge von Objekten, aber auf eine Weise, mit der Sie schnell und einfach feststellen können, ob sich ein Objekt bereits in der Menge befindet oder nicht. Dazu wird intern ein Array verwaltet und das Objekt mit einem Index gespeichert, der aus dem Hashcode des Objekts berechnet wird. Schauen Sie sich hier um

1-b) HashSet ist eine ungeordnete Sammlung mit eindeutigen Elementen. Es verfügt über die Standardauflistungsvorgänge Hinzufügen, Entfernen, Enthält, aber da es eine Hash-basierte Implementierung verwendet, sind diese Vorgänge O (1). (Im Gegensatz zu List ist dies beispielsweise O(n) für "Enthält" und "Entfernen".) HashSet bietet auch Standardvorgänge wie Vereinigung, Schnittmenge und symmetrische Differenz. Schauen Sie hier nach

2) Es gibt verschiedene Implementierungen von Sets. Einige machen Einfügungs- und Nachschlageoperationen durch Hash-Elemente superschnell. Das bedeutet jedoch, dass die Reihenfolge, in der die Elemente hinzugefügt wurden, verloren geht. Bei anderen Implementierungen wird die hinzugefügte Reihenfolge auf Kosten langsamerer Laufzeiten beibehalten.

Die HashSet-Klasse in C # gilt für den ersten Ansatz, sodass die Reihenfolge der Elemente nicht beibehalten wird. Es ist viel schneller als eine normale Liste. Einige grundlegende Benchmarks zeigten, dass HashSet beim Umgang mit Primärtypen (int, double, bool usw.) anständig schneller ist. Bei der Arbeit mit Klassenobjekten geht es wesentlich schneller. Dieser Punkt ist also, dass HashSet schnell ist.

Der einzige Haken von HashSet ist, dass es keinen Zugriff auf Indizes gibt. Um auf Elemente zuzugreifen, können Sie entweder einen Enumerator verwenden oder die integrierte Funktion verwenden, um das HashSet in eine Liste zu konvertieren und diese zu durchlaufen. Schauen Sie hier nach

1
Furquan Khan

Verwendung von Java 8:

public static <T> List<T> removeDuplicates(List<T> list) {
    return list.stream().collect(Collectors.toSet()).stream().collect(Collectors.toList());
}
0
Brice Roncace
public static List<String> removeDuplicateElements(List<String> array){
    List<String> temp = new ArrayList<String>();
    List<Integer> count = new ArrayList<Integer>();
    for (int i=0; i<array.size()-2; i++){
        for (int j=i+1;j<array.size()-1;j++)
            {
                if (array.get(i).compareTo(array.get(j))==0) {
                    count.add(i);
                    int kk = i;
                }
            }
        }
        for (int i = count.size()+1;i>0;i--) {
            array.remove(i);
        }
        return array;
    }
}
0
leeyang

Falls Sie die Duplikate nur mit ArrayList und keinen anderen Collection-Klassen entfernen müssen, gehen Sie wie folgt vor: 

//list is the original arraylist containing the duplicates as well
List<String> uniqueList = new ArrayList<String>();
    for(int i=0;i<list.size();i++) {
        if(!uniqueList.contains(list.get(i)))
            uniqueList.add(list.get(i));
    }

Hoffe das hilft!

0
iamharish15
private static void removeDuplicates(List<Integer> list)
{
    Collections.sort(list);
    int count = list.size();
    for (int i = 0; i < count; i++) 
    {
        if(i+1<count && list.get(i)==list.get(i+1)){
            list.remove(i);
            i--;
            count--;
        }
    }
}
0
sid