add
, equals
, hashCode
에 추가 규정을 명시함add
Adds the specified element to this set if it is not already present (optional operation). More formally, adds the specified element e to this set if the set contains no element e2 such that Objects.equals(e, e2). If this set already contains the element, the call leaves the set unchanged and returns false. In combination with the restriction on constructors, this ensures that sets never contain duplicate elements.
equals
Compares the specified object with this set for equality. Returns true if the specified object is also a set, the two sets have the same size, and every member of the specified set is contained in this set (or equivalently, every member of this set is contained in the specified set). This definition ensures that the equals method works properly across different implementations of the set interface.
hashCode
set 의 hashCode 는 set 에 있는 요소들의 hashCode 의 합계다.Returns the hash code value for this set. The hash code of a set is defined to be the sum of the hash codes of the elements in the set, where the hash code of a null element is defined to be zero. This ensures that s1.equals(s2) implies that s1.hashCode()==s2.hashCode() for any two sets s1 and s2, as required by the general contract of Object.hashCode.
HashSet<Mock> hashSet = new HashSet<>();
Mock a = new Mock("A");
Mock b = new Mock("B");
System.out.println("hashCode a + b = " + (a.hashCode() + b.hashCode()));
hashSet.add(a);
hashSet.add(b);
System.out.println("hashCode hashSet = " + hashSet.hashCode());
------- 출력 결과 -------
hashCode a + b = 724073426
hashCode hashSet = 724073426
https://qph.cf2.quoracdn.net/main-qimg-2b6812dceb05fa46a0cb130d9adf2043
This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.
Iterating over this set requires time proportional to the sum of the HashSet instance's size (the number of elements) plus the "capacity" of the backing HashMap instance (the number of buckets). Thus, it's very important not to set the initial capacity too high (or the load factor too low) if iteration performance is important.
`public HashSet()`
`public HashSet(Collection<? extends E> c)`
Constructs a new set containing the elements in the specified collection. The HashMap is created with default load factor (0.75) and an initial capacity sufficient to contain the elements in the specified collection.
`public HashSet(int initialCapacity, float loadFactor)`
이 생성자를 사용하면 다른 생성자들과 달리 내부적으로 LinkedHashMap 인스턴스를 생성한다.
/**
* Constructs a new, empty linked hash set. (This package private
* constructor is only used by LinkedHashSet.) The backing
* HashMap instance is a LinkedHashMap with the specified initial
* capacity and the specified load factor.
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
`public HashSet(int initialCapacity)`
HashMap<E, Object> map
private transient HashMap<E,Object> map;
HashSet 은 내부적으로 HashMap 자료구조를 사용한다.static final Object PRESENT
HashSet 은 내부적으로 HashMap을 사용한다. Key 에 요소를 저장하고 Value 는 더미 객체를 사용한다. // Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
add(E e)
HashMap.put
메서드는 key-value 값이 새로운 값이면 null 을 리턴하고 기존에 동일한 key 객체가 있으면 교체한 value 객체를 리턴한다. 그래서 (map.put(e, PRESENT)==null) → true
의미는 중복된 데이터가 아닌 새로운 데이터를 추가했다는 뜻이다. /**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element {@code e} to this set if
* this set contains no element {@code e2} such that
* {@code Objects.equals(e, e2)}.
* If this set already contains the element, the call leaves the set
* unchanged and returns {@code false}.
*
* @param e element to be added to this set
* @return {@code true} if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
Object.clone 을 호출해 HashSet 참조값을 복사한다.
HashSet 의 필드 HashMap 의 참조값도 복사한다.
public Object clone() {
try {
// 참조변수 복사
HashSet<E> newSet = (HashSet<E>) super.clone(); // Object.clone 호출
newSet.map = (HashMap<E, Object>) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
!https://javagoal.com/wp-content/uploads/2019/12/6-1.png
리스트가 순차적 데이터 저장을 구현하도록 골격이 구현되어 있다.This class provides a skeletal implementation of the List interface to minimize the effort required to implement this interface backed by a "sequential access" data store (such as a linked list). For random access data (such as an array), AbstractList should be used in preference to this class.
This class is the opposite of the AbstractList class in the sense that it implements the "random access" methods (get(int index), set(int index, E element), add(int index, E element) and remove(int index)) on top of the list's list iterator, instead of the other way around.
Throws exception | Returns special value | |
---|---|---|
Insert | add(e) | offer(e) |
Remove | remove() | poll() |
Examine | element() | peek() |
add, remove, element 는 정의된 동작이 실패했을 경우 예외를 던지고, offer, poll, peek 는 false 또는 null 을 리턴한다. 왜 그럴까? Queue 구현체에 따라 용량에 제한이 있는 경우와 아닌 경우가 있는데 이때 다르게 사용한다.one throws an exception if the operation fails, the other returns a special value (either null or false, depending on the operation). The latter form of the insert operation is designed specifically for use with capacity-restricted Queue implementations; in most implementations, insert operations cannot fail.
링크드 리스트는 배열의 길이 지정이 필요 없으므로 생성자가 단촐하다.
Node<E> first, Node<E> last
/**
* Pointer to first node.
*/
transient Node<E> first;
/**
* Pointer to last node.
*/
transient Node<E> last;
목록의 첫 번째, 마지막 노드의 참조값을 저장한다. !https://www.callicoder.com/static/ffb4ab89e6cfc7e840b8da297b169550/ea544/java-linkedlist-vs-arraylist.jpgprivate static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
LinkedList 에 static 중첩 클래스로 선언되어 있는 Node.
이전 Node 와 다음 Node 의 참조값을 저장한다.