HashMap은 키(key)와 값(value)을 묶어서 하나의 데이터(entry)로 저장한다. 그리고 해싱(hashing)을 사용하기 때문에 많은 양의 데이터를 검색하는데 있어서 뛰어난 성능을 보인다.
HashMap은 키와 값을 각각 Object 타입으로 저장한다. 어떤 형태로 저장하기 때문에 어떠한 객체도 저장할 수 있지만 키는 주로 String을 대문자 또는 소문자로 통일해서 사용하곤 한다.
키는 저장된 값을 찾는데 사용되는 것이기 때문에 컬렉션 내에서 유일 (unique)해야 한다.
Object get(Object key)
: 지정된 키의 값(value)을 반환한다. 못 찾으면 Null 반환.Object replace (Object key, Object value)
: 지정된 값을 지정된 객체 (value)로 대체Set keySet()
: HashMap에 저장된 모든 키가 저장된 Set을 반환한다.해싱이란 해시 함수 (hash function)을 이용해서 데이터를 해시 테이블에 저장하고 검색하는 기법을 말한다. 해시함수는 데이터가 저장되어 있는 곳을 알려주기 때문에 다량의 데이터 중에서도 원하는 데이터를 빠르게 찾을 수 있다.
해싱에서 사용하는 자료구조는 배열과 링크드 리스트의 조합으로 되어 있다.
저장할 데이터의 키를 해시함수에 넣으면 배열의 한 요소를 얻게 되고, 다시 그 곳에 연결되어 있는 링크드 리스트에 저장하게 된다.
배열은 크키가 커져도 원하는 요소가 몇 번째에 있는 지만 알면 빠르게 원하는 값을 찾을 수 있다. 그러나 링크드 리스트는 검색에 불리한 자료구조이기 때문에 링크드 리스트의 크기가 커질수록 검색속도가 떨어지게 된다.
하나의 링크드 리스트에 최소한의 데이터만 저장되려면, 저장될 데이터의 크기를 고려해서 HashMap의 크기를 적절하게 지정해주어야 하고, 해시함수가 서로 다른 키에 대해서 해시코드의 반환을 최소화해야 빠른 검색시간을 얻을 수 있다.
실제로는 HashMap과 같이 해싱을 구현한 컬렉션 클래스에서는 Object 클래스에 정의된 hashCode()를 해시함수로 사용한다. Object 클래스에 정의된 hashCode()는 객체의 주소를 이용하는 알고리즘으로 해시코드를 만들어 내기 때문에 모든 객체에 대해 hashCode()를 호출한 결과가 서로 유일한 훌륭한 방법이다.
//HashMap 생성
HashMap<String, String> map = new HashMap<>();
//데이터 put
map.put("조예지", "https://github.com/coastby/java-project/tree/main/java-project/src");
map.put("권하준", "https://github.com/dongyeon-0822/java-project-exercise");
map.put("조성윤", "https://github.com/kang-subin/Java");
map.put("안예은", "https://github.com/KoKwanwun/LikeLion.git");
map.put("남우빈", "https://github.com/lcomment/Algorithm_Solution--Java/tree/main/LikeLion");
map.put("최경민", "https://github.com/cmkxak/likelion-java-course");
map.put("안준휘", "https://github.com/rnrudejr9/CodeLion-git-test");
map.put("하채민", "https://github.com/Qkite/java-excercise-01/tree/main/src");
map.put("허도한", "https://github.com/lucyoz/java-exercise");
System.out.println("맵의 게수는 "+ map.size() + "개 입니다."); //맵의 개수는 9개입니다.
System.out.println(map.get("조예지")); //https://github.com/coastby/java-project/tree/main/java-project/src
String s에 있는 a~z까지 알파벳의 개수를 세는 알고리즘을 구현 해보세요.
대소문자는 구별하지 않습니다.
2-1) isAlphabet()
구현하기
String의 특정 문자가 알파벳이 맞으면 true, 아니면 false를 반환하는 함수
static boolean isAlphabet(char ch) {
boolean result = false;
//ch를 아스키로 바꾸지 않아도 바로 비교 가능
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
result = true;
}
return result;
}
2-2) Map<String, Integer> map = a~z까지 등록
//알파벳 키값 세팅
for (char c = 'A'; c <= 'Z'; c++) {
alphabetMap.put(c, 0);
}
2-3) 하나씩 세어서 카운팅 & 출력
public static void main(String[] args) {
String s1 = "aAAaab...bbcc//dd-efft-gg".toUpperCase();
HashMap<Character, Integer> alphabetMap = new HashMap<>();
//알파벳 키값 세팅
for (char c = 'A'; c <= 'Z'; c++) {
alphabetMap.put(c, 0);
}
//하나씩 찾아서 카운팅
for (int i = 0; i < s1.length(); i++) {
char ch = s1.charAt(i);
if (isAlphabet(ch)) {
alphabetMap.put(ch, alphabetMap.get(ch)+1);
}
}
System.out.println(alphabetMap);
}