안녕하세요 알통몬입니다. 공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^ |
이전 포스팅에 이어서 검색 기능을 강화시킨 컬렉션에 대해 공부하겠습니다.
2017/03/25 - [자바] - 자바 컬렉션 Java 컬렉션 - 이진트리구조, TreeSet
TreeMap
: TreeSet과의 차이점 : Key 와 Value가 저장된 Map.Entry를 저장한다는 것.
TreeMap에 객체를 저장하게 되면 자동으로 정렬이 됩니다.
부모 키값과 비교를 해 키 값이 낮으면 왼쪽 자식 노드로,
키 값이 높으면 오른쪽 자식 노드의 Map.Entry 객체에 저장됩니다.
TreeMap 생성 방법은 HashMap과 동일합니다.
2017/03/24 - [자바] - 자바 Map 컬렉션 자바 셋 컬렉션 -> Map, HashMap, Hashtable, Properties
생성할 때 Map 인터페이스 타입 변수로 대입해도 되지만 아래
TreeMap 클래스 타입으로 대입하는 것이 좋은데 이유는 아래와 같은 메소드들을
사용하기 위해서 입니다.
예제)
import java.util.Map;
import java.util.TreeMap;
public class Example {
public static void main(String[] args) {
TreeMap<Integer,String> scores = new TreeMap<Integer,String>();
scores.put(new Integer(77), "티스토리");
scores.put(new Integer(88), "Tistory");
scores.put(new Integer(65), "알통몬");
scores.put(new Integer(85), "Altongmon");
scores.put(new Integer(70), "블로그");
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(new Integer(85));
System.out.println("85점 아래 점수: " + entry.getKey() + "-" + entry.getValue());
entry = scores.higherEntry(new Integer(95));
System.out.println("85점 위의 점수: " + entry.getKey() + "-" + entry.getValue() + "\n");
entry = scores.floorEntry(new Integer(95));
System.out.println("85점 이거나 바로 아래 점수: " + entry.getKey() + "-" + entry.getValue());
entry = scores.ceilingEntry(new Integer(85));
System.out.println("75점 이거나 바로 위의 점수: " + entry.getKey() + "-" + entry.getValue() + "\n");
while(!scores.isEmpty()) {
entry = scores.pollFirstEntry();
System.out.println(entry.getKey() + "-" + entry.getValue() + "(남은 객체 수: " + scores.size() + ")");
}
}
}
TreeMap이 가지는 정렬관련 메소드
descendingMap()은 정렬된 NavigabableMap 객체를 정렬하여 내림차순으로 리턴합니다.
firstEntry() , lastEntry(), lowerEntry(), higherEntry(), floorEntry(), ceilingEntry()를 제공하고
오름차순과 내림차순을 번갈아가며 정렬 순서를 바꾸는 descendingMap도 제공합니다.
만약 내림차순이 아닌 오름차순으로 정렬하고 싶다면 descendingMap()을 두 번 호출하면 됩니다.
예제)
import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
public class Example {
public static void main(String[] args) {
TreeMap<Integer,String> scores = new TreeMap<Integer,String>();
scores.put(new Integer(77), "티스토리");
scores.put(new Integer(88), "Tistory");
scores.put(new Integer(65), "알통몬");
scores.put(new Integer(85), "Altongmon");
scores.put(new Integer(70), "블로그");
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() + " ");
}
}
}
TreeMap이 가지는 범위검색 관련 메소드
예제)
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
public class Example {
public static void main(String[] args) {
TreeMap<String,Integer> treeMap = new TreeMap<String,Integer>();
treeMap.put("apple", new Integer(10));
treeMap.put("forever", new Integer(60));
treeMap.put("description", new Integer(40));
treeMap.put("ever", new Integer(50));
treeMap.put("zoo", new Integer(10));
treeMap.put("base", new Integer(20));
treeMap.put("guess", new Integer(70));
treeMap.put("cherry", new Integer(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() + "페이지");
}
}
}
Comparable과 Comparator
TreeSet, TreeMap은 정렬을 위해 java.lang.Comparable을 구현한 객체를 요구하는데요.
Integer, Double, String의 정렬은 전부 Comparable 인터페이스를 구현하고 있어요.
사용자 정의 클래스도 Comparable을 구현하게 되면 자동 정렬을 할 수 있습니다.
Comparable에는 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("티스토리", 55));
treeSet.add(new Person("블로그", 35));
treeSet.add(new Person("알통몬", 41));
Iterator<Person> iterator = treeSet.iterator();
while(iterator.hasNext()) {
Person person = iterator.next();
System.out.println(person.name + ":" + person.age);
}
}
}
TreeSet 객체와 TreeMap의 Key가 Comparable을 구현하고 있지 않다면
저장하는 순간 예외가 발생하는 데요.
Comparable 비구현 객체를 정렬하는 방법은
TreeSet 이나 TreeMap 생성자의 매개값으로 정렬자를 제공하는 것이에요.
TreeSet<E> treeSet = new TreeSet<E>(new AscendingComparator() );
오름차순 또는 내림차순 정렬자
TreeMap<K ,V> treeMap = new TreeMap<K, V>(new DescendingComparator() );
정렬자는 Comparator 인터페이스를 구현한 객체를 말합니다.
Comparator 인터페이스는 compare()가 정의되어 있습니다.
예제)
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 DescendingComparator implements Comparator {
public int compare(Object o1, Object o2) {
Fruit fruit1 = (Fruit) o1;
Fruit fruit2 = (Fruit) o2;
if(fruit1.price < fruit2.price) return 1;
else if(fruit1.price == fruit2.price) return 0;
else return -1;
}
}*/
Comparable을 구현하지 않은 클래스
public class Menu{
public String name;
public int price;
public Menu(String name, int price) {
this.name = name;
this.price = price;
}
}
실행 클래스
import java.util.Iterator;
import java.util.TreeSet;
public class ComparatorExample {
public static void main(String[] args) {
/*
TreeSet<Menu> treeSet = new TreeSet<Menu>();
//Menu이 Comparable을 구현하지 않았기 때문에 예외 발생
treeSet.add(new Menu("아메리카노", 3000));
treeSet.add(new Menu("오가닉 요거트 스무디", 10000));
treeSet.add(new Menu("카페 라떼", 6000));
*/
TreeSet<Menu> treeSet = new TreeSet<Menu>(new DescendingComparator());
treeSet.add(new Menu("아메리카노", 3000));
treeSet.add(new Menu("오가닉 요거트 스무디", 10000));
treeSet.add(new Menu("카페 라떼", 6000));
Iterator<Menu> iterator = treeSet.iterator();
while(iterator.hasNext()) {
Menu menu = iterator.next();
System.out.println(menu.name + ":" + menu.price);
}
}
}
이상입니다.