자바의 정석 <기초편> 📌chapter11. 컬렉션 프레임웍

모깅·2023년 2월 9일
0

📖 01. 컬렉션 프레임웍

  • 라이브러리 : 공통으로 사용될만한 유용한 기능을 모듈화하여 제공
  • 프레임웍 : 기능뿐만아니라 프로그래밍 방식을 정형화

📖 02. 컬렉션 프레임웍의 핵심 인터페이스

  • 인터페이스 List와 Set의 공통된 부분을 다시 뽑아서 새로운 인터페이스 Collection을 추가로 정의

📖 03. Collection인터페이스

  • Collection인터페이스는 컬렉션 클래스에 저장된 데이터를 읽고, 추가하고 삭제하는 등 컬렉션을 다루는데 가장 기본적인 메서드들을 정의하고 있다.

📖 04. List인터페이스

-> Vector는 ArrayList의 old버전

  • Collection 인터페이스의 자식이니 Collection 인터페이스 메서드 사용가능.

📖 05. Set인터페이스

-> HashSet, TreeSet 중요!


📖 06. Map인터페이스


📖 07. ArrayList

-> Object배열을 멤버변수로 하고 있기 때문에 모든 객체를 담을 수 있다.


📖 08. ArrayList의 메서드


📖 09. ArrayList의 메서드 예제

<예제 11-1 >

✍️ 입력

import java.util.*;

class Ex11_1 {
	public static void main(String[] args) {
		ArrayList list1 = new ArrayList(10);
		list1.add(new Integer(5));
		list1.add(new Integer(4));
		list1.add(new Integer(2));
		list1.add(new Integer(0));
		list1.add(new Integer(1));
		list1.add(new Integer(3));

		ArrayList list2 = new ArrayList(list1.subList(1,4)); 
		print(list1, list2);

		Collections.sort(list1);	// list1과 list2를 정렬한다.
		Collections.sort(list2);	// Collections.sort(List l)
		print(list1, list2);

		System.out.println("list1.containsAll(list2):"
                                               + list1.containsAll(list2));

		list2.add("B");
		list2.add("C");
		list2.add(3, "A");
		print(list1, list2);

		list2.set(3, "AA");
		print(list1, list2);

		// list1에서 list2와 겹치는 부분만 남기고 나머지는 삭제한다.
		System.out.println("list1.retainAll(list2):" + list1.retainAll(list2));

		print(list1, list2);

		//  list2에서 list1에 포함된 객체들을 삭제한다.
		for(int i= list2.size()-1; i >= 0; i--) {
			if(list1.contains(list2.get(i)))
				list2.remove(i);
		}
		print(list1, list2);
	} // main의 끝

	static void print(ArrayList list1, ArrayList list2) {
		System.out.println("list1:"+list1);
		System.out.println("list2:"+list2);
		System.out.println();		
	}
} // class

💻 출력
list1:[5, 4, 2, 0, 1, 3]
list2:[4, 2, 0]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4]

list1.containsAll(list2):true
list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, A, B, C]

list1:[0, 1, 2, 3, 4, 5]
list2:[0, 2, 4, AA, B, C]

list1.retainAll(list2):true
list1:[0, 2, 4]
list2:[0, 2, 4, AA, B, C]

list1:[0, 2, 4]
list2:[AA, B, C]


📖 10. ArrayList의 추가와 삭제

-> 모두 삭제해야 한다면 2번의 방법을 사용하자.


📖 11. Java API소스보기

  • JDK 설치 디렉토리 src.zip에서 볼 수 있다.

📖 12. LinkedList && 13. LinkedList의 추가와 삭제

-> 이러한 배열의 단점을 보완하기 위해서 링크드 리스트(linked list)라는 자료구조가 고안되었다.

  • 링크드 리스트의 단점을 보완하고자 나온 리스트들이다.

📖 14. ArrayList와 LinkedList의 비교

-> 다루고자 하는 데이터의 개수가 변하지 않는 경우라면, ArrayList가 최상의 선택이 되겠지만, 데이터 개수의 변경이 잦다면 LinkedList를 사용하는 것이 더 나은 선택이 될 것이다.


📖 15. Stack과 Queue

