Antworten:
Wenn Sie keine Duplikate in a möchten Collection
, sollten Sie überlegen, warum Sie ein Collection
Duplikat verwenden , das Duplikate zulässt. Der einfachste Weg, wiederholte Elemente zu entfernen, besteht darin, den Inhalt zu a hinzuzufügen Set
(was keine Duplikate zulässt) und dann die Set
Rückseite zu ArrayList
:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
Dies zerstört natürlich die Reihenfolge der Elemente in der 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
und Set
(anstelle der Implementierungstypen ArrayList
und HashSet
wie in Ihrem Beispiel) zu definieren.
new HashSet(al)
anstatt es zu leeren und aufzurufen addAll
.
Object
Wert mehrere Werte hat, wenn sich zwei davon wiederholen, betrachte ich sie als doppelt (andere Werte können unterschiedlich sein) und verwende Set
?
Wenn Sie die Einfügereihenfolge beibehalten möchten, sollten Sie diese Variante verwenden, obwohl beim Konvertieren ArrayList
in eine HashSet
Duplikate effektiv entfernt werden
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Wenn Sie dann eine List
Referenz zurückerhalten müssen , können Sie den Konvertierungskonstruktor erneut verwenden.
In Java 8:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
Bitte beachten Sie, dass der hashCode-equals- Vertrag für Listenmitglieder eingehalten werden sollte, damit die Filterung ordnungsgemäß funktioniert.
addAll
zu new TreeSet<String>(String.CASE_INSENSITIVE_ORDER)
. Das erste hinzugefügte Element bleibt im Set. Wenn Ihre Liste "Hund" und "Hund" (in dieser Reihenfolge) enthält, enthält die Liste TreeSet
"Hund". Wenn die Reihenfolge erhalten bleiben muss, dann vor der Zeile in der Antwort setzen list.replaceAll(String::toUpperCase);
.
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.
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
Hinweis: Wenn wir die Einfügereihenfolge beibehalten möchten, müssen wir LinkedHashSet
anstelle von verwendenHashSet
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
Hinweis: Wenn wir das Ergebnis in einer bestimmten Listenimplementierung erfassen möchten, z. B. LinkedList
können wir das obige Beispiel wie folgt ändern:
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
Wir können parallelStream
den obigen Code auch verwenden, er bietet jedoch möglicherweise keine erwarteten Leistungsvorteile. Überprüfen Sie diese Frage für mehr.
parallel streams
immer eine bessere Leistung bringen wird. Aber es ist ein Mythos. Ich habe später erfahren, dass es bestimmte Szenarien gibt, in denen parallele Streams verwendet werden sollten. In diesem Szenario bieten parallele Streams keine bessere Leistung. und ja, parallele Streams liefern in einigen Fällen möglicherweise nicht die gewünschten Ergebnisse. List<String> deDupStringList3 = stringList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());
sollte in diesem Fall die geeignete Lösung sein
Wenn Sie keine Duplikate möchten, verwenden Sie ein Set anstelle von a List
. Um a List
in a umzuwandeln , Set
können Sie den folgenden Code verwenden:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
Wenn es wirklich nötig ist, können Sie dieselbe Konstruktion verwenden, um einen Set
Rücken in einen umzuwandeln List
.
Set
kann hier nicht verwendet werden.
Sie können dies auch auf diese Weise tun und die Ordnung bewahren:
// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
Java 8-Streams bieten eine sehr einfache Möglichkeit, doppelte Elemente aus einer Liste zu entfernen. Mit der eindeutigen 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());
Hier ist ein Weg, der 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 (Stellen Sie sicher, dass YourClass die Methode equals hat, je nachdem, was Sie für Gleichheit stehen möchten.)
ArrayList<T>
sollten anstelle von verwendet werden ArrayList
). 2) Das explizite Erstellen von Iteratoren kann durch Verwendung von a vermieden werden for (T current : l1) { ... }
. Auch wenn Sie eine Iterator
explizit verwenden wollten , iterador
ist falsch geschrieben.
Es ist möglich, Duplikate aus der Arrayliste zu entfernen, ohne HashSet oder eine weitere Arrayliste zu verwenden .
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]
ImmutableSet.copyOf(lst).toList()
.
indexOf
iteriert die lst
Verwendung einer for-Schleife.
Es gibt auch ImmutableSet
von Guava als Option ( hier ist die Dokumentation):
ImmutableSet.copyOf(list);
ImmutableSet.asList()
Methode gibt, die eine ImmutableList
zurückgibt, wenn Sie sie als benötigen List
.
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;
}
Wahrscheinlich ein bisschen übertrieben, aber ich mag diese Art von isoliertem Problem. :) :)
Dieser Code verwendet einen temporären Satz (für die Eindeutigkeitsprüfung), entfernt jedoch Elemente direkt in der ursprünglichen Liste. Da das Entfernen von Elementen in einer ArrayList eine große Menge an Array-Kopieren 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, ist 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 einheitliche 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 Generika-Zeug bringt hier keinen wirklichen Mehrwert. Na ja. :) :)
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);
}
Wenn Sie bereit sind, eine Bibliothek eines Drittanbieters zu verwenden, 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 distinct()
anstelle der Konvertierung in eine Menge und dann zurück in eine Liste besteht darin, dass distinct()
die Reihenfolge der ursprünglichen Liste beibehalten wird und das erste Vorkommen jedes Elements beibehalten wird. Es wird mithilfe eines Sets und einer Liste implementiert.
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-Sammlungstyp konvertieren können, können Sie ListAdapter verwenden, um dieselbe API abzurufen.
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Hinweis: Ich bin ein Committer für Eclipse-Sammlungen.
Diese drei Codezeilen können das duplizierte Element aus ArrayList oder einer beliebigen Sammlung entfernen.
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
Verwenden Sie beim Füllen der ArrayList eine Bedingung für jedes Element. 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}
Wenn Sie Ihre Bestellung erhalten möchten, verwenden Sie am besten LinkedHashSet . Wenn Sie diese Liste durch Iterieren an eine Einfügeabfrage übergeben möchten, bleibt die Reihenfolge erhalten.
Versuche dies
LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);
Diese Konvertierung ist sehr hilfreich, wenn Sie eine Liste, aber keinen Satz zurückgeben möchten.
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 entsteht Speicheraufwand.
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 erledigt 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
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]
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 die verschachtelte Schleife wie folgt 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);
}
Wie bereits erwähnt, sollten Sie anstelle von List eine Klasse verwenden, die die Set-Schnittstelle implementiert, um die Einheitlichkeit der Elemente zu gewährleisten. Wenn Sie die Reihenfolge der Elemente beibehalten müssen, kann die SortedSet-Schnittstelle verwendet werden. Die TreeSet-Klasse implementiert diese Schnittstelle.
Hier ist mein Code ohne Verwendung einer anderen Datenstruktur wie Set oder 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);
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;
}