/**
* 지정된 요소가 아직 없으면 이 세트에 추가합니다.
* 보다 공식적으로, 다음과 같은 경우 지정된 요소 <tt>e</tt>를 이 세트에 추가합니다.
* 이 세트에는 <tt>e2</tt>
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* 이 세트에 이미 요소가 포함되어 있으면 호출이 세트를 떠납니다.
* 변경되지 않고 <tt>false</tt>를 반환합니다.
*
* @param e 요소가 이 세트에 추가됩니다.
* @return <tt>true</tt>
*요소
*/
공개 부울 추가(E e) {
return map.put(e, PRESENT)==null;
}
HashSet에 의해 내부적으로 관리되는 map에 새 요소를 추가하세요. //HashMap 코드
/**
* 지정된 값을 이 맵의 지정된 키와 연결합니다.
* 이전에 맵에 키에 대한 매핑이 포함된 경우 이전
* 값이 대체됩니다.
*
* @param key 지정된 값이 연결될 키
* @param value 지정된 키와 연결될 값
* @<tt>key</tt>와 관련된 이전 값을 반환합니다. 또는
* 키에 대한 매핑이 없는 경우 null입니다.
* (null 반환은 지도가
* 이전에 key와 연결된 null.)
*/
공개 V put(K 키, V 값) {
if (테이블 == EMPTY_TABLE) {
inflateTable(임계값);
}
if (키 == null)
return putForNullKey(값);
int 해시 = 해시(키);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = 테이블[i]; e != null; e = e.next) {
객체 k;
if (e.hash == hash && ((k = e.key) == 키 || key.equals(k))) {
V oldValue = e.value;
e.값 = 값;
e.recordAccess(this);
oldValue를 반환합니다.
}
}
모드카운트++;
addEntry(해시, 키, 값, i);
null을 반환;
}
Element가 해싱되는 것을 볼 수 있는데, Foo(1)를 추가하면 HashSet에 저장하는 과정에서 꼭 필요하게 됩니다. 이 링크.
비교를 살펴보겠습니다 //HashSet 코드
/**
* 이 세트에 지정된 요소가 포함되어 있으면 <tt>true</tt>를 반환합니다.
* 더 공식적으로는 이 값이 설정된 경우에만 <tt>true</tt>를 반환합니다.
*는 <tt>e</tt> 요소를 포함합니다.
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* @param o 이 세트에 존재하는지 테스트할 요소
* @return <tt>true</tt> 이 세트에 지정된 요소가 포함되어 있으면
*/
공개 부울 포함(객체 o) {
return map.containsKey(o);
}
//HashMap 코드
/**
* 이 지도에 다음에 대한 매핑이 포함되어 있으면 <tt>true</tt>를 반환합니다.
* 지정된 키.
*
* @param key 이 맵에 존재하는지 테스트할 키입니다.
* @return <tt>true</tt> 이 지도에 지정된 매핑이 포함된 경우
* 열쇠.
*/
공개 부울 containKey(객체 키) {
return getEntry(key) != null;
}
/**
* 지정된 키와 연관된 항목을 반환합니다.
* HashMap에 매핑이 없으면 null을 반환합니다.
* 열쇠의 경우.
*/
최종 항목 getEntry(객체 키) {
if (크기 == 0) {
null을 반환;
}
int hash = (key == null) 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
전자!= 널;
e = e.다음) {
객체 k;
if (e.hash == 해시 &&
((k = e.key) == 키 || (키 != null && key.equals(k))))
e를 반환;
}
null을 반환;
}
결론 HashSet 컨테이너에 요소를 삽입할 때 요소를 해시하고, 컨테이너에 요소가 포함되어 있는지 판단할 때 요소를 해시합니다. , 요소의 해시 값을 비교합니다.
equals 메서드이지만 2층에서는 String의 equals 메서드에 대해 이야기하고 있다는 점에 주목할 필요가 있습니다. 왜냐하면 String의 equals 메서드가 다시 작성되었기 때문입니다. 주체가 contain 메서드를 통해 일반 객체를 비교하려는 경우에는 여전히 그렇습니다. 어떤 규칙을 결정하기 위해 String과 같은 equals 메소드를 다시 작성합니다.
public boolean contain(Object o) {
Iterator it = iterator();
if (o==null) {
동안(it.hasNext())
if (it.next()==null)
사실을 반환;
} 또 다른 {
동안(it.hasNext())
if (o.equals(it.next()))
사실을 반환;
}
거짓을 반환;
}
이것은 AbstractCollection의 구현이며, AbstractList, AbstractSet은 모두 이것을 상위 클래스로 구현합니다.
소스 코드를 확인해보니 여기에
HashSet
의Hash
에 대한 기사가 있는 것 같습니다.
/** * 지정된 요소가 아직 없으면 이 세트에 추가합니다. * 보다 공식적으로, 다음과 같은 경우 지정된 요소 <tt>e</tt>를 이 세트에 추가합니다. * 이 세트에는 <tt>e2</tt> * <tt>(e==null ? e2==null : e.equals(e2))</tt>. * 이 세트에 이미 요소가 포함되어 있으면 호출이 세트를 떠납니다. * 변경되지 않고 <tt>false</tt>를 반환합니다. * * @param e 요소가 이 세트에 추가됩니다. * @return <tt>true</tt> *요소 */ 공개 부울 추가(E e) { return map.put(e, PRESENT)==null; }1. 먼저 요소 추가 과정을 살펴보세요
//HashSet 코드
/** * 지정된 값을 이 맵의 지정된 키와 연결합니다. * 이전에 맵에 키에 대한 매핑이 포함된 경우 이전 * 값이 대체됩니다. * * @param key 지정된 값이 연결될 키 * @param value 지정된 키와 연결될 값 * @<tt>key</tt>와 관련된 이전 값을 반환합니다. 또는 * 키에 대한 매핑이 없는 경우 null입니다. * (null 반환은 지도가 * 이전에 key와 연결된 null.) */ 공개 V put(K 키, V 값) { if (테이블 == EMPTY_TABLE) { inflateTable(임계값); } if (키 == null) return putForNullKey(값); int 해시 = 해시(키); int i = indexFor(hash, table.length); for (Entry<K,V> e = 테이블[i]; e != null; e = e.next) { 객체 k; if (e.hash == hash && ((k = e.key) == 키 || key.equals(k))) { V oldValue = e.value; e.값 = 값; e.recordAccess(this); oldValue를 반환합니다. } } 모드카운트++; addEntry(해시, 키, 값, i); null을 반환; }HashSet
에 의해 내부적으로 관리되는map
에 새 요소를 추가하세요.//HashMap 코드
Element
가 해싱되는 것을 볼 수 있는데,Foo(1)
를 추가하면HashSet에 저장하는 과정에서 꼭 필요하게 됩니다.
이 링크.
/** * 이 세트에 지정된 요소가 포함되어 있으면 <tt>true</tt>를 반환합니다. * 더 공식적으로는 이 값이 설정된 경우에만 <tt>true</tt>를 반환합니다. *는 <tt>e</tt> 요소를 포함합니다. * <tt>(o==null ? e==null : o.equals(e))</tt>. * * @param o 이 세트에 존재하는지 테스트할 요소 * @return <tt>true</tt> 이 세트에 지정된 요소가 포함되어 있으면 */ 공개 부울 포함(객체 o) { return map.containsKey(o); }비교를 살펴보겠습니다
//HashSet 코드
//HashMap 코드
/** * 이 지도에 다음에 대한 매핑이 포함되어 있으면 <tt>true</tt>를 반환합니다. * 지정된 키. * * @param key 이 맵에 존재하는지 테스트할 키입니다. * @return <tt>true</tt> 이 지도에 지정된 매핑이 포함된 경우 * 열쇠. */ 공개 부울 containKey(객체 키) { return getEntry(key) != null; } /** * 지정된 키와 연관된 항목을 반환합니다. * HashMap에 매핑이 없으면 null을 반환합니다. * 열쇠의 경우. */ 최종 항목결론
HashSet
컨테이너에 요소를 삽입할 때 요소를 해시하고, 컨테이너에 요소가 포함되어 있는지 판단할 때 요소를 해시합니다. , 요소의 해시 값을 비교합니다.equals 메서드이지만 2층에서는 String의 equals 메서드에 대해 이야기하고 있다는 점에 주목할 필요가 있습니다. 왜냐하면 String의 equals 메서드가 다시 작성되었기 때문입니다. 주체가 contain 메서드를 통해 일반 객체를 비교하려는 경우에는 여전히 그렇습니다. 어떤 규칙을 결정하기 위해 String과 같은 equals 메소드를 다시 작성합니다.
이것은
AbstractCollection
의 구현이며,AbstractList
,AbstractSet
은 모두 이것을 상위 클래스로 구현합니다.