스택 : 순차적으로 데이터를 추가하고 삭제하는 스택에는 ArrayList와 같은 배열기반의 컬렉션 클래스가 적합하다.

큐 : 데이터를 꺼낼 때 항상 첫 번째 저장된 데이터를 삭제하므로, ArrayList와 같은 배열기반의 컬렉션 클래스를 사용한다면 데이터를 꺼낼 때마다 빈 공간을 채우기 비효율적 -> 따라서 LinkedList 적합하다.


📖 16. Stack과 Queue의 메서드


📖 17. Stack과 Queue의 메서드 예제

<예제 11-2 >

✍️ 입력

import java.util.*;

class Ex11_2 {
	public static void main(String[] args) {
		Stack st = new Stack();
		Queue q = new LinkedList();	// Queue인터페이스의 구현체인 LinkedList를 사용
		
		st.push("0");
		st.push("1");
		st.push("2");

		q.offer("0");
		q.offer("1");
		q.offer("2");

		System.out.println("= Stack =");
		while(!st.empty()) {
			System.out.println(st.pop()); // 스택에서 요소 하나를 꺼내서 출력
		}

		System.out.println("= Queue =");
		while(!q.isEmpty()) {
			System.out.println(q.poll()); // 큐에서 요소 하나를 꺼내서 출력
		}
	}
}

💻 출력
= Stack =
2
1
0
= Queue =
0
1
2


📖 18. 인터페이스를 구현한 클래스 찾기

  • 네모안이 Queue인터페이스를 구현한 클래스이다.
  • 클래스들 중에서 적당한 것을 찾아 객체 생성 후 사용하면 그만이다.

📖 19. Stack과 Queue의 활용 && 20. Stack과 Queue의 활용 예제 1

<예제 11-3 >

✍️ 입력

import java.util.*;

public class Ex11_3 {
	public static void main(String[] args) {
//		if (args.length != 1) {
//			System.out.println("Usage:java Ex11_3 \"EXPRESSION\"");
//			System.out.println("Example:java Ex11_3 \"((2+3)*1)+3\"");
//			System.exit(0);
//		}

		Stack st = new Stack();
		String expression = "((2+3)*1)+3";

		System.out.println("expression:" + expression);

		try {
			for (int i = 0; i < expression.length(); i++) {
				char ch = expression.charAt(i);

				if (ch == '(') {
					st.push(ch + "");
				} else if (ch == ')') {
					st.pop();
				}
			}

			if (st.isEmpty()) {
				System.out.println("괄호가 일치합니다.");
			} else {
				System.out.println("괄호가 일치하지 않습니다.");
			}
		} catch (EmptyStackException e) {
			System.out.println("괄호가 일치하지 않습니다.");
		} // try
	}
}

💻 출력

expression:((2+3)*1)+3
괄호가 일치합니다.

-> 만약 ')' 가 더 많다면 예외가 발생한다.


📖 21. Stack과 Queue의 활용 예제 2

<예제 11-4 >

✍️ 입력

import java.util.*;

class Ex11_4 {
	static Queue q = new LinkedList();
	static final int MAX_SIZE = 5;	// Queue에 최대 5개까지만 저장되도록 한다.

	public static void main(String[] args) {
		System.out.println("help를 입력하면 도움말을 볼 수 있습니다.");

		while(true) {
			System.out.print(">>");
			try {
				// 화면으로부터 라인단위로 입력받는다.
				Scanner s = new Scanner(System.in);  
				String input = s.nextLine().trim();

				if("".equals(input)) continue;

				if(input.equalsIgnoreCase("q")) {
					System.exit(0);
				} else if(input.equalsIgnoreCase("help")) {
					System.out.println(" help - 도움말을 보여줍니다.");
					System.out.println(" q 또는 Q - 프로그램을 종료합니다.");
					System.out.println(" history - 최근에 입력한 명령어를 "
                                                  + MAX_SIZE +"개 보여줍니다.");
				} else if(input.equalsIgnoreCase("history")) {
					int i=0;
					// 입력받은 명령어를 저장하고,
					save(input);    

					// LinkedList의 내용을 보여준다.
					LinkedList tmp = (LinkedList)q;
					
                    final int SIZE = tmp.size();
                    for(int i = 0;i<SIZE;i++)
                    	system.out.println((i+1)+"."+tmp.get(0));
				} else {
					save(input);    
					System.out.println(input);
				} // if(input.equalsIgnoreCase("q")) {
			} catch(Exception e) {
				System.out.println("입력오류입니다.");
			}
		} // while(true)
	} //  main()
	public static void save(String input) {
		// queue에 저장한다.
		if(!"".equals(input))
          q.offer(input);

		// queue의 최대크기를 넘으면 제일 처음 입력된 것을 삭제한다.
		if(q.size() > MAX_SIZE)  // size()는 Collection인터페이스에 정의
			q.remove();
	}
} // end of class

