web-dev-qa-db-fra.com

Supprimer des valeurs en double de ArrayList

J'ai un Arraylist of String et j'ai ajouté quelques valeurs en double à cela. et je veux juste enlever cette valeur en double Alors comment l'enlever. 

Ici, exemple, j'ai eu une idée.

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

Mais existe-t-il un moyen suffisant de supprimer cette liste de formulaires en double? sans utiliser pour boucle? Et je peux le faire en utilisant HashSet ou un autre moyen mais en utilisant uniquement la liste de tableaux .. .. aimerait avoir votre suggestion pour cela. merci d'avance pour votre réponse.

18
Krishna

Vous pouvez créer un LinkedHashSet à partir de la liste. LinkedHashSet ne contiendra chaque élément qu'une seule fois et dans le même ordre que List. Créez ensuite un nouveau List à partir de ce LinkedHashSet. Tellement efficacement, c'est un one-liner:

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

Toute approche impliquant List#contains ou List#remove réduira probablement la durée d'exécution asymptotique de O(n) (comme dans l'exemple ci-dessus) à O (n ^ 2). 


EDITPour l'exigence mentionnée dans le commentaire: Si vous souhaitez supprimer les éléments en double, mais considérez les chaînes comme equal en ignorant la casse, vous pouvez procéder comme suit:

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

Il aura une durée d'exécution de O (n * logn), ce qui est toujours meilleur que beaucoup d'autres options. Notez que cela semble un peu plus compliqué que cela n’aurait dû être fait: j’ai supposé que le order des éléments de la liste ne pouvait pas être modifié. Si l'ordre des éléments dans la liste n'a pas d'importance, vous pouvez simplement faire

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

si vous voulez utiliser uniquement des listes de lecture, je crains qu'il n'existe pas de meilleur moyen de créer un avantage énorme en termes de performances. Mais en utilisant uniquement arraylist je vérifierais avant d’ajouter à la liste comme suit

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

Dans ce cas, utiliser un Set convient.

11
stinepike

Vous pouvez utiliser les utilitaires Google Guava, comme indiqué ci-dessous.

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

C’est probablement le moyen le plus efficace d’éliminer les doublons de la liste et, chose intéressante, il conserve également l’ordre des itérations.

METTRE &AGRAVE; JOUR

Toutefois, si vous ne souhaitez pas impliquer la goyave, vous pouvez supprimer les doublons comme indiqué ci-dessous.

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

Mais, bien sûr, cela détruira l'ordre d'itération des éléments de la liste de tableaux.

Shishir

9
Shishir Kumar

Java 8fonction de flux 

Vous pouvez utiliser la fonction distinct comme ci-dessus pour obtenir les éléments distincts de la liste, 

stringList.stream().distinct();

De la documentation, 

Retourne un flux composé des éléments distincts (selon Object.equals (Object)) de ce flux.


Une autre façon, si vous ne souhaitez pas utiliser la méthode equals, consiste à utiliser la fonction collect comme ceci, 

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

De la documentation, 

Effectue une opération de réduction mutable sur les éléments de ce flux à l'aide d'un collecteur. 

J'espère que cela pourra aider.

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

Fonction simple pour supprimer les doublons de la 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--;
            }
        }
    }
}

Exemple:
Entrée: [1, 2, 2, 3, 1, 3, 3, 2, 3, 1, 2, 3, 3, 4, 4, 4, 1]
Sortie: [1, 2, 3, 4]

2
BRIJ

Je ne pense pas que list = new ArrayList<String>(new LinkedHashSet<String>(list)) n'est pas la meilleure solution, car nous utilisons LinkedHashset (nous pourrions utiliser directement LinkedHashset au lieu de ArrayList), 

Solution:

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

Sortie: [1, 2, 3]

Ici, je suis en train d’étendre la ArrayList, car je l’utilise avec quelques modifications en surchargeant la méthode add.

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

}

C'est la meilleure façon

1
kumar venkatesan

Ce sera le meilleur moyen

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

Sans boucle, Non ! Puisque ArrayList est indexé par ordre plutôt que par clé, vous ne pouvez pas trouver l'élément cible sans parcourir la liste entière.

Une bonne pratique de programmation consiste à choisir une structure de données adaptée à votre scénario. Donc, si Set convient le mieux à votre scénario, la discussion de son implémentation avec List et d'essayer de trouver le moyen le plus rapide d'utiliser une structure de données incorrecte n'a aucun sens.

1
Weibo Li

Il vaut mieux utiliser HastSet

1-a) Un hachage contient un ensemble d'objets, mais de manière à ce qu'il vous permette de déterminer facilement et rapidement si un objet est déjà dans l'ensemble ou non. Pour ce faire, il gère en interne un tableau et stocke l'objet à l'aide d'un index calculé à partir du hashcode de l'objet. Regardez ici

1-b) HashSet est une collection non ordonnée contenant des éléments uniques. Il comporte les opérations de collecte standard Add, Remove, Contains, mais comme il utilise une implémentation basée sur un hachage, ces opérations sont O (1). (Contrairement à List, par exemple, qui correspond à O(n) pour Contains and Remove.) HashSet fournit également des opérations standard telles que l'union, l'intersection et la différence symétrique. Consultez ici.

2) Il existe différentes implémentations des ensembles. Certains accélèrent les opérations d'insertion et de recherche en hachant des éléments. Cependant, cela signifie que l'ordre dans lequel les éléments ont été ajoutés est perdu. D'autres implémentations préservent l'ordre ajouté au détriment des temps d'exécution plus lents.

La classe HashSet en C # utilise la première approche, ne préservant donc pas l'ordre des éléments. C'est beaucoup plus rapide qu'une liste normale. Certains tests de base ont montré que HashSet est nettement plus rapide s’agissant des types primaires (int, double, bool, etc.). C'est beaucoup plus rapide lorsque vous travaillez avec des objets de classe. Donc, ce point est que HashSet est rapide.

La seule capture de HashSet est qu'il n'y a pas d'accès par index. Pour accéder aux éléments, vous pouvez utiliser un énumérateur ou utiliser la fonction intégrée pour convertir le HashSet en une liste et effectuer une itération à travers celle-ci. Jetez un oeil ici.

1
Furquan Khan

Utilisation de 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

Au cas où vous auriez simplement besoin de supprimer les doublons en utilisant uniquement ArrayList, pas d'autres classes Collection, alors: - 

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

J'espère que cela t'aides!

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