>  기사  >  Java  >  Java 목록 중복 제거 작업을 구현하는 방법

Java 목록 중복 제거 작업을 구현하는 방법

高洛峰
高洛峰원래의
2017-01-22 15:53:041495검색

Java의 목록에는 반복되는 요소(해시 코드 및 등호)가 포함될 수 있으므로 목록을 중복 제거하는 방법에는 두 가지가 있습니다.
옵션 1: HashSet을 통해 구현할 수 있으며 코드는 다음과 같습니다.

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; 
} 
}

은 반드시 hashCode와 equals 메소드를 구현해야 합니다.
구체적인 연산 코드는 다음과 같습니다:

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())); 
}

호출 코드:

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

HashSet 시 사용 중복 제거 작업을 수행하는데 왜 hashCode 및 equals 메소드를 포함해야 합니까?
HashSet의 add 연산 소스 코드를 살펴보면 다음과 같습니다.

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

HashMap이 호출되어 HashMap의 put 연산을 살펴보겠습니다.

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; 
}

주의해야 할 점은 다음과 같습니다. :

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

즉, 해시 코드가 동일하고 동일합니다(==).
복잡성: 한쪽으로 순회, O(n)
옵션 2: 목록을 직접 순회하고 포함 및 추가 작업을 통해 구현
코드는 다음과 같습니다.

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())); 
}

기타 위와 동일합니다.
복잡성:
순회하는 동안 포함 메소드가 동시에 호출됩니다. 소스 코드를 보면 다음과 같습니다.

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; 
}

새 목록에 대해 또 다른 순회 작업이 수행되는 것을 볼 수 있습니다. 즉, 1+2+....+n의 복잡도는 O(n*n)입니다.
결론:
Scheme 1은 매우 효율적입니다. 즉, HashSet을 사용하여 중복 제거 작업을 수행합니다

Java 목록 중복 제거 작업 구현과 관련된 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.