💻 출력
help를 입력하면 도움말을 볼 수 있습니다.
>>DFD
DFD
>>hELP
help - 도움말을 보여줍니다.
q 또는 Q - 프로그램을 종료합니다.
history - 최근에 입력한 명령어를 5개 보여줍니다.
>>HIstory
1.DFD
2.HIstory
>>history
1.DFD
2.HIstory
3.history
>>dffdfd
dffdfd
>>history
1.DFD
2.HIstory
3.history
4.dffdfd
5.history
>>


📖 22. Iterator, Listlterator, Enumeration

-> Map의 경우 Collection인터페이스의 자손이 아니기 때문에 iterator()을 사용 할 수 없다.
-> entrySet()으로 Set으로 변형 한 뒤 iterator()을 호출하자.


📖 23. Iterator, Listlterator, Enumeration 예제

<예제 11-5 >

✍️ 입력

import java.util.*;

class Ex11_5 {
	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		list.add("1");
		list.add("2");
		list.add("3");
		list.add("4");
		list.add("5");

		Iterator it = list.iterator();

		while(it.hasNext()) {
			Object obj = it.next();
			System.out.println(obj);
		}
	} // main
}

💻 출력
1
2
3
4
5

-> ArrayList를 사용해도 되지만 다형성을 이용해 Collection을 사용하면 더욱 유연한 코드를 만들 수 있다.


📖 24. Map과 lterator

-> Map의 경우 Collection인터페이스의 자손이 아니기 때문에 iterator()을 사용 할 수 없다.
-> entrySet()으로 Set으로 변형 한 뒤 iterator()을 호출하자.


📖 25. Arrays의 메서드(1) - 복사 && 26. Arrays의 메서드(2) - 채우기, 정렬, 검색 && 27. Arrays의 메서드(3) - 비교와 출력 && 27. Arrays의 메서드(4) - 변환

-> asList()가 바환한 List의 크기를 변경할 수 없다. 즉, 추가 또는 삭제가 불가능하다. 저장된 내용은 변경가능하다. 만일 크기를 변경할 수 있는 List가 필요하다면 다음과 같이 하면 된다.

List list = new ArrayList(Arrays.asList(1,2,3,4,5));

📖 29. Arrays의 메서드 예제

<예제 11-6 >

✍️ 입력

import java.util.*;

class Ex11_6 {
	public static void main(String[] args) {
		int[]	   arr   = {0,1,2,3,4};
		int[][]	arr2D = {{11,12,13}, {21,22,23}};

		System.out.println("arr="+Arrays.toString(arr));
		System.out.println("arr2D="+Arrays.deepToString(arr2D));

		int[] arr2 = Arrays.copyOf(arr, arr.length);
		int[] arr3 = Arrays.copyOf(arr, 3);          
		int[] arr4 = Arrays.copyOf(arr, 7);          
		int[] arr5 = Arrays.copyOfRange(arr, 2, 4);  
		int[] arr6 = Arrays.copyOfRange(arr, 0, 7);  

		System.out.println("arr2="+Arrays.toString(arr2));
		System.out.println("arr3="+Arrays.toString(arr3));
		System.out.println("arr4="+Arrays.toString(arr4));
		System.out.println("arr5="+Arrays.toString(arr5));
		System.out.println("arr6="+Arrays.toString(arr6));
		
		int[] arr7 =  new int[5];
		Arrays.fill(arr7, 9);  // arr=[9,9,9,9,9]
		System.out.println("arr7="+Arrays.toString(arr7));

		Arrays.setAll(arr7, i -> (int)(Math.random()*6)+1);
		System.out.println("arr7="+Arrays.toString(arr7));

		for(int i : arr7) {
			char[] graph = new char[i];
			Arrays.fill(graph, '*');
			System.out.println(new String(graph)+i);
		}

		String[][] str2D  = new String[][]{{"aaa","bbb"},{"AAA","BBB"}};
		String[][] str2D2 = new String[][]{{"aaa","bbb"},{"AAA","BBB"}};

		System.out.println(Arrays.equals(str2D, str2D2));     // false
		System.out.println(Arrays.deepEquals(str2D, str2D2)); // true

		char[] chArr = { 'A', 'D', 'C', 'B', 'E' };

		System.out.println("chArr="+Arrays.toString(chArr));
		System.out.println("index of B ="+Arrays.binarySearch(chArr, 'B'));
		System.out.println("= After sorting =");
		Arrays.sort(chArr);
		System.out.println("chArr="+Arrays.toString(chArr));
		System.out.println("index of B ="+Arrays.binarySearch(chArr, 'B'));
	}
}

