Heim  >  Artikel  >  Java  >  So implementieren Sie einen Java-Listen-Deduplizierungsvorgang

So implementieren Sie einen Java-Listen-Deduplizierungsvorgang

高洛峰
高洛峰Original
2017-01-22 15:53:041455Durchsuche

Listen in Java können wiederholte Elemente enthalten (Hash-Code und Gleiches), daher gibt es zwei Möglichkeiten, Listen zu deduplizieren:
Option 1: Kann über HashSet implementiert werden. Der Code lautet wie folgt:

class Student { 
private String id; 
private String name; 
public Student(String id, String name) { 
super(); 
this.id = id; 
this.name = name; 
} 
@Override 
public String toString() { 
return "Student [id=" + id + ", name=" + name + "]"; 
} 
@Override 
public int hashCode() { 
final int prime = 31; 
int result = 1; 
result = prime * result + ((id == null) ? 0 : id.hashCode()); 
result = prime * result + ((name == null) ? 0 : name.hashCode()); 
return result; 
} 
@Override 
public boolean equals(Object obj) { 
if (this == obj) { 
return true; 
} 
if (obj == null) { 
return false; 
} 
if (getClass() != obj.getClass()) { 
return false; 
} 
Student other = (Student) obj; 
if (id == null) { 
if (other.id != null) { 
return false; 
} 
} else if (!id.equals(other.id)) { 
return false; 
} 
if (name == null) { 
if (other.name != null) { 
return false; 
} 
} else if (!name.equals(other.name)) { 
return false; 
} 
return true; 
} 
}

Die Methoden hashCode und equal müssen gleich implementiert werden.
Der spezifische Operationscode lautet wie folgt:

private static void removeListDuplicateObject() { 
List<Student> list = new ArrayList<Student>(); 
for (int i = 0; i < 10; i++) { 
Student student = new Student("id", "name"); 
list.add(student); 
} 
System.out.println(Arrays.toString(list.toArray())); 
Set<Student> set = new HashSet<Student>(); 
set.addAll(list); 
System.out.println(Arrays.toString(set.toArray())); 
list.removeAll(list); 
set.removeAll(set); 
System.out.println(Arrays.toString(list.toArray())); 
System.out.println(Arrays.toString(set.toArray())); 
}

Aufrufcode:

public static void main(String[] args) { 
removeListDuplicateObject(); 
}

Wenn wir HashSet zur Durchführung von Deduplizierungsvorgängen verwenden, warum müssen wir die Methoden hashCode und equal überschreiben?
Wir sehen uns den Quellcode der Add-Operation von HashSet wie folgt an:

public boolean add(E e) { 
return map.put(e, PRESENT)==null; 
}

HashMap wird für die Operation aufgerufen:

public V put(K key, V value) { 
if (key == null) 
return putForNullKey(value); 
int hash = hash(key.hashCode()); 
int i = indexFor(hash, table.length); 
for (Entry<K,V> e = table[i]; e != null; e = e.next) { 
Object k; 
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
V oldValue = e.value; 
e.value = value; 
e.recordAccess(this); 
return oldValue; 
} 
} 
modCount++; 
addEntry(hash, key, value, i); 
return null; 
}

It Es ist zu beachten, dass:

if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
...... 
}

Das heißt, die Hash-Codes sind gleich und gleich (==).
Komplexität: nur auf einer Seite durchlaufen, O(n)
Option 2: Liste direkt durchlaufen und durch Enthält- und Add-Operationen implementieren
Der Code lautet wie folgt:

private static void removeListDuplicateObjectByList() { 
List<Student> list = new ArrayList<Student>(); 
for (int i = 0; i < 10; i++) { 
Student student = new Student("id", "name"); 
list.add(student); 
} 
System.out.println(Arrays.toString(list.toArray())); 
List<Student> listUniq = new ArrayList<Student>(); 
for (Student student : list) { 
if (!listUniq.contains(student)) { 
listUniq.add(student); 
} 
} 
System.out.println(Arrays.toString(listUniq.toArray())); 
list.removeAll(list); 
listUniq.removeAll(listUniq); 
System.out.println(Arrays.toString(list.toArray())); 
System.out.println(Arrays.toString(listUniq.toArray())); 
}

Andere entsprechen den oben genannten.
Komplexität:
Während des Durchlaufs wird gleichzeitig die Methode „contains“ aufgerufen. Wir sehen den Quellcode wie folgt:

public boolean contains(Object o) { 
return indexOf(o) >= 0; 
} 
public int indexOf(Object o) { 
if (o == null) { 
for (int i = 0; i < size; i++) 
if (elementData[i]==null) 
return i; 
} else { 
for (int i = 0; i < size; i++) 
if (o.equals(elementData[i])) 
return i; 
} 
return -1; 
}

Sie können sehen, dass ein weiterer Durchlaufvorgang für den neuen ausgeführt wird Liste. Das heißt, die Komplexität von 1+2+....+n ist O(n*n)
Schlussfolgerung:
Schema 1 ist hocheffizient, das heißt, es verwendet HashSet, um Deduplizierungsvorgänge durchzuführen

Weitere Artikel zur Implementierung des Java-Listen-Deduplizierungsvorgangs finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn