자바 프로그래밍

컬렉션의 정렬

TreeSet과 TreeMap

지난 시간에는 Collection과 Map에 대해 알아보았습니다. 이번 시간에는 좀더 주제를 발전시켜서 Sorted 계열인 TreeSet과 TreeMap에 대해 알아보겠습니다. 지난 시간을 통해 Set과 Map의 차이점에 대해서는 어느 정도 학습이 되었으리라 생각합니다.

Set은 저장 순서와 상관없이 데이터의 존재 유무가 중요한 포인트이며 중복을 허용하지 않습니다. Map은 키와 값이라는 개념을 사용하여 연관배열(Associate Array)과 비슷한 개념의 자료구조를 만듭니다. Map에서 데이터는 유일한 키에 의해 저장되며, 데이터를 참조할 경우 키에 의해 참조하게 됩니다. 결과적으로 키들만을 놓고 본다면 Set의 구조를 가지게 됩니다.

Set과 Map의 경우 저장 순서가 의미를 갖지 않으므로 순서의 개념이 없으나 프로그램을 위해 정렬을 해야될 필요가 있게 됩니다. 이러한 경우를 위해 정렬의 개념을 도입한 TreeSet과 TreeMap이 제공됩니다.

일반적으로 Set의 경우 HashSet을 가장 많이 사용하며, Map의 경우 HashMap을 가장 많이 사용하게 되는데 이 HashSet과 HashMap을 정렬시키기 위해 TreeSet과 TreeMap으로 변환하여 사용합니다.

package net.jeongsam.collection;

import java.util.*;

class SortedEx02 {

	public static void main(String[] args) {
		HashSet<String> hSet = new HashSet<String>();
		HashMap<String, Integer> hMap = new HashMap<String, Integer>();
		
		Collections.addAll(hSet, "송아지", "강아지", "송아지", "망아지");
		
		hMap.put("홍길동", 150);
		hMap.put("김삿갓", 10);
		hMap.put("성춘향", 8);
		
		System.out.println("--- 정렬전 ---");
		System.out.println("Set: " + hSet);
		System.out.println("Map: " + hMap);
		
		TreeSet<String> tSet = new TreeSet<String>();
		TreeMap<String, Integer> tMap = new TreeMap<String, Integer>();

		// Set.addAll() 을 이용하여 HashSet을 추가
		tSet.addAll(hSet);
		// Map.putAll() 을 이용하여 HashMap을 추가
		tMap.putAll(hMap);
		
		System.out.println("--- 정렬후 ---");
		System.out.println("Set: " + tSet);
		System.out.println("Map: " + tMap);
	}

}

사용자 정의 타입의 정렬

TreeSet에 데이터를 저장하면 원시 데이터 타입이나 문자열의 경우 기본적으로 오름차순으로 정렬이 됩니다. 하지만 사용자가 직접 작성한 클래스 타입의 경우 Comparator 인터페이스를 구현해야만 정렬을 할 수 있습니다. Comparator 인터페이스는 compare() 추상 메서드만을 정의하였기 때문에 compare() 메서드를 구현하면 됩니다.

package net.jeongsam.collection;

public class Pet {
	private String name;
	
	public Pet(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object o) {
		boolean isEqual = false;
		if ((o instanceof Pet) && ((Pet)o).name.equals(name)) {
			isEqual = true;
		}
		
		return isEqual;
	}

	@Override
	public String toString() {
		return name;
	}
}
package net.jeongsam.collection;

import java.util.Comparator;

public class MyComparator<T> implements Comparator<T> {
	
	@Override
	public int compare(T o1, T o2) {
		String s1 = ((Pet)o1).getName();
		String s2 = ((Pet)o2).getName();
		
		return (s1.compareTo(s2));
	}

}
package net.jeongsam.collection;

import java.util.*;

class SortedEx03 {

	public static void main(String[] args) {
		TreeSet<Pet> setPet = new TreeSet<Pet>(new MyComparator<Pet>());
		
		Collections.addAll(setPet, new Pet("홍길동"), new Pet("이몽룡"), new Pet("성춘향"));
		
		System.out.println(setPet);	
	}
}

예제 9월 7일 Map의 사용

2009. 9. 7. 15:26
package net.jeongsam.collection;

import java.util.*;

class MapEx02 {

	public static void main(String[] args) {
		Map<String, String> students = new HashMap<String, String>();
		
		/*
		 * Map에 요소 추가하기
		 */
		students.put("200901003", "홍삼정");
		students.put("200902001", "오비타");
		students.put("200902002", "유성룡");
		
		/*
		 * Map에서 요소 읽어내기
		 */
		System.out.println(students.get("200902001"));
		
		/*
		 * 키나 값을 이용한 찾기
		 */
		System.out.println(students.containsKey("200902002"));
		System.out.println(students.containsValue("오비타"));
		
		/*
		 * 키를 Set에 담기
		 */
		Set<String> keys = students.keySet();
		System.out.println(keys);
		
		/*
		 * 값을 Collection에 담기
		 */
		Collection<String> values = students.values();
		System.out.println(values);
	}
}
package net.jeongsam.collection;

import java.util.*;

class ListEx02 {

	public static void main(String[] args) {
		/*
		 * ArrayList와 Vector의 선언
		 */
		List<String> strArrayList = new ArrayList<String>(5);
		List<String> strVector = new Vector<String>(5, 5);
		
		/*
		 * List에 요소 추가하기
		 */
		strArrayList.add("홍길동");
		strVector.add("홍길동");
		
		/*
		 * List의 크기 구하기
		 */
		System.out.println(strArrayList.size());
		System.out.println(strVector.size());
		
		// Vector의 메모리 할당량
		System.out.println(
				((Vector<String>)strVector).capacity());
		/*
		 * Collections.addAll() 이용한 추가
		 */
		Collections.addAll(strArrayList, "이몽룡", "성춘향",
				"월매", "변악도", "향단이", "방자");
		Collections.addAll(strVector, "이몽룡", "성춘향",
				"월매", "변악도", "이몽룡", "향단이", "방자");
		
		/*
		 * index를 이용한 요소 읽어오기
		 */
		System.out.println(
				((ArrayList<String>)strArrayList).get(2));
		System.out.println(
				((Vector<String>)strVector).elementAt(2));
		// Vector에서 첫번째 요소 읽기
		System.out.println(
				((Vector<String>)strVector).firstElement());
		System.out.println(
				((Vector<String>)strVector).indexOf("이몽룡"));
		// Vector에서 마지막 요소 읽기
		System.out.println(
				((Vector<String>)strVector).lastElement());
		System.out.println(
				((Vector)strVector).lastIndexOf("이몽룡"));
		// ArrayList와 Vector에 포함된 요소의 개수 알아내기
		System.out.println(searchCount(strArrayList, "이몽룡"));
		System.out.println(searchCount(strVector, "이몽룡"));		
	}

	public static int searchCount(Collection<String> c, String s) {
		Iterator<String> i = c.iterator();
		int count = 0;
		
		while (i.hasNext()) {
			if (i.next().equals(s)) count++;
		}
		
		return count;
	}
}
package net.jeongsam.collection;

public class PersonSet {
	private String name;
	private int age;
	
	public PersonSet(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public boolean equals(Object o) {
		if (!(o instanceof PersonSet)) return false;
		if (((PersonSet)o).name.equals(name)
				&& ((PersonSet)o).age == age)
			return true;
		else
			return false;
	}
	
	@Override
	public int hashCode() {
		// 조슈아 블러시 방법
		int result = 17;
		result = 37 * result + name.hashCode();
		result = 37 * result + age;
		return result; 
	}
	
	@Override
	public String toString() {
		return super.toString() + " " + name + " " + age;
	}
}
package net.jeongsam.collection;

import java.util.*;

class HashSetEx03 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Set<PersonSet> personSet = new HashSet<PersonSet>();
		
		Collections.addAll(personSet,
				new PersonSet("이몽룡", 16),
				new PersonSet("성춘향", 16),
				new PersonSet("월매", 40),
				new PersonSet("이몽룡", 16)
				);
		
		for (PersonSet p : personSet)
			System.out.println(p);
		
		System.out.println(new PersonSet("이몽룡", 16).equals(new PersonSet("이몽룡", 16)));
	}

}

예제 9월 7일 Set의 사용

2009. 9. 7. 11:39
package net.jeongsam.collection;

import java.util.*;

class HashSetEx02 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Set<Integer> s1 = new HashSet<Integer>();
		
		/*
		s1.add(1);
		s1.add(3);
		*/
		
		Collections.addAll(s1, 10, 3, 5, 10, 7, 3, 8);
		
		System.out.println(s1);
		
		Set<String> s2 = new HashSet<String>();
		
		Collections.addAll(s2, "홍길동", "홍길동", "이몽룡");
		
		System.out.println(s2);
		
		// Foreach 문을 이용한 출력
		for (String e : s2)
			System.out.println(e);
		
		// Iterator 인터페이스 이용
		Iterator<String> i = s2.iterator();
		while (i.hasNext())
			System.out.println(i.next());
		
		// Set에 데이터 추가
		s2.add("성춘향");
		
		// Set에서 데이터 검색 : true or false 
		System.out.println(s2.contains("이몽룡"));
		
		// Set에서 집합 검색 : true of false
		Set<String> comp = new HashSet<String>();
		Collections.addAll(comp, "이몽룡", "성춘향", "홍길동");
		// Collections.addAll(comp, "월매", "성춘향");
		
		System.out.println(s2.containsAll(comp));
		
		// Set과 Set을 비교
		System.out.println(s2.equals(comp));
		
		// cf. ArrayList의 경우
		List<String> list1 = new ArrayList<String>();
		List<String> list2 = new ArrayList<String>();
		Collections.addAll(list1, "이몽룡", "성춘향", "홍길동");
		Collections.addAll(list2, "성춘향", "이몽룡", "홍길동");
		
		System.out.println(list1.equals(list2));
		
		// Set에서 특정 요소의 삭제
		System.out.println(s2.remove("홍길동") ? "삭제 성공" : "삭제 실패");
		System.out.println(s2);
	}
}

+ Recent posts