💻 출력
arr=[0, 1, 2, 3, 4]
arr2D=[[11, 12, 13], [21, 22, 23]]
arr2=[0, 1, 2, 3, 4]
arr3=[0, 1, 2]
arr4=[0, 1, 2, 3, 4, 0, 0]
arr5=[2, 3]
arr6=[0, 1, 2, 3, 4, 0, 0]
arr7=[9, 9, 9, 9, 9]
arr7=[6, 5, 3, 4, 5]
**6
*5
*3
**
4
*5
false
true
chArr=[A, D, C, B, E]
index of B =-2
= After sorting =
chArr=[A, B, C, D, E]
index of B =1


📖 30. Comparator와 Comparable


📖 31. Comparator와 Comparable 예제

<예제 11-7 >

✍️ 입력

import java.util.*;

class Ex11_7 {
	public static void main(String[] args) {
		String[] strArr = {"cat", "Dog", "lion", "tiger"};

		Arrays.sort(strArr); // String의 Comparable구현에 의한 정렬
		System.out.println("strArr=" + Arrays.toString(strArr));

		Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소문자 구분안함
		System.out.println("strArr=" + Arrays.toString(strArr));

		Arrays.sort(strArr, new Descending()); // 역순 정렬
		System.out.println("strArr=" + Arrays.toString(strArr));
	}
}

class Descending implements Comparator { 
	public int compare(Object o1, Object o2){
		if( o1 instanceof Comparable && o2 instanceof Comparable) {
			Comparable c1 = (Comparable)o1;
			Comparable c2 = (Comparable)o2;
			return c1.compareTo(c2) * -1 ; // -1을 곱해서 기본 정렬방식의 역으로 변경한다.
						                // 또는 c2.compareTo(c1)와 같이 순서를 바꿔도 된다.
		}
		return -1;
	} 
}

💻 출력
strArr=[Dog, cat, lion, tiger]
strArr=[cat, Dog, lion, tiger]
strArr=[tiger, lion, cat, Dog]

-> 정렬을 할 때 두가지가 필요하다.
1. 정렬 대상 2. 정렬 기준

-> 정렬은 두 대상을 비교해서 바꿔주는 일이다.
바꿔 주는 것은 불변이기 때문에 가변인 정렬 기준만 바꿔주면 된다.

-> sort()메서드 내부에 대상을 바꿔주는 코드가 존재하며, 특정 기준으로 비교한 값을 대상을 한다.


📖 32. Integer와 Comparable

  • 대부분 삼항 연산자를 통해 compareTo()를 구현했지만 단순히 뺄셈으로도 구현 가능하다. (뺄셈을 통해 양수, 음수, 0 판단가능)

📖 33. Integer와 Comparable 예제

<예제 11-8 >

✍️ 입력

import java.util.*; 

class Ex11_8 { 
	public static void main(String[] args) { 
		Integer[] arr = { 30, 50, 10, 40, 20 }; 

		Arrays.sort(arr); // Integer가 가지고 있는 기본 정렬 기준 compareTo()로 정렬 
		System.out.println(Arrays.toString(arr));

		// sort(Object[] objArr, Comparator c)
		Arrays.sort(arr, new DescComp()); // DescComp에 구현된 정렬 기준으로 정렬
		System.out.println(Arrays.toString(arr));
	} // main
}	

