J'ai un ArrayList<String>
et je veux supprimer les chaînes répétées. Comment puis-je faire ceci?
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
.
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.
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.
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
.
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.
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
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
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.
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 .__
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 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());
Il y a aussi ImmutableSet
from Guava en option ( ici est la documentation):
ImmutableSet.copyOf(list);
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]
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'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. :)
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 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.
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();
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.
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}
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.
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);
}
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.
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);
}
}
}
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--;
}
}
}
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);
}
Set<String> strSet = strList.stream().collect(Collectors.toSet());
Est le moyen le plus simple de supprimer vos doublons.
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;
}
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.
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;
}
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);
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;
}
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);
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;
}
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!