it-swarm.com.de

Wie entferne ich wiederholte Elemente aus ArrayList?

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

444
user25778

Wenn Sie keine Duplikate in einem Collection wünschen, sollten Sie überlegen, warum Sie ein Collection verwenden, das Duplikate zulässt. Wiederholte Elemente können Sie am einfachsten entfernen, indem Sie den Inhalt zu Set hinzufügen (was keine Duplikate zulässt) und dann Set wieder zu ArrayList hinzufügen:

Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);

Dies zerstört natürlich die Anordnung der Elemente in der ArrayList.

920

Wenn Sie die Variable ArrayList in eine Variable HashSet konvertieren, werden Duplikate zwar effektiv entfernt. Wenn Sie jedoch die Einfügungsreihenfolge beibehalten möchten, sollten Sie diese Variante verwenden

// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);

Wenn Sie dann eine List-Referenz zurückholen müssen, können Sie den Konvertierungskonstruktor erneut verwenden.

281
abahgat

In Java 8:

List<String> deduped = list.stream().distinct().collect(Collectors.toList());

Bitte beachten Sie, dass der hashCode-equals contract für Listenmitglieder beachtet werden sollte, damit die Filterung ordnungsgemäß funktioniert.

112

Wenn Sie keine Duplikate wünschen, verwenden Sie ein Set anstelle einer List. Um eine List in eine Set zu konvertieren, können Sie den folgenden Code verwenden:

// list is some List of Strings
Set<String> s = new HashSet<String>(list);

Wenn wirklich notwendig, können Sie dieselbe Konstruktion verwenden, um eine Set zurück in eine List zu konvertieren.

52
Benno Richters

Angenommen, wir haben eine Liste von String wie:

List<String> strList = new ArrayList<>(5);
// insert up to five items to list.        

Dann können wir doppelte Elemente auf verschiedene Arten entfernen.

Vor Java 8

List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));

Hinweis: Wenn wir die Einfügereihenfolge beibehalten möchten, müssen wir LinkedHashSet anstelle von HashSet verwenden.

Guave verwenden

List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));

Java verwenden 8

List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());

Anmerkung: Wenn wir das Ergebnis in einer spezifischen Listenimplementierung erfassen möchten, z. LinkedList dann können wir das obige Beispiel wie folgt ändern:

List<String> deDupStringList3 = strList.stream().distinct()
                 .collect(Collectors.toCollection(LinkedList::new));

Wir können parallelStream auch im obigen Code verwenden, aber es kann keine erwarteten Performance-Vorteile geben. Überprüfen Sie diese Frage für mehr.

44
i_am_zero

Hier ist eine Möglichkeit, die Ihre Listenreihenfolge nicht beeinflusst:

ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();

Iterator iterator = l1.iterator();

        while (iterator.hasNext())
        {
            YourClass o = (YourClass) iterator.next();
            if(!l2.contains(o)) l2.add(o);
        }

l1 ist die ursprüngliche Liste und l2 ist die Liste ohne wiederholte Elemente (Vergewissern Sie sich, dass YourClass die Methode equals hat, die Ihrer Gleichheit entspricht.

27
stbn

Sie können es auch so machen und die Ordnung bewahren:

// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
26
Nenad Bulatovic

Java 8-Streams bieten eine sehr einfache Möglichkeit, doppelte Elemente aus einer Liste zu entfernen. Verwenden der unterschiedlichen Methode ..__ Wenn wir eine Liste von Städten haben und Duplikate aus dieser Liste entfernen möchten, kann dies in einer einzigen Zeile erfolgen 

 List<String> cityList = new ArrayList<>();
 cityList.add("Delhi");
 cityList.add("Mumbai");
 cityList.add("Bangalore");
 cityList.add("Chennai");
 cityList.add("Kolkata");
 cityList.add("Mumbai");

 cityList = cityList.stream().distinct().collect(Collectors.toList());

So entfernen Sie doppelte Elemente aus einer Arrayliste

23
infoj

Es gibt auch ImmutableSet from Guava als Option ( hier ist die Dokumentation):

ImmutableSet.copyOf(list);
22

Duplikate können ohne Verwendung von HashSet oder einer weiteren Arraylist aus der Arrayliste entfernt werden. 

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);