class DescComp implements Comparator {
	public int compare(Object o1, Object o2) {
		if(!(o1 instanceof Integer && o2 instanceof Integer))
			return -1; // Integer가 아니면, 비교하지 않고 -1 반환

		Integer i  = (Integer)o1;
		Integer i2 = (Integer)o2;
		
		// return i2 - i; 또는 return i2.compareTo(i);도 가능
		return i.compareTo(i2) * -1; // 기본 정렬인 compareTo()의 역순으로 정렬
	}
}

💻 출력
[10, 20, 30, 40, 50]
[50, 40, 30, 20, 10]


📖 34. HashSet

-> Set인터페이스 특징대로 HashSet은 중복과 순서 X


📖 35. HashSet 예제 1

<예제 11-9 >

✍️ 입력

import java.util.*;

class Ex11_9 {
	public static void main(String[] args) {
		Object[] objArr = {"1",new Integer(1),"2","2","3","3","4","4","4"};
		Set set = new HashSet();

		for(int i=0; i < objArr.length; i++) {
			set.add(objArr[i]);	// HashSet에 objArr의 요소들을 저장한다.
		}
                // HashSet에 저장된 요소들을 출력한다.
		System.out.println(set);	

		// HashSet에 저장된 요소들을 출력한다.(Iterator이용)
		Iterator it = set.iterator();
		
		while(it.hasNext()) {
			System.out.println(it.next());	
		}
	}
}

💻 출력
[1, 1, 2, 3, 4]
1
1
2
3
4

-> add메서드는 개체를 추가할 때 HashSet에 이미 같은 객체가 있으면 중복으로 간주하고 저장하지 않는다. 그리고는 작업이 실패했다는 의미로 false를 반환한다.

-> Set을 구현한 컬렉션 클래스는 List를 구현한 컬렉션 클래스와 달리 순서를 유지하지 않기 때문에 저장한 순서와 다를 수 있다.

-> 만일 중복을 제거하는 동시에 저장한 순서를 유지하고자 한다면 LinkedHashSet을 사용하자.


📖 36. HashSet 예제 2

<예제 11-10 >

✍️ 입력

import java.util.*;

class Ex11_10 {
	public static void main(String[] args) {
		Set set = new HashSet();
		
		for (int i = 0; set.size() < 6 ; i++) {
			int num = (int)(Math.random()*45) + 1;
			set.add(new Integer(num));
		}

		List list = new LinkedList(set); // LinkedList(Collection c)
		Collections.sort(list);          // Collections.sort(List list)
		System.out.println(list);
	}
}

💻 출력
[4, 10, 13, 21, 27, 42]


📖 37. HashSet 예제 3

<예제 11-10 >

✍️ 입력

import java.util.*;

class Ex11_11 {
	public static void main(String[] args) {
		HashSet set = new HashSet();

		set.add("abc");
		set.add("abc");
		set.add(new Person("David",10));
		set.add(new Person("David",10));

		System.out.println(set);
	}
}

public int hashCode() {
	return Objects.hash(name, age);
    }
    
public boolean equals(Object obj) {
	if(!(obj instanceof Person)) return false;
    
    Person p = (Person)obj;
    return this.name.equals(p.name) && this.age == p.age;
    }

class Person {
	String name;
	int age;

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String toString() {
		return name +":"+ age;
	}
}

💻 출력
[David:10, abc]

-> add메서드는 새로운 요소를 추가하기 전에 기존에 저장된 요소와 같은 것인지 판별하기 위해 추가하려는 요소의 equals()와 hashCode()를 호출하기 때문에 목적에 맞게 오버라이딩 해야한다.


📖 38. HashSet 예제 4

<예제 11-11 >

✍️ 입력

import java.util.*;

