해시 테이블은 연관배열 구조를 이용하여 키(key)에 결과 값(value)을 저장하는 자료구조이다.
연관배열 구조(associative array)란,
키(key) 1개와 값(value) 1개가 1:1로 연관되어 있는 자료구조이다. 따라서 키(key)를 이용하여 값(value)을 도출할 수 있다.
연관배열 구조는 다음의 명령을 지원한다.
HashMap<String,String> map1 = new HashMap<String,String>(); //HashMap생성
HashMap<String,String> map2 = new HashMap<>(); //new에서 타입 파라미터 생략가능
HashMap<String,String> map3 = new HashMap<>(map1); //map1의 모든 값을 가진 HashMap생성
HashMap<String,String> map4 = new HashMap<>(10); //초기 용량(capacity)지정
HashMap<String,String> map5 = new HashMap<>(10, 0.7f); //초기 capacity,load factor지정
HashMap<String,String> map6 = new HashMap<String,String>(){{ //초기값 지정
put("a","b");
}};
HashMap은 저장공간보다 값이 추가로 들어오면 List처럼 저장공간을 추가로 늘리는데 List처럼 저장공간을 한 칸씩 늘리지 않고 약 두배로 늘린다. 이때, 과부하가 발생하는데, 초기에 저장할 데이터 개수를 알고 있다면 Map의 초기 용량을 지정해주는 것이 좋다.
HashMap<Integer,String> map = new HashMap<>();//new에서 타입 파라미터 생략가능
map.put(1,"사과"); //값 추가
map.put(2,"바나나");
map.put(3,"포도");
HashMap에 값을 추가하려면 put(key,value) 메소드를 된다. add(key, value)와 헷갈리지 않게 주의하자.
선언 시 HashMap에 설정해준 타입과 같은 타입의 Key와 Value값을 넣어야 하며 만약 입력되는 키 값이 HashMap 내부에 존재한다면, 기존의 value는 새로운 값으로 대체된다.
HashMap<Integer,String> map = new HashMap<Integer,String>(){{//초기값 지정
put(1,"사과");
put(2,"바나나");
put(3,"포도");
}};
map.remove(1); //key값 1 제거
map.clear(); //모든 값 제거
HashMap에 값을 제거하려면 remove(key) 메소드를 사용하면 된다. 오직 키값으로만 Map의 요소를 삭제할 수 있습니다. 모든 값을 제거하려면 clear() 메소드를 사용하면 된다.
HashMap<Integer,String> map = new HashMap<Integer,String>(){{//초기값 지정
put(1,"사과");
put(2,"바나나");
put(3,"포도");
}};
System.out.println(map); //전체 출력 : [1=사과, 2=바나나, 3=포도]
System.out.println(map.get(1)); //key값 1의 value얻기 : 사과
//entrySet()
for (Entry<Integer, String> entry : map.entrySet()) {
System.out.println("[Key]:" + entry.getKey() + " [Value]:" + entry.getValue());
}
//keySet().iterator()
Iterator<Integer> keys = map.keySet().iterator();
while(keys.hasNext()){
int key = keys.next();
System.out.println("[Key]:" + key + " [Value]:" + map.get(key));
}
//[Key]:1 [Value]:사과
//[Key]:2 [Value]:바나나
//[Key]:3 [Value]:포도
//KeySet()
for(Integer i : map.keySet()){ //저장된 key값 확인
System.out.println("[Key]:" + i + " [Value]:" + map.get(i));
}
//[Key]:1 [Value]:사과
//[Key]:2 [Value]:바나나
//[Key]:3 [Value]:포도
entrySet()은 key와 value 모두가 필요할 경우 사용하기에 좋다. keySet()은 key 값만 필요할 경우 사용하는데 key값만 받아서 get(key)를 활용하여 value도 출력할 수도 있기에 어떤 메소드를 선택하든지 간에 큰 상관이 없다. 대부분 코드가 간단한 keySet을 활용하시던데 key값을 이용해서 value를 찾는 과정에서 시간이 많이 소모되므로 많은 양의 데이터를 가져와야 한다면 entrySet()이 좋다.(약 20%~200% 성능 저하가 있음)
List<Map.Entry<String, Integer>> entryList = new LinkedList<>(map.entrySet());
Collections.sort(entryList, (o1, o2) -> o1.getKey() - o2.getKey()); //Key 정렬
Collections.sort(entryList, (o1, o2) -> o1.getValue() - o2.getValue()); //Value 정렬
HashMap은 entrySet()을 이용하여 List로 변환 시킨 후 정렬을 하면 된다.
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("A","APPLE");
hashMap.put("B","BANANA");
hashMap.put("C","CHERRY");
hashMap.put("D","DURIAN");
System.out.println(hashMap.containsKey("A")); //true
System.out.println(hashMap.containsKey("E")); //false
System.out.println(hashMap.containsValue("BANANA")); //true
System.out.println(hashMap.containsValue("E????")); //false