Réponses:
Si vous ne voulez pas de doublons dans un Collection
, vous devez vous demander pourquoi vous utilisez un Collection
qui autorise les doublons. Le moyen le plus simple de supprimer des éléments répétés consiste à ajouter le contenu à un Set
(qui ne permettra pas les doublons), puis à ajouter le Set
dos au ArrayList
:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
Bien sûr, cela détruit l'ordre des éléments dans le ArrayList
.
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; }
List
et Set
(au lieu des types d'implémentation ArrayList
et HashSet
comme dans votre exemple).
new HashSet(al)
au lieu de l'initialiser à vide et en appelant addAll
.
Object
a plusieurs valeurs si deux d'entre elles se répètent, je les considère comme des doublons (d'autres valeurs peuvent être différentes) et j'utilise Set
?
Bien que la conversion ArrayList
en un HashSet
supprime efficacement les doublons, si vous devez conserver l'ordre d'insertion, je vous suggère plutôt d'utiliser cette variante
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Ensuite, si vous avez besoin de récupérer une List
référence, vous pouvez réutiliser le constructeur de conversion.
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.
addAll
faire new TreeSet<String>(String.CASE_INSENSITIVE_ORDER)
. Le premier élément ajouté restera dans l'ensemble, donc si votre liste contient "Chien" et "chien" (dans cet ordre), TreeSet
il contiendra "Chien". Si l'ordre doit être préservé, alors avant la ligne de la réponse, mettez list.replaceAll(String::toUpperCase);
.
Supposons que nous ayons une liste 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.
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
Remarque: Si nous voulons conserver l'ordre d'insertion, nous devons utiliser LinkedHashSet
à la place deHashSet
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
Remarque: Si nous voulons collecter le résultat dans une implémentation de liste spécifique,LinkedList
nous pouvons par exemple modifier l'exemple ci-dessus comme suit:
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
Nous pouvons parallelStream
également l' utiliser dans le code ci-dessus, mais il peut ne pas offrir les avantages attendus en termes de performances. Consultez cette question pour en savoir plus.
parallel streams
donnera toujours de meilleures performances. Mais c'est un mythe. J'ai appris plus tard qu'il existe certains scénarios dans lesquels des flux parallèles doivent être utilisés. Dans ce scénario, les flux parallèles ne donneront pas de meilleures performances. et oui les flux parallèles peuvent ne pas donner les résultats souhaités dans certains cas. List<String> deDupStringList3 = stringList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());
devrait être la solution appropriée dans ce cas
Si vous ne voulez pas de doublons, utilisez un ensemble au lieu d'un List
. Pour convertir un List
en un, 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 convertir un Set
dos en un List
.
Set
Ne peut donc pas être utilisé ici.
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));
Les flux Java 8 offrent un moyen très simple de supprimer les é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 sur 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 d'une liste d'arrayl
Voici un moyen qui n'affecte pas l'ordre 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 est la liste sans éléments répétés (assurez-vous que YourClass a la méthode equals selon ce que vous voulez représenter pour l'égalité)
ArrayList<T>
doivent être utilisés à la place de ArrayList
) 2) La création explicite d'itérateur peut être évitée en utilisant a for (T current : l1) { ... }
. Même si vous vouliez utiliser Iterator
explicitement, iterador
est mal orthographié.
Il est possible de supprimer les doublons de l'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]
ImmutableSet.copyOf(lst).toList()
.
indexOf
itère l' lst
utilisation d'une boucle for.
Il y a aussi ImmutableSet
de Guava en option ( voici la documentation):
ImmutableSet.copyOf(list);
ImmutableSet.asList()
méthode, renvoyant un ImmutableList
, si vous en avez besoin en tant que List
.
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;
}
Probablement un peu exagéré, mais j'aime 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 copie de tableau, 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 (beaucoup plus agréable!):
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 trucs génériques n'ajoutent pas vraiment de valeur ici .. Oh bien. :)
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);
}
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 un ensemble puis de revenir à une liste est qu'il 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();
Remarque: je suis un committer pour les collections Eclipse.
Ces trois lignes de code peuvent supprimer l'élément dupliqué d'ArrayList ou de toute collection.
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
Lorsque vous remplissez ArrayList, 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 obtiendrons un tableau {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Si vous souhaitez conserver votre commande, il est préférable d'utiliser LinkedHashSet . Parce que si vous voulez passer cette liste à une requête d'insertion en l'itérant, l'ordre serait conservé.
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.
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.
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();
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
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]
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;
}
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);
}
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--;
}
}
}
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);
Si vous souhaitez supprimer les doublons de ArrayList signifie trouver 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;
}