class Ex11_12 {
	public static void main(String args[]) {
		HashSet setA   = new HashSet();
		HashSet setB   = new HashSet();
		HashSet setHab = new HashSet();
		HashSet setKyo = new HashSet();
		HashSet setCha = new HashSet();

		setA.add("1");	 setA.add("2");  setA.add("3");
		setA.add("4");  setA.add("5");
		System.out.println("A = "+setA);

		setB.add("4");	 setB.add("5");  setB.add("6");		
      setB.add("7");  setB.add("8");
		System.out.println("B = "+setB);

		Iterator it = setB.iterator();
		while(it.hasNext()) {
			Object tmp = it.next();
			if(setA.contains(tmp))
				setKyo.add(tmp);
		}
        // setA.retainAll(setB);  // 교집합. 공통된 요소만 남기고 삭제

		it = setA.iterator();
		while(it.hasNext()) {
			Object tmp = it.next();
			if(!setB.contains(tmp))
				setCha.add(tmp);
		}
        // setA.removeAll(setB);  // 차집합. setB와 공통 요소를 제거

		it = setA.iterator();
		while(it.hasNext())
			setHab.add(it.next());

		it = setB.iterator();
		while(it.hasNext())
			setHab.add(it.next());
        // setA.addAll(setB);  // 합집합. setB의 모든 요소를 추가(중복 제외)

		System.out.println("A ∩ B = " + setKyo);  // 한글 ㄷ을 누르고 한자키
		System.out.println("A U B = " + setHab);  // 한글 ㄷ을 누르고 한자키
		System.out.println("A - B = " + setCha); 
	}
}

💻 출력
A = [1, 2, 3, 4, 5]
B = [4, 5, 6, 7, 8]
A ∩ B = [4, 5]
A U B = [1, 2, 3, 4, 5, 6, 7, 8]
A - B = [1, 2, 3]


📖 39. TreeSet

-> 저장순서와 중복을 허용하지 않는다.


📖 40. 이진 탐색 트리(binary search tree)

  1. 모든 노드는 최대 두 개의 자식노드를 가질 수 있다.
  2. 왼쪽 자식노드의 값은 부모노드의 값보다 작고 오른쪽 자식노드의 값은 부모노드의 값보다 커야한다.
  3. 노드의 추가 삭제에 시간이 걸린다.(반복 비교로 자리를 찾아 저장)
  4. 검색(범위검색)과 정렬에 유리하다.
  5. 중복된 값을 저장하지 못한다.
  6. 데이터를 순차적으로 저장하는 것이 아니라 저장위치를 찾아서 저장해야하고, 삭제하는 경우 트리의 일부를 재구성해야 하므로 링크드 리스트보다 데이터의 추가/삭제시간은 더 걸린다.

📖 41. 이진 탐색 트리의 저장과정

-> 컴퓨터는 알아서 값을 비교하지 못한다.
따라서 , TreeSet에 저장되는 객체가 Comparable을 구현하던가 아니면, Comparator를 제공해서 두 객체를 비교할 방법을 알려줘야 한다.
그렇지 않으면, TreeSet에 객체를 저장할 때 예외가 발생한다.


📖 42. TreeSet의 메서드


📖 43. TreeSet 예제 1

<예제 11-13 >

✍️ 입력

import java.util.*;

class Ex11_13 {
	public static void main(String[] args) {
		Set set = new TreeSet();
		
		for (int i = 0; set.size() < 6 ; i++) {
			int num = (int)(Math.random()*45) + 1;
			set.add(num);  // set.add(new Integer(num));
		}

		System.out.println(set);
	}
}

💻 출력
[1, 19, 24, 25, 30, 45]

-> add를 사용하면 정렬기준이 필요한데, TreeSet에 존재하는 Comparable이 기본정렬을 제공한다.


📖 44. TreeSet 예제 2

<예제 11-14 >

✍️ 입력

import java.util.*;

class Ex11_14 {
	public static void main(String[] args) {
		TreeSet set = new TreeSet();

		String from = "b";
		String to	= "d";

		set.add("abc");      set.add("alien");    set.add("bat");
		set.add("car");      set.add("Car");      set.add("disc");
		set.add("dance");    set.add("dZZZZ");    set.add("dzzzz");
		set.add("elephant"); set.add("elevator"); set.add("fan");
		set.add("flower");

		System.out.println(set);
		System.out.println("range search : from " + from  +" to "+ to);
		System.out.println("result1 : " + set.subSet(from, to));
		System.out.println("result2 : " + set.subSet(from, to + "zzz"));
	}
}

💻 출력
[Car, abc, alien, bat, car, dZZZZ, dance, disc, dzzzz, elephant, elevator, fan, flower]
range search : from b to d
result1 : [bat, car]
result2 : [bat, car, dZZZZ, dance, disc]

