Список в Java может содержать повторяющиеся элементы (хеш-код и равные элементы), поэтому существует два способа дедупликации списка:
Вариант 1: Это можно реализовать через HashSet. Код выглядит следующим образом:
Скопируйте код кода следующим образом:
Студент класса {
частный строковый идентификатор;
частное имя строки;
public Student (идентификатор строки, имя строки) {
супер();
this.id = идентификатор;
это.имя = имя;
}
@Override
публичная строка toString() {
return "Студент [id=" + id + ", name=" + name + "]";
}
@Override
общественный int hashCode() {
окончательный int prime = 31;
интервал результата = 1;
результат = простое * результат + ((id == null) ? 0: id.hashCode());
result = prime * result + ((name == null) ? 0: name.hashCode());
вернуть результат;
}
@Override
общественное логическое равенство (Object obj) {
если (это == объект) {
вернуть истину;
}
если (объект == ноль) {
вернуть ложь;
}
if (getClass() != obj.getClass()) {
вернуть ложь;
}
Другой студент = (Студент) obj;
если (идентификатор == ноль) {
если (other.id != ноль) {
вернуть ложь;
}
} else if (!id.equals(other.id)) {
вернуть ложь;
}
если (имя == ноль) {
if (other.name != null) {
вернуть ложь;
}
} else if (!name.equals(other.name)) {
вернуть ложь;
}
вернуть истину;
}
}
Должны быть реализованы два метода, hashCode и Equals. Вскоре мы увидим, почему конкретные коды операций должны быть реализованы следующим образом:
Скопируйте код кода следующим образом:
Private static void RemoveListDuplateObject() {
List<Студент> list = новый ArrayList<Студент>();
для (int я = 0; я <10; я++) {
Студент Студент = новый Студент("id", "имя");
list.add(студент);
}
System.out.println(Arrays.toString(list.toArray()));
Set<Student> set = new HashSet<Student>();
set.addAll(список);
System.out.println(Arrays.toString(set.toArray()));
list.removeAll(список);
set.removeAll(установить);
System.out.println(Arrays.toString(list.toArray()));
System.out.println(Arrays.toString(set.toArray()));
}
Код вызова:
Скопируйте код кода следующим образом:
public static void main(String[] args) {
удалитьСписокДубликатовОбъекта();
}
Почему при использовании HashSet для выполнения операций дедупликации нам нужно переопределять методы hashCode и Equals?
Давайте проверим исходный код операции добавления HashSet следующим образом:
Скопируйте код кода следующим образом:
общедоступное логическое значение add(E e) {
return map.put(e, PRESENT)==null;
}
HashMap вызывается для работы. Давайте посмотрим на операцию put HashMap:
Скопируйте код кода следующим образом:
public V put (ключ K, значение V) {
если (ключ == ноль)
вернуть putForNullKey (значение);
int hash = hash(key.hashCode());
int я = indexFor(хеш, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Объект К;
if (e.hash == хэш && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
е.значение = значение;
e.recordAccess(это);
вернуть старое значение;
}
}
модКаунт++;
addEntry (хеш, ключ, значение, я);
вернуть ноль;
}
Следует отметить следующее:
Скопируйте код кода следующим образом:
if (e.hash == хэш && ((k = e.key) == key || key.equals(k))) {
...
}
Другими словами, хэш-коды равны и равны (==).
Сложность: просто пройти в одну сторону, O(n)
Вариант 2. Непосредственный просмотр списка и реализация операций добавления и добавления. Код выглядит следующим образом:
Скопируйте код кода следующим образом:
Private static void RemoveListDuplateObjectByList() {
List<Студент> list = новый ArrayList<Студент>();
для (int я = 0; я <10; я++) {
Студент Студент = новый Студент("id", "имя");
list.add(студент);
}
System.out.println(Arrays.toString(list.toArray()));
List<Студент> listUniq = новый ArrayList<Студент>();
for (Студент: список) {
if (!listUniq.contains(студент)) {
listUniq.add(студент);
}
}
System.out.println(Arrays.toString(listUniq.toArray()));
list.removeAll(список);
listUniq.removeAll(listUniq);
System.out.println(Arrays.toString(list.toArray()));
System.out.println(Arrays.toString(listUniq.toArray()));
}
Остальные такие же, как указано выше.
Сложность:
При обходе одновременно вызывается метод contains. Мы просматриваем исходный код следующим образом:
Скопируйте код кода следующим образом:
общедоступное логическое значение содержит (Объект o) {
вернуть indexOf(o) >= 0;
}
public int indexOf(Object o) {
если (о == ноль) {
for (int я = 0; я <размер; я++)
если (elementData[i]==null)
вернуть я;
} еще {
for (int я = 0; я <размер; я++)
если (o.equals(elementData[i]))
вернуть я;
}
вернуть -1;
}
Вы можете видеть, что над новым списком была выполнена еще одна операция обхода. То есть 1+2+....+n, сложность O(n*n)
в заключение:
Решение 1 является высокоэффективным: оно использует HashSet для выполнения операций дедупликации.