TreeMap
은 이진 트리를 기반으로 한 Map 컬렉션이다.
Map.Entry
를 저장한다.Map.Entry
객체를 저장한다.TreeMap을 생성하기 위해서는 키로 저장할 객체 타입과 값으로 저장할 객체 타입을 타입 파라미터로 주고 기본 생성자를 호출하면 된다.
TreeMap<K, V> treeMap = new TreeMap<K, V>();
TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>();
Map 인터페이스 타입 변수에 대입해도 되지만 TreeMap
클래스 타입으로 대입한 이유는 특정 객체를 찾거나 범위 검색과 관련된 메소드를 사용하기 위해서이다.
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
TreeMap<Integer, String> scores = new TreeMap<Integer, String>();
scores.put(87, "김");
scores.put(98, "이");
scores.put(75, "박");
scores.put(95, "최");
scores.put(80, "윤");
Map.Entry<Integer, String> entry = null;
entry = scores.firstEntry();
System.out.println("가장 낮은 점수: " + entry.getKey() + "-" + entry.getValue());
entry = scores.lastEntry();
System.out.println("가장 높은 점수: " + entry.getKey() + "-" + entry.getValue() + "\n");
entry = scores.lowerEntry(95);
System.out.println("95점 아래 점수: " + entry.getKey() + "-" + entry.getValue());
entry = scores.higherEntry(95);
System.out.println("95점 위의 점수: " + entry.getKey() + "-" + entry.getValue() + "\n");
entry = scores.ceilingEntry(95);
System.out.println("95점 이거나 바로 아래 점수: " + entry.getKey() + "-" + entry.getValue());
entry = scores.floorEntry(95);
System.out.println("95점 이거나 바로 위의 점수: " + entry.getKey() + "-" + entry.getValue() + "\n");
while (!scores.isEmpty()) {
entry = scores.pollFirstEntry();
System.out.println(entry.getKey() + "-" + entry.getValue() + " (남은 객체 수: " + scores.size() + ")");
}
}
}
가장 낮은 점수: 75-박
가장 높은 점수: 98-이
95점 아래 점수: 87-김
95점 위의 점수: 98-이
95점 이거나 바로 아래 점수: 95-최
95점 이거나 바로 위의 점수: 95-최
75-박 (남은 객체 수: 4)
80-윤 (남은 객체 수: 3)
87-김 (남은 객체 수: 2)
95-최 (남은 객체 수: 1)
98-이 (남은 객체 수: 0)
descendingKeySet()
메소드는 내림차순으로 정렬된 NavigableSet 객체를 리턴한다.descendingMap()
메소드는 내림차순으로 정렬된 NavigableMap 객체를 리턴한다.firstEntry()
, lastEntry()
, lowerEntry()
, higherEntry()
, floorEntry()
, ceilingEntry()
메소드를 제공하고, 오름차순과 내림차순으로 번갈하며 정렬 순서를 바꾸는 descendingMap()
메소드도 제공한다.descendingMap()
메소드를 두 번 호출하면 된다.NavigableMap<K, V> descendingMap = treeMap.descendingMap();
NavigableMap<K, V> ascendingMap = descendingMap.descendingMap();
import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapExample2 {
public static void main(String[] args) {
TreeMap<Integer, String> scores = new TreeMap<Integer, String>();
scores.put(87, "김");
scores.put(98, "이");
scores.put(75, "박");
scores.put(95, "최");
scores.put(80, "윤");
NavigableMap<Integer, String> descendingMap = scores.descendingMap();
Set<Map.Entry<Integer, String>> descendingEntrySet = descendingMap.entrySet();
for (Map.Entry<Integer, String> entry : descendingEntrySet) {
System.out.print(entry.getKey() + "-" + entry.getValue() + " ");
}
System.out.println();
NavigableMap<Integer, String> ascendingMap = descendingMap.descendingMap();
Set<Map.Entry<Integer, String>> ascendingEntrySet = ascendingMap.entrySet();
for (Map.Entry<Integer, String> entry : ascendingEntrySet) {
System.out.print(entry.getKey() + "-" + entry.getValue() + " ");
}
}
}
98-이 95-최 87-김 80-윤 75-박
75-박 80-윤 87-김 95-최 98-이
세 가지 메소드 중에서 subMap()
메소드의 사용 방법을 자세히 살펴보도록 하자. subMap()
메소드는 네 개의 매개 변수가 있는데, 시작 키
와 끝 키
, 그리고 이 키들의 Map.Entry를 포함할지 여부의 boolean 값
을 받는다.
NavigableMap<K, V> subMap = treeMap.subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive);
K fromKey
: 시작 키boolean fromInclusive
: 시작 Map.Entry 포함 여부K toKey
: 끝 키boolean toInclusive
: 끝 Map.Entry 포함 여부import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
public class TreeMapExample3 {
public static void main(String[] args) {
TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>();
treeMap.put("apple", 10);
treeMap.put("forever", 60);
treeMap.put("description", 40);
treeMap.put("ever", 50);
treeMap.put("zoo", 10);
treeMap.put("base", 20);
treeMap.put("guess", 70);
treeMap.put("cherry", 30);
System.out.println("[c-f 사이의 단어 검색]");
NavigableMap<String, Integer> rangeMap = treeMap.subMap("c", true, "f", true);
for (Map.Entry<String, Integer> entry : rangeMap.entrySet()) {
System.out.println(entry.getKey() + "-" + entry.getValue() + "페이지");
}
}
}
[c-f 사이의 단어 검색]
cherry-30페이지
description-40페이지
ever-50페이지
java.lang.Comparable
을 구현한 객체를 요구하는데, Integer, Double, String은 모두 Comparable 인터페이스를 구현하고 있다.다음은 나이를 기준으로 Person 객체를 오름차순으로 정렬하기 위해 Comparable 인터페이스를 구현한 것이다.
나이가 적을 경우는 -1을, 동일한 경우는 0을, 클 경우는 1을 리턴하도록 compareTo() 메소드를 재정의하였다.
public class Person implements Comparable<Person> {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
if (age < o.age) return -1;
else if (age == o.age) return 0;
else return 1;
}
}
import java.util.Iterator;
import java.util.TreeSet;
public class ComparableExample {
public static void main(String[] args) {
TreeSet<Person> treeSet = new TreeSet<Person>();
treeSet.add(new Person("김", 45));
treeSet.add(new Person("이", 25));
treeSet.add(new Person("최", 31));
Iterator<Person> iterator = treeSet.iterator();
while (iterator.hasNext()) {
Person person = iterator.next();
System.out.println(person.name + ": " + person.age);
}
}
}
TreeSet<E> treeSet = new TreeSet<E>( new AscendingComparator() );
TreeMap<K, V> treeMap = new TreeMap<K, V>( new DescendingComparator() );
정렬자는 Comparator 인터페이스를 구현한 객체를 말하는데, Comparator 인터페이스에는 다음과 같이 메소드가 정의되어 있다.
compare() 메소드는 비교하는 두 객체가 동등하면 0, 비교하는 값보다 앞에 오게 하려면 음수, 뒤에 오게 하려면 양수를 리턴하도록 구현하면 된다.
다음은 가격을 기준으로 Fruit 객체를 내림차순으로 정렬시키는 정렬자이다.
import java.util.Comparator;
public class DescendingComparator implements Comparator<Fruit> {
@Override
public int compare(Fruit o1, Fruit o2) {
if (o1.price < o2.price) return 1;
else if (o1.price == o2.price) return 0;
else return -1;
}
}
public class Fruit {
public String name;
public int price;
public Fruit(String name, int price) {
this.name = name;
this.price = price;
}
}
package book;
import java.util.Iterator;
import java.util.TreeSet;
public class ComparatorExample {
public static void main(String[] args) {
TreeSet<Fruit> treeSet = new TreeSet<Fruit>(new DescendingComparator()); //내림차순 정렬자 제공
treeSet.add(new Fruit("포도", 3000));
treeSet.add(new Fruit("수박", 10000));
treeSet.add(new Fruit("딸기", 6000));
Iterator<Fruit> iterator = treeSet.iterator();
while (iterator.hasNext()) {
Fruit fruit = iterator.next();
System.out.println(fruit.name + ": " + fruit.price);
}
}
}
수박: 10000
딸기: 6000
포도: 3000
이것이 자바다 책
http://tcpschool.com/java/java_collectionFramework_map