-> subSet()메서드를 사용하면 범위검색에 유리하다.
-> subSet()메서드는 TreeSet클래스의 메서드이므로 TreeSet -> Set으로 바꿀 수 없다. (다형성 사용해서는 안됨!)


📖 45. TreeSet 예제 3

<예제 11-15 >

✍️ 입력

import java.util.*;

class Ex11_15 {
	public static void main(String[] args) {
		TreeSet set = new TreeSet();
		int[] score = {80, 95, 50, 35, 45, 65, 10, 100};

		for(int i=0; i < score.length; i++)
			set.add(new Integer(score[i]));

		System.out.println("50보다 작은 값 :" + set.headSet(new Integer(50)));
		System.out.println("50보다 큰 값 :"  + set.tailSet(new Integer(50)));
	}
}

💻 출력
50보다 작은 값 :[10, 35, 45]
50보다 큰 값 :[50, 65, 80, 95, 100]


📖 46. HashMap과 Hashtable

-> 키(key)와 값(value)은 별개의 값이 아니라 서로 관련된 값이기 때문에 각각의 배열로 선언하기 보다는 하나의 클래스로 정의해서 하나의 배열로 다루는 것이 데이터의 무결성(integraity)적인 측면에서 더 바람직하기 때문이다.


📖 47. HashMap의 키(key)와 값(value)

키는 컬렉션내에서 유일(unique)해야 한다. 하나의 키를 검색했을 때 결과가 단 하나이어야 함을 뜻한다.


📖 48. HashMap의 메서드


📖 49. HashMap 예제 1

<예제 11-16 >

✍️ 입력

import java.util.*;

class Ex11_16 {
	public static void main(String[] args) {
		HashMap map = new HashMap();
		map.put("myId", "1234");
		map.put("asdf", "1111");
		map.put("asdf", "1234");

		Scanner s = new Scanner(System.in);	// OK. 이미 존재하는 키 추가가능. 기존 값은 없어짐

		while(true) {
			System.out.println("id와 password를 입력해주세요.");
			System.out.print("id :");
			String id = s.nextLine().trim();

			System.out.print("password :");
			String password = s.nextLine().trim();
			System.out.println();

			if(!map.containsKey(id)) {
				System.out.println("입력하신 id는 존재하지 않습니다. 다시 입력해주세요.");
				continue;
			} 
			
			if(!(map.get(id)).equals(password)) {
				System.out.println("비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
			} else {
				System.out.println("id와 비밀번호가 일치합니다.");
				break;
			}
		} // while
	} // main의 끝
}

💻 출력
id와 password를 입력해주세요.
id : asdf
password :1111

비밀번호가 일치하지 않습니다. 다시 입력해주세요.
id와 password를 입력해주세요.
id :asdf
password :1234

id와 비밀번호가 일치합니다.


📖 50. HashMap 예제 2

<예제 11-17 >

✍️ 입력

import java.util.*;

class Ex11_17 {
	public static void main(String[] args) {
		HashMap map = new HashMap();
		map.put("김자바", 90);
		map.put("김자바", 100);
		map.put("이자바", 100);
		map.put("강자바", 80);
		map.put("안자바", 90);

		Set set = map.entrySet();
		Iterator it = set.iterator();

		while(it.hasNext()) {
			Map.Entry e = (Map.Entry)it.next();
			System.out.println("이름 : "+ e.getKey() + ", 점수 : " + e.getValue());
		}

		set = map.keySet();
		System.out.println("참가자 명단 : " + set);

		Collection values = map.values();
		it = values.iterator();

		int total = 0;
		
		while(it.hasNext()) {
			int i = (int)it.next();
			total += i;
		}

		System.out.println("총점 : " + total);
		System.out.println("평균 : " + (float)total/set.size());
		System.out.println("최고점수 : " + Collections.max(values));
		System.out.println("최저점수 : " + Collections.min(values));
	}
}

💻 출력
이름 : 안자바, 점수 : 90
이름 : 김자바, 점수 : 100
이름 : 강자바, 점수 : 80
이름 : 이자바, 점수 : 100
참가자 명단 : [안자바, 김자바, 강자바, 이자바]
총점 : 370
평균 : 92.5
최고점수 : 100
최저점수 : 80


📖 51. HashMap 예제 3

<예제 11-18 >

✍️ 입력

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

class Test0001 {
	public static void main(String[] args) {
		String[] data = { "A","K","A","K","D","K","A","K","K","K","Z","D" };

		HashMap map = new HashMap();

		for(int i=0; i < data.length; i++) {
			if(map.containsKey(data[i])) {
				int value = (int)map.get(data[i]);
				map.put(data[i], value+1);  // 기존에 있는 키는 기존 값에 1을 더해서 저장
			} else {
				map.put(data[i], 1);	    // 기존에 없던 키는 값을 1로 저장
			}
		}

		Iterator it = map.entrySet().iterator();

		while(it.hasNext()) {
			Map.Entry entry = (Map.Entry)it.next();
			int value = (int)entry.getValue();
			System.out.println(entry.getKey() + " : " + printBar('#', value) + " " + value );
		}
	} // main

