HashSet 에 있 는 대상 에 대한 재 작성 hashcode () 와 equals ()
우선, 제 가 예 를 들 어 보 겠 습 니 다. Person 류 를 쓰 고 equals () 방법 만 덮어 썼 습 니 다.
class Person{
private String name;
private int age;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return this.name + " :" + this.age;
}
}
다음은 테스트 클래스 의 코드 를 드 립 니 다.
public class HashSetResearch {
public static void main(String[] args) {
Set<Person> s = new HashSet<Person>();
Person p1 = new Person(22,"zhongyao");
Person p2 = new Person(22,"zhongyao");
s.add(p1);
s.add(p2);
for(Person temp : s){
System.out.println(temp);
}
}
}
:
zhongyao :22
zhongyao :22
HashSet 에서 중 복 된 대상 을 설치 할 수 없습니다. 이것 은 모두 가 알 고 있 는 것 입 니 다. 구체 적 인 설명 은 jdk 의 HashSet 류 와 관련 된 javadoc 설명 을 볼 수 있 습 니 다.
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
e==null ? e2 = = null: e. equals (e2) 는 HashSet 에서 e 와 같은 element 를 가 질 수 없 음 을 설명 합 니 다. 같은 조건 은 null 또는 equals () 방법 으로 true 를 되 돌려 주 는 것 입 니 다.이 럴 때 당신 은 왜 위의 p2 가 s 에 들 어 갔 느 냐 고 물 을 수 있 습 니 다.
HashSet 을 호출 할 때 많은 일이 발생 했 습 니 다. 대상 의 hashcode () 방법 이 있 습 니 다. 전체 프로 세 스 의 호출 과정 을 상세 하 게 보 여 드 리 겠 습 니 다.
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
HashSet add 。
map HashSet :
private transient HashMap<E,Object> map;
PRESENT , :
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
” ”, , map value。
HashMap put(K k, V v) , 。 , 。 ,
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);// ,
// key hashcode, key
// , HashMap ,
//
int hash = hash(key.hashCode());
// i , table
// , table Entry , ,
// 。 indexFor() , i=hash&(talbe.length-1)
// hash 。
int i = indexFor(hash, table.length);
// for , table i
// , , ,
// hash hashcode ( )
// for
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
// ,
// hashcode, ,
//((k = e.key) == key e
// , 。 key.equals(k) 。
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);// do nothing
//
return oldValue;
}
}
modCount++;
// for , ,
//
addEntry(hash, key, value, i);
return null;
}
HashSet. Entry 의 소스 코드 를 첨부 합 니 다:
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
final int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry)o;
Object k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public final int hashCode() {
return (key==null ? 0 : key.hashCode()) ^
(value==null ? 0 : value.hashCode());
}
public final String toString() {
return getKey() + "=" + getValue();
}
/**
* This method is invoked whenever the value in an entry is
* overwritten by an invocation of put(k,v) for a key k that's already
* in the HashMap.
*/
void recordAccess(HashMap<K,V> m) {
}
/**
* This method is invoked whenever the entry is
* removed from the table.
*/
void recordRemoval(HashMap<K,V> m) {
}
}
이것 은 모든 set 에서 거의 차이 가 나 지 않 으 니 여러분 스스로 보 셔 도 됩 니 다.한 가지 더 말씀 드 리 겠 습 니 다. TreeSet 에 서 는 copare To () 에 게 똑 같이 되 돌아 오 라 고 추가 로 요구 합 니 다. 즉, equals () 가 true 로 돌아 갈 때 copare To () 는 0 으로 돌아 가 야 합 니 다.
질문:
hashset 에 가입 한 후에 수정 대상 의 상 태 는 다른 것 과 마찬가지 로 가능 합 니 다. 자동 으로 끊 어 지지 않 습 니 다. 이것 이 바로 제 가 알 고 싶 은 것 입 니 다. 이것 은 set 의 유일 성 을 파괴 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
2022년 3월 21일 TIL1. JVM & JDK JVM JRE 자바 실행 환경의 약자로 자바 프로그램을 실행하기 위한 도구들이 들어있으며 JVM이 이 안에 포함된다 JDK JRE + 개발툴 javac는 컴파일 명령어 HelloWorld.cl...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.