Ausgabe ist

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

dies kann das Problem lösen:

private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {

Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
     cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}
12
user2868724

Wahrscheinlich ein bisschen übertrieben, aber ich mag dieses isolierte Problem. :)

Dieser Code verwendet ein temporäres Set (für die Überprüfung der Eindeutigkeit), entfernt jedoch Elemente direkt in der ursprünglichen Liste. Da das Entfernen von Elementen in einer ArrayList eine große Menge an Array-Kopien verursachen kann, wird die Methode remove (int) 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);
    }
}

Während wir gerade dabei sind, hier 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 Markierungsschnittstelle, um eine vereinheitlichte 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 denke, das Generics-Zeug bringt hier wirklich keinen Wert. Oh ja. :)

12
volley
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);
}
10

Wenn Sie eine Fremdanbieter-Bibliothek verwenden möchten, können Sie die Methode distinct() in Eclipse Collections (ehemals GS Collections) verwenden.

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 Konvertierung in ein Set und dann wieder in eine Liste besteht darin, dass distinct() die Reihenfolge der ursprünglichen Liste beibehält und das erste Vorkommen jedes Elements beibehält. Es wird implementiert, indem sowohl ein Set als auch eine Liste verwendet wird.

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-Auflistungstyp konvertieren können, können Sie ListAdapter verwenden, um dieselbe API zu erhalten.

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

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

5
Craig P. Motlin

Diese drei Codezeilen können das duplizierte Element aus ArrayList oder einer beliebigen Auflistung entfernen.

List<Entity> entities = repository.findByUserId(userId);

Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");

HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();
2
hardip

Code:

List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);

Hinweis: Auf jeden Fall wird Speicherüberhang entstehen.

2
sambhu

Wenn Sie den Modelltyp List <T>/ArrayList <T> verwenden. Hoffe, es hilft dir.


Hier ist mein Code, ohne eine andere Datenstruktur wie set oder Hashmap zu verwenden

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--;
                            }
                        }
                    }

Verwenden Sie beim Füllen der ArrayList für jedes Element eine Bedingung. Zum Beispiel:

    ArrayList< Integer > al = new ArrayList< Integer >(); 

    // fill 1 
    for ( int i = 0; i <= 5; i++ ) 
        if ( !al.contains( i ) ) 
            al.add( i ); 

    // fill 2 
    for (int i = 0; i <= 10; i++ ) 
        if ( !al.contains( i ) ) 
            al.add( i ); 

    for( Integer i: al )
    {
        System.out.print( i + " ");     
    }

Wir erhalten ein Array {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

2
HarpyWar

Wenn Sie Ihre Bestellung beibehalten möchten, verwenden Sie am besten LinkedHashSet . Wenn Sie diese Liste durch Iteration an eine Einfügeabfrage übergeben, wird die Reihenfolge beibehalten.

Versuche dies

LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);

Diese Konvertierung ist sehr hilfreich, wenn Sie eine Liste aber kein Set zurückgeben möchten.

2
ramakrishnan

LinkedHashSet macht den Trick.

String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
    System.out.println(s1);

System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
     System.out.println(arr3[i].toString());

// Ausgabe: 5,1,2,3,4

1
user1912383
        List<String> result = new ArrayList<String>();
        Set<String> set = new LinkedHashSet<String>();
        String s = "ravi is a good!boy. But ravi is very nasty fellow.";
        StringTokenizer st = new StringTokenizer(s, " ,. ,!");
        while (st.hasMoreTokens()) {
            result.add(st.nextToken());
        }
         System.out.println(result);
         set.addAll(result);
        result.clear();
        result.addAll(set);
        System.out.println(result);

output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
1
siva

Dies wird für Ihre Liste der benutzerdefinierten Objekte verwendet 

   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) o2).getId()) /*&&
                    ((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
                return 0;
            }
            return 1;
        }
    });
    set.addAll(list);

    final List newList = new ArrayList(set);
    return newList;
}

sie können eine geschachtelte Schleife folgendermaßen verwenden:

ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();

        Iterator iterator1 = l1.iterator();
        boolean repeated = false;

        while (iterator1.hasNext())
        {
            Class1 c1 = (Class1) iterator1.next();
            for (Class1 _c: l2) {
                if(_c.getId() == c1.getId())
                    repeated = true;
            }
            if(!repeated)
                l2.add(c1);
        }
1
HamidReza

Wie bereits erwähnt, sollten Sie eine Klasse verwenden, die die Set-Schnittstelle anstelle von List implementiert, um die Einheitlichkeit der Elemente sicherzustellen. Wenn Sie die Reihenfolge der Elemente beibehalten müssen, kann die SortedSet-Schnittstelle verwendet werden. Die TreeSet-Klasse implementiert diese Schnittstelle.

1
Vinze
import Java.util.*;
class RemoveDupFrmString
{
    public static void main(String[] args)
    {

        String s="appsc";

        Set<Character> unique = new LinkedHashSet<Character> ();

        for(char c : s.toCharArray()) {

            System.out.println(unique.add(c));
        }
        for(char dis:unique){
            System.out.println(dis);
        }


    }
}
0
reddy
for(int a=0;a<myArray.size();a++){
        for(int b=a+1;b<myArray.size();b++){
            if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
                myArray.remove(b); 
                dups++;
                b--;
            }
        }
}
0
Ghyour

Zeitkomplexität: O(n): Ohne Set

private static void removeDup(ArrayList<String> listWithDuplicateElements) {
    System.out.println(" Original Duplicate List :" + listWithDuplicateElements);
    List<String> listWithoutDuplicateElements = new ArrayList<>(listWithDuplicateElements.size());

    listWithDuplicateElements.stream().forEach(str -> {
        if (listWithoutDuplicateElements.indexOf(str) == -1) {
            listWithoutDuplicateElements.add(str);
        }
    });     

    System.out.println(" Without Duplicate List :" + listWithoutDuplicateElements);
}
0
Sameer Shrestha
Set<String> strSet = strList.stream().collect(Collectors.toSet());

Ist der einfachste Weg, Ihre Duplikate zu entfernen.

0
saif ali

Dies ist der richtige (wenn Sie sich Gedanken über den Overhead von HashSet machen).

 public static ArrayList<String> removeDuplicates (ArrayList<String> arrayList){
    if (arrayList.isEmpty()) return null;  //return what makes sense for your app
    Collections.sort(arrayList, String.CASE_INSENSITIVE_ORDER);
    //remove duplicates
    ArrayList <String> arrayList_mod = new ArrayList<>();
    arrayList_mod.add(arrayList.get(0));
    for (int i=1; i<arrayList.size(); i++){
        if (!arrayList.get(i).equals(arrayList.get(i-1))) arrayList_mod.add(arrayList.get(i));
    }
    return arrayList_mod;
}
0

Würde so etwas besser funktionieren? 

public static void removeDuplicates(ArrayList<String> list) {
Arraylist<Object> ar     = new Arraylist<Object>();
Arraylist<Object> tempAR = new Arraylist<Object>();
while (list.size()>0){
    ar.add(list(0));
    list.removeall(Collections.singleton(list(0)));
}
list.addAll(ar);

}

Das sollte die Reihenfolge beibehalten und auch nicht zur Laufzeit quadratisch sein.

0
Ravi Vital
public Set<Object> findDuplicates(List<Object> list) {
        Set<Object> items = new HashSet<Object>();
        Set<Object> duplicates = new HashSet<Object>();
        for (Object item : list) {
            if (items.contains(item)) {
                duplicates.add(item);
                } else { 
                    items.add(item);
                    } 
            } 
        return duplicates;
        }
0
Harsha

Wenn Sie möchten, dass Ihre Liste Duplikate automatisch ignoriert und ihre Reihenfolge beibehält, können Sie eine HashList (eine in HashMap eingebettete Liste) erstellen.

public static class HashList<T> extends ArrayList<T>{
        private HashMap <T,T> hashMap;
        public HashList(){
            hashMap=new HashMap<>();
        }

        @Override
        public boolean add(T t){
            if(hashMap.get(t)==null){
                hashMap.put(t,t);
                return super.add(t);
            }else return false;
        }

        @Override
        public boolean addAll(Collection<? extends T> c){
            HashList<T> addup=(HashList<T>)c;
            for(int i=0;i<addup.size();i++){
                add(addup.get(i));
            }return true;
        }

    }

Usage Example:

HashList<String> hashlist=new HashList<>();
hashList.add("hello");
hashList.add("hello");
System.out.println(" HashList: "+hashlist);
0
LiNKeR

Wenn Sie Duplikate aus ArrayList entfernen möchten, finden Sie die folgende Logik.

public static Object[] removeDuplicate(Object[] inputArray)
{
    long startTime = System.nanoTime();
    int totalSize = inputArray.length;
    Object[] resultArray = new Object[totalSize];
    int newSize = 0;
    for(int i=0; i<totalSize; i++)
    {
        Object value = inputArray[i];
        if(value == null)
        {
            continue;
        }

        for(int j=i+1; j<totalSize; j++)
        {
            if(value.equals(inputArray[j]))
            {
                inputArray[j] = null;
            }
        }
        resultArray[newSize++] = value;
    }

    long endTime = System.nanoTime()-startTime;
    System.out.println("Total Time-B:"+endTime);
    return resultArray;
}
0
Thananjayan N
    ArrayList<String> list = new ArrayList<String>();
    HashSet<String> unique = new LinkedHashSet<String>();
    HashSet<String> dup = new LinkedHashSet<String>();
    boolean b = false;
    list.add("Hello");
    list.add("Hello");
    list.add("how");
    list.add("are");
    list.add("u");
    list.add("u");

    for(Iterator iterator= list.iterator();iterator.hasNext();)
    {
        String value = (String)iterator.next();
        System.out.println(value);

        if(b==unique.add(value))
            dup.add(value);
        else
            unique.add(value);


    }
    System.out.println(unique);
    System.out.println(dup);
0
SparkOn

Hier ist meine Antwort, ohne eine andere Datenstruktur wie set oder Hashmap usw. zu verwenden.

public static <T> ArrayList<T> uniquefy(ArrayList<T> myList) {

    ArrayList <T> uniqueArrayList = new ArrayList<T>();
    for (int i = 0; i < myList.size(); i++){
        if (!uniqueArrayList.contains(myList.get(i))){
            uniqueArrayList.add(myList.get(i));
        }
    }

    return uniqueArrayList;
}
0
neo7

Die @ jonathan-stafford-Lösung ist in Ordnung. Die Listenreihenfolge bleibt dabei jedoch nicht erhalten.

Wenn Sie die Listenreihenfolge beibehalten möchten, müssen Sie Folgendes verwenden:

public static <T> void removeDuplicate(List <T> list) {
Set <T> set = new HashSet <T>();
List <T> newList = new ArrayList <T>();
for (Iterator <T>iter = list.iterator();    iter.hasNext(); ) {
   Object element = iter.next();
   if (set.add((T) element))
      newList.add((T) element);
   }
   list.clear();
   list.addAll(newList);
}

Es ist nur die Antwort zu vervollständigen. Sehr gut!

0
sharkbait