	public static String printBar(char ch, int value) { 
		char[] bar = new char[value]; 

		for(int i=0; i < bar.length; i++)
			bar[i] = ch; 

		return new String(bar); // String(char[] chArr)
	}
}

💻 출력
A : ### 3
D : ## 2
Z : # 1
K : ###### 6


📖 52. Collections의 메서드 - 동기화 && 53. Collections의 메서드 - 변경불가, 싱글톤 && 54. Collections의 메서드 - 단일 컬렉션

  • 멀티 쓰레드(multi-thread) 프로그래밍에서는 하나의 객체를 여러 쓰레드가 동시에 접근 할 수 있기 때문에 데이터의 무결성(integrity)을 유지하기 위해서는 공유되는 객체에 동기화(synchronization)가 필요하다.


📖 55. Collections 예제

<예제 11-19 >

✍️ 입력

import java.util.*;
import static java.util.Collections.*;

class Ex11_19 {
	public static void main(String[] args) {
		List list = new ArrayList();
		System.out.println(list);

		addAll(list, 1,2,3,4,5); 
		System.out.println(list);
		
		rotate(list, 2);  // 오른쪽으로 두 칸씩 이동
		System.out.println(list);

		swap(list, 0, 2); // 첫 번째와 세 번째를 교환(swap)
		System.out.println(list);

		shuffle(list);    // 저장된 요소의 위치를 임의로 변경
		System.out.println(list);

		sort(list, reverseOrder()); // 연순 정렬 reverse(list);와 동일 
		System.out.println(list);
		
		sort(list);       // 정렬
		System.out.println(list);
 
		int idx = binarySearch(list, 3);  // 3이 저장된 위치(index)를 반환
		System.out.println("index of 3 = " + idx);
		
		System.out.println("max="+max(list));
		System.out.println("min="+min(list));
		System.out.println("min="+max(list, reverseOrder()));

		fill(list, 9); // list를 9로 채운다.
		System.out.println("list="+list);

		// list와 같은 크기의 새로운 list를 생성하고 2로 채운다. 단, 결과는 변경불가
		List newList = nCopies(list.size(), 2); 
		System.out.println("newList="+newList);

		System.out.println(disjoint(list, newList)); // 공통요소가 없으면 true

		copy(list, newList); 
		System.out.println("newList="+newList);
		System.out.println("list="+list);

		replaceAll(list, 2, 1); 
		System.out.println("list="+list);

		Enumeration e = enumeration(list);
		ArrayList list2 = list(e); 

		System.out.println("list2="+list2);
	}
}

💻 출력
[]
[1, 2, 3, 4, 5]
[4, 5, 1, 2, 3]
[1, 5, 4, 2, 3]
[5, 1, 3, 2, 4]
[5, 4, 3, 2, 1]
[1, 2, 3, 4, 5]
index of 3 = 2
max=5
min=1
min=1
list=[9, 9, 9, 9, 9]
newList=[2, 2, 2, 2, 2]
true
newList=[2, 2, 2, 2, 2]
list=[2, 2, 2, 2, 2]
list=[1, 1, 1, 1, 1]
list2=[1, 1, 1, 1, 1]


📖 56. 컬렉션 클래스 정리 & 요약





[출처] 자바의 정석 <기초편> (남궁 성 지음)

profile
멈추지 않기

0개의 댓글