December 31, 2021
HashSet은 Set인터페이스를 구현한 컬렉션이다.
HashSet() // HashSet 객체 생성
boolean add(Object o) // 새로운 객체를 저장한다
boolean addAll(Collection c) // 주어진 커렉션에 저장된 모든 객체들을 추가한다.
void clear() // 저장된 모든 객체를 삭제한다
boolean contains(Object o) // 지정된 객체를 포함하고 있는지 알려준다
boolean conatainsAll(Collection c) // 주어진 컬렉션에 저장된 모든 객체들을 포함하고 있는지 알려준다.
boolean remove(Object o) // 지정된 객체를 HashSet에서 삭제한다
boolean removeAll(Collection c) // 주어진 컬렉션에 저장된 모든 객체와 동일한 것들을 HashSet에서 삭제한다.
boolean retainAll(Collection c) // 주어진 컬렉션에서 저장된 객체와 동일한 것만 남기고 다 삭제한다.
다음과 같은 함수들이 있고 자세한 상황은 공식문서를 확인하자
HashSet의 add메서드는 새로운 요소를 추가하기 전에 기존에 저장된 요소와 같은 것인지 판별하기 위해 추가하려는 요소의 equals()와 hashCode()를 호출한다.
HashSet에서는 두 객체의 해시코드가 같고, equals메서드를 호출한 결과가 같아야지만 두 객체를 같다고 판단한다.
요소를 같은 것인지 판별하기 위해서 hashCode 메서드를 호출하며 이를 목적에 맞게 오버라이딩하여 사용해야한다.
public int hashCode(){
return (name+age).hashCode();
}
위에 예시처럼 기존의 hash코드를 사용하는 것이 아니라 String클래스의 hashCode()가 잘 구현되어 있기 때문에 이를 사용하여 이렇게 구현할 수도 있다.
또는 Object클래스의 hash()를 이용해서도 hashCode함수를 오버라이딩할 수 있다.
public int hashCode(){
return Objects.hash(name, age);
}
오버라이딩을 통해 작성한 hashCode() 함수는 다음의 세 가지 조건을 만족 시켜야 한다.
이진 검색 트리 (binary search tree) 형태로 데이터를 저장하는 컬렉션 클래스이다.
관련 메서드들은 공식문서를 확인하자.
다음과 같은 관련 메소드들이 있고 더 자세이 알고 싶으면 공식문서를 참고하자.
iterator를 사용하는 동안 쓰는 interface이다. 즉 iterator로 받아오는 요소들을 assign해줄 대상으로 사용하면 된다. Map.Entry에는 각 요소를 접근하기 위한 메서드들이 있다.
import java.util.*;
class HashMapEx{
static HashMap phoneBook = new HashMap();
public static void main(String[] args){
addPhoneNo("친구", "이자바", "010-111-1111");
addPhoneNo("친구", "김자바", "010-222-2222");
addPhoneNo("친구", "김자바", "010-333-4444");
addPhoneNo("회사", "김대리", "010-444-4444");
addPhoneNo("회사", "김대리", "010-555-5555");
addPhoneNo("회사", "박대리", "010-666-6666");
addPhoneNo("회사", "이과장", "010-777-7777");
addPhoneNo("세탁", "010-888-8888");
printList();
}
static void addPhoneNo(String groupName, String name, String tel){
addGroup(groupName);
HashMap group = (HashMap)phoneBook.get(groupName);
group.put(tel, name);
}
static void addGroup(String groupName){
if(!phoneBook.containsKey(groupName))
phoneBook.put(groupName, new HashMap());
}
static void addPhoneNo(String name, String tel){
addPhoneNo("기타", name, tel);
}
static void printList(){
Set set = phoneBook.entrySet();
Iterator it = set.iterator();
while(it.hasNext()){
Map.Entry e = (Map.Entry)it.next();
Set subSet = ((HashMap)e.getValue()).entrySet();
Iterator subIt = subSet.iterator();
System.out.println(" * " + e.getKey() + "[" + subSet.size() + "]");
while(subIt.hasNext()){
Map.Entry subE = (Map.Entry)subIt.nect();
String telNo = (String)subE.getKey();
String name = (String)subE.getValue();
System.out.println(name + " " + telNo);
}
System.out.println();
}
}
}
위에 예제를 보면 HashMap의 사용에 대한 대략적인 방법을 알 수 있을 거 같다.
해싱이란 해시함수(hashFunction)을 이용해서 데이터를 해시테이블(hash table)에 저장하고 검색하는 기법이다. 해시함수는 데이터가 저장되어 있는 곳을 알려주기 때문에 다량의 데이터 중에서도 원하는 데이터를 빠르게 찾을 수 있다.
HashMap에서 데이터를 찾는 과정은 위에 사진과 같다
위와 같은 프로세스에서 가장 빠른 방법은 역시 하나의 해시코드에 하나의 결과값만 있는 것이다.
그래서 실제로 Object클래스에 정의된 hashCode()함수는 객체의 주소를 이용하는 알고리즘으로 해시코드를 만들어 내기 때문에 모든 객체에 대해서 hashCode()를 호출한 결과가 서로 유일한 방법이다.
String클래스의 hashCode함수의 경우 Object로 부터 상속받은 hashCode()를 오버라이딩 하였는데, 문자열의 내용이 같다면 같은 hashCode()를 얻는다.
각 컬랙션마다 동기화를 하기위한 클래스들을 만들 수 있다.
static Collection synchronizedCollection(Collection c)
static List synchronizedList(List list)
static Set synchronizedSet(Set s)
static Map synchronizedMap(Map m)
static SortedSet synchronizedSortedSet(SortedSet s)
static SortedMap synchronizedSortedMap(SortedMap m)
// 다음과 같이 사용한다
List syncList = Collection.synchronizedList(new ArrayList[...])
해당 클래스 앞에 unmodified키워드만 붙여주면 된다.
static Collection unmodifiedCollection(Collection c)
static List unmodifiedList(List list)
...
싱글톤 즉 단 하나의 객체만을 저장하는 컬렉션을 만들 고 싶을 때 사용한다
static List singletonList(Object o)
static Set singleton(Object o)
static Map singletonMap(Object key, Object value)
컬렉션의 모든 종류의 객체를 저장할 수 있는 것은 장점이며 또한 단점이 될 수 있다. 한 종류의 객체만을 저장하고 싶을 떄 사용한다.
이후의 제네릭으로 간단히 처리할 수 있지만 호환성을 위해 위와 같은 메서드들도 포함된다.
static Collection checkedCollection(Collection c, Class type)
static List checkedList(List list, Class type)
...
// 아래와 같이 사용한다.
List list = new ArrayList();
List checkedList = checkedList(list, String.class); //String만 저장 가능하다
checkedList.add("abc");
checkList.add(new Integer(3)); // 에러 발생한다