Ich habe einen ArrayList<String>
und möchte wiederholte Zeichenfolgen daraus entfernen. Wie kann ich das machen?
Wenn Sie keine Duplikate in einem Collection
wünschen, sollten Sie überlegen, warum Sie ein Collection
verwenden, das Duplikate zulässt. Wiederholte Elemente können Sie am einfachsten entfernen, indem Sie den Inhalt zu Set
hinzufügen (was keine Duplikate zulässt) und dann Set
wieder zu ArrayList
hinzufügen:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
Dies zerstört natürlich die Anordnung der Elemente in der ArrayList
.
Wenn Sie die Variable ArrayList
in eine Variable HashSet
konvertieren, werden Duplikate zwar effektiv entfernt. Wenn Sie jedoch die Einfügungsreihenfolge beibehalten möchten, sollten Sie diese Variante verwenden
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Wenn Sie dann eine List
-Referenz zurückholen 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 contract für Listenmitglieder beachtet werden sollte, damit die Filterung ordnungsgemäß funktioniert.
Wenn Sie keine Duplikate wünschen, verwenden Sie ein Set anstelle einer List
. Um eine List
in eine Set
zu konvertieren, können Sie den folgenden Code verwenden:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
Wenn wirklich notwendig, können Sie dieselbe Konstruktion verwenden, um eine Set
zurück in eine List
zu konvertieren.
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 HashSet
verwenden.
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
Anmerkung: Wenn wir das Ergebnis in einer spezifischen Listenimplementierung erfassen möchten, z. LinkedList
dann können wir das obige Beispiel wie folgt ändern:
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
Wir können parallelStream
auch im obigen Code verwenden, aber es kann keine erwarteten Performance-Vorteile geben. Überprüfen Sie diese Frage für mehr.
Hier ist eine Möglichkeit, die 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 (Vergewissern Sie sich, dass YourClass die Methode equals hat, die Ihrer Gleichheit entspricht.
Sie können es auch so machen 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. Verwenden der unterschiedlichen 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());
Es gibt auch ImmutableSet
from Guava als Option ( hier ist die Dokumentation):
ImmutableSet.copyOf(list);
Duplikate können ohne Verwendung von HashSet oder einer weiteren Arraylist aus der Arrayliste entfernt werden.
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]
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 dieses isolierte Problem. :)
Dieser Code verwendet ein temporäres Set (für die Überprüfung der Eindeutigkeit), entfernt jedoch Elemente direkt in der ursprünglichen Liste. Da das Entfernen von Elementen in einer ArrayList eine große Menge an Array-Kopien 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, 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 vereinheitlichte 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 Generics-Zeug bringt hier wirklich keinen Wert. Oh 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 eine Fremdanbieter-Bibliothek verwenden möchten, 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 von distinct()
anstelle der Konvertierung in ein Set und dann wieder in eine Liste besteht darin, dass distinct()
die Reihenfolge der ursprünglichen Liste beibehält und das erste Vorkommen jedes Elements beibehält. Es wird implementiert, indem sowohl ein Set als auch eine Liste verwendet wird.
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-Auflistungstyp konvertieren können, können Sie ListAdapter verwenden, um dieselbe API zu erhalten.
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Hinweis: Ich bin ein Committer für Eclipse Collections.
Diese drei Codezeilen können das duplizierte Element aus ArrayList oder einer beliebigen Auflistung entfernen.
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);
Hinweis: Auf jeden Fall wird Speicherüberhang entstehen.
Hier ist mein Code, ohne eine andere Datenstruktur wie set oder Hashmap zu verwenden
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--;
}
}
}
Verwenden Sie beim Füllen der ArrayList für jedes Element eine Bedingung. 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 beibehalten möchten, verwenden Sie am besten LinkedHashSet . Wenn Sie diese Liste durch Iteration an eine Einfügeabfrage übergeben, wird die Reihenfolge beibehalten.
Versuche dies
LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);
Diese Konvertierung ist sehr hilfreich, wenn Sie eine Liste aber kein Set zurückgeben möchten.
LinkedHashSet macht 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 eine geschachtelte Schleife folgendermaßen 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 eine Klasse verwenden, die die Set-Schnittstelle anstelle von List implementiert, um die Einheitlichkeit der Elemente sicherzustellen. Wenn Sie die Reihenfolge der Elemente beibehalten müssen, kann die SortedSet-Schnittstelle verwendet werden. Die TreeSet-Klasse implementiert diese Schnittstelle.
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--;
}
}
}
Zeitkomplexität: O(n): Ohne Set
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());
Ist der einfachste Weg, Ihre Duplikate zu entfernen.
Dies ist der richtige (wenn Sie sich Gedanken über den Overhead von HashSet machen).
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;
}
Würde so etwas besser funktionieren?
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);
}
Das sollte die Reihenfolge beibehalten und auch nicht zur Laufzeit quadratisch sein.
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;
}
Wenn Sie möchten, dass Ihre Liste Duplikate automatisch ignoriert und ihre Reihenfolge beibehält, können Sie eine HashList (eine in HashMap eingebettete Liste) erstellen.
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);
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;
}
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);
Hier ist meine Antwort, ohne eine andere Datenstruktur wie set oder Hashmap usw. zu verwenden.
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;
}
Die @ jonathan-stafford-Lösung ist in Ordnung. Die Listenreihenfolge bleibt dabei jedoch nicht erhalten.
Wenn Sie die Listenreihenfolge beibehalten möchten, müssen Sie Folgendes verwenden:
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);
}
Es ist nur die Antwort zu vervollständigen. Sehr gut!