on
JAVA - Collection Frameworks4
Java
Java 공부를 정리 tag
JDK 8 Collections: Java docs를 공부하며 정리하는 글입니다.
Map Interface
A
Mapis an object that maps keys to values.
-
중복 key를 가질 수 없다.
- operations
- Basic :
put,get,remove,containsKey,containsValue,size,empty) - bulk operation :
putAll,clear - collection views :
keySet,entrySet,values
- Basic :
-
Java platform에서는
HashMap,TreeMap,LinkedHashMap3개의Map구현체를 제공한다.→
Setinterface의HashSet,TreeSet,LinkedHashSet와 기능과 성능이 유사하다.
Map Interface Basic Operations
Map의 기본 연산(put, get, containsKey, containsValue, size, isEmpty)은 HastTable과 정확히 동일하다. 만약 Map에서 key에 따라서 특정 순서를 갖고 싶다면, TreeMap을 쓰면 된다. Map에 입력하는 순서를 지키고 싶다면, LinkedHashMap을 쓰면된다.
→ 이렇게 유연함은 interface기반의 framework이 가지는 강력한 기능을 보여준다.
Set, List interface와 마찬가지로 Map은 equals, hashCode method에 대한 요구사항을 강화하하여 구현체에 관계없이 2개의 Map 객체가 논리적으로 동일성을 비교할 수 있게 해준다.
→ 여기서 2개의 Map 객체는 ‘같은 key-value’ pair를 가졌다면 동일한 것이다.
Map Interface Bulk Operations
clear:Map에서 모든 mapping을 제거한다.putAll:Collectioninterface의addAll연산과 비슷한 연산이다.
Collection Views
Collection view method는 Map이 Collection으로 보이게 해준다.
keySet:Map에 포함된 key의 setvalues:Map에 포함된 value들의Collection. 다수의 key들이 같은 value로 mapping됐을 수 있기에 이Collection은Set이 아니다.entrySet:Map에 포함된 key-value pair의Set.Map은Map.Entry라고 불리는 작은 내부 interface를 제공한다. 이 elements type은Set의 element이다.
Collection view는 단지 Map을 iterate하겠다는 의미이다.
Map이 삭제기능을 제공한다면 Iteration 도중에Iterator의removemethod로 element를 삭제할 수 있다.entrySetview에서Map.Entry의setValuemethod를 호출하여 key를 통해Map의 value를 바꾸는게 가능하다. iteration 도중 수정할 수 있는 유일한 방법이라고 한다. 이 동작은 반복 도중 다른 방법으로Map이 수정되면 동작하지 않는다.Collectionview는 다양한 삭제 기능들을 제공한다.remove,removeAll,retainAll,clear,Iterator.removeCollectionview는 어떠한 상황에서도 element 추가 기능은 제공하지 않는다.put,putAllmethod가Map에 이미 있기 때문에 굳이 필요없기 때문이다.
Object Ordering
List type인 list라는 객체에 대해 정렬을 수행한다면, 아래와 같이 할 수 있다.
Collections.sort(list);
만약 list가 String type이라면 알파벳 순서로 정렬이 될 것이고, Date type이라면 시간 순서로 정렬이 될 것이다. 어떻게 위 코드 1줄을 적었다고 type에 관련하여 적절하게 순서를 정렬해주는 것일까? → String, Date 는 모두 Comparable interface를 implements하기 때문이다.
Comparable 구현체는 해당 클래스의 객체가 자동으로 정렬될 수도록 ordering 기능을 제공한다.

사진 출처: Java JDK 8 docs-Object ordering
만약에 Comparable을 구현 하지 않는 element의 list를 정렬할 때는 ClassCastException이 발생한다. 따라서 만약에 Person이라는 사용자 정의 클래스를 만들었다면,
static class Person implements Comparable<Person> {
static int SERIAL = 0;
String name;
int seq;
Long id;
public Person(String name, Long id) {
this.name = name;
this.id = id;
seq = (++SERIAL);
}
@Override
public int compareTo(Person o) {
return this.seq - o.seq;
}
}
Comparable interface를 구현해야 list에서 정렬이 가능하다. 따라서 mutually comparable 한 element들만 정렬이 가능하다.
-
compareTo특정 객체와 받은 객체를 비교해서 특정 객체보다 더 작은지, 같은지, 더 큰지에 따라서 음수, 0, 양수를 반환한다. 특정 객체가 받은 객체와 비교할 수 없다면,
ClassCastException을 던진다.
근데 위와 같이 비교할 경우, overflow, underflow에 대해 고려를 안한 것이 된다. 따라서 어떤 값이 들어올지 알 수 없을 경우,
@Override
public int compareTo(Person o) {
if (this.seq > o.seq) return 1;
else if (this.seq < o.seq) return -1;
else return 0;
}
과 같이 대소비교를 해주는게 안전해서 좋다고 한다.
Comparators
만약에 원래 정렬방법이 아닌 다른 방법으로 정렬하고 싶거나 Comparable을 구현하지 않는 객체를 정렬하고 싶을 땐 어떻게 해야 할까? → Comparator사용.
public interface Comparator<T> {
int compare(T o1, T o2);
}
Comparator<Person> comp = new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.id - o2.id;
}
};
를 생성하여 비교해줄 수 있다. 더 간단하게 lambda eq로 만들어보면
Comparator<Person> comp = Comparator.comparingInt(o -> o.id);
로 만들 수 있다. 여기서 테스트 코드를 작성해봤다.
Comparators vs Comparable
- Comparable : compareTo(T o) 라는 method가 있다. ‘자기 자신과 매개변수 객체를비교’ 하는 것.
- Comparator : compare(T o1, T o2) 라는 method가 있다. ‘두 parameter 객체를 비교’ 하는 것.
Rerference
Java JDK 8 docs - Object Ordering