web-dev-qa-db-fra.com

Comment supprimer des éléments répétés de ArrayList?

J'ai un ArrayList<String> et je veux supprimer les chaînes répétées. Comment puis-je faire ceci?

444
user25778

Si vous ne voulez pas de doublons dans une Collection, vous devez vous demander pourquoi vous utilisez un Collection permettant les doublons. Le moyen le plus simple de supprimer des éléments répétés consiste à ajouter le contenu à une Set (qui ne permet pas les doublons), puis à rajouter la Set à la ArrayList:

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

Bien sûr, cela détruit l'ordre des éléments dans la variable ArrayList.

920
jonathan-stafford

Bien que la conversion de ArrayList en HashSet supprime efficacement les doublons, si vous devez conserver l'ordre d'insertion, je vous suggérerais plutôt d'utiliser cette variante.

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

Ensuite, si vous devez récupérer une référence List, vous pouvez utiliser à nouveau le constructeur de conversion.

281
abahgat

En Java 8:

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

Veuillez noter que le contrat hashCode-equals pour les membres de la liste doit être respecté pour que le filtrage fonctionne correctement.

112
Vitalii Fedorenko

Si vous ne voulez pas de doublons, utilisez Set au lieu de List. Pour convertir une List en une Set, vous pouvez utiliser le code suivant:

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

Si vraiment nécessaire, vous pouvez utiliser la même construction pour reconvertir une Set en une List.

52
Benno Richters

Supposons que nous ayons une liste de String comme:

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

Ensuite, nous pouvons supprimer les éléments en double de plusieurs manières.

Avant Java 8

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

Remarque: Si nous voulons conserver l'ordre d'insertion, nous devons utiliser LinkedHashSet à la place de HashSet

Utilisation de goyave

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

Utiliser Java 8

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

Remarque: Si nous souhaitons collecter le résultat dans une implémentation de liste spécifique à LinkedList alors nous pouvons modifier l'exemple ci-dessus comme suit:

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

Nous pouvons également utiliser parallelStream dans le code ci-dessus, mais cela ne donnera pas les avantages attendus en termes de performances. Cochez cette question pour plus.

44
i_am_zero

Voici un moyen qui n’affecte pas le classement de votre liste:

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 est la liste d'origine et l2 la liste sans éléments répétés .__

27
stbn

Vous pouvez également le faire de cette façon et préserver l’ordre:

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

Les flux Java 8 constituent un moyen très simple de supprimer des éléments en double d’une liste. En utilisant la méthode distincte . Si nous avons une liste de villes et que nous voulons supprimer les doublons de cette liste, cela peut être fait en une seule ligne 

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

Comment supprimer des éléments en double dans une liste

23
infoj

Il y a aussi ImmutableSet from Guava en option ( ici est la documentation):

ImmutableSet.copyOf(list);
22
Timofey Gorshkov

Il est possible de supprimer les doublons d'un arraylist sans utiliser HashSet ou un autre arraylist

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

La sortie est

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

cela peut résoudre le problème:

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

Probablement un peu exagéré, mais j'apprécie ce genre de problème isolé. :)

Ce code utilise un ensemble temporaire (pour la vérification de l'unicité) mais supprime les éléments directement dans la liste d'origine. Étant donné que la suppression d'éléments à l'intérieur d'une ArrayList peut induire une énorme quantité de copies de tableaux, la méthode remove (int) est évitée.

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

Pendant que nous y sommes, voici une version pour LinkedList (bien plus jolie!):

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

Utilisez l'interface de marqueur pour présenter une solution unifiée pour List:

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

EDIT: Je suppose que les médicaments génériques n’ajoutent pas vraiment de valeur ici .. Oh bien. :)

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
Manash Ranjan Dakua

Si vous souhaitez utiliser une bibliothèque tierce, vous pouvez utiliser la méthode distinct() dans Eclipse Collections (anciennement GS Collections).

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

L'avantage d'utiliser distinct() au lieu de convertir en ensemble puis en liste est que distinct() préserve l'ordre de la liste d'origine en conservant la première occurrence de chaque élément. Il est implémenté en utilisant à la fois un ensemble et une liste.

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;

Si vous ne pouvez pas convertir votre liste d'origine en un type de collections Eclipse, vous pouvez utiliser ListAdapter pour obtenir la même API.

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

Note: Je suis un partisan des collections Eclipse.

5
Craig P. Motlin

Ces trois lignes de code peuvent supprimer l'élément dupliqué de ArrayList ou de n'importe quelle collection.

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

Remarque: Certainement, il y aura une surcharge de mémoire.

2
sambhu

Si vous utilisez le type de modèle List <T>/ArrayList <T>. J'espère que ça vous aide.


Voici mon code sans utiliser aucune autre structure de données comme set ou 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--;
                            }
                        }
                    }

Lorsque vous remplissez la liste de tableaux, utilisez une condition pour chaque élément. Par exemple:

    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 + " ");     
    }

Nous aurons un tableau {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

2
HarpyWar

Si vous souhaitez conserver votre commande, il est préférable d’utiliser LinkedHashSet . Si vous souhaitez transmettre cette liste à une requête d’insertion en la parcourant, la commande sera préservée.

Essaye ça

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

Cette conversion sera très utile lorsque vous souhaitez renvoyer une liste mais pas un ensemble.

2
ramakrishnan

LinkedHashSet fera l'affaire.

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

// sortie: 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

Ceci est utilisé pour votre liste d'objets personnalisés 

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

vous pouvez utiliser la boucle imbriquée en suivant:

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

Comme indiqué précédemment, vous devez utiliser une classe implémentant l'interface Set au lieu de List pour vous assurer de l'unicité des éléments. Si vous devez conserver l'ordre des éléments, vous pouvez utiliser l'interface SortedSet. la classe TreeSet implémente cette interface.

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

Complexité temporelle: O(n): sans ensemble

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

Est le moyen le plus simple de supprimer vos doublons.

0
saif ali

C’est le bon choix (si vous vous inquiétez des frais généraux de HashSet.

 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
seekingStillness

Est-ce que quelque chose comme ça fonctionnerait mieux? 

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

}

Cela devrait maintenir l'ordre et également ne pas être quadratique dans le temps d'exécution.

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

Si vous voulez que votre liste ignore automatiquement les doublons et conserve son ordre, vous pouvez créer un HashList (une liste intégrée HashMap).

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

Si vous souhaitez supprimer les doublons de ArrayList, recherchez la logique ci-dessous,

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

Voici ma réponse sans utiliser aucune autre structure de données comme set ou hashmap, etc.

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

La solution @ jonathan-stafford est OK. Mais cela ne conserve pas l'ordre de la liste.

Si vous voulez conserver l'ordre de la liste, vous devez utiliser ceci:

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

C'est seulement pour compléter la réponse. Très bien!

0
sharkbait