이 글은 남궁성의 정석코딩 [자바의정석-기초편]을 수강하며 정리한 글입니다.
🟣 기본 환경: IDE: Eclipse, Language: Java
Set: 순서X, 중복X
TreeSet: 이진 검색 트리(Binary Search Tree*)를 활용하여 자료 정렬
* Binary Search Tree: 조상 노드의 왼쪽에는 조상 노드보다 작은 값, 오른쪽에는 큰 값을 저장하는 이진트리, 첫 번째로 저장하는 값이 최고 조상 노드(=루트)가 됨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.util.*;
public class Ex11_15 {
public static void main(String[] args) {
// set: 중복 X, 순서 X
// treeSet: 중복 X, 순서 O
// Constructs a new, empty tree set, sorted according to the natural ordering of its elements.
TreeSet<Integer> set = new TreeSet<>();
int[] scope = {80, 95, 20, 45, 10, 55, 50, 30, 75, 100, 60};
for(int i=0; i<scope.length; i++) {
set.add(Integer.valueOf(scope[i]));
}
System.out.println("TreeSet: "+set);
System.out.println("50보다 작은 값: "+set.headSet(50));
// headSet: Returns a view of the portion of this set whose elements are strictly less than toElement.
System.out.println("50보다 큰 값: "+set.tailSet(Integer.valueOf(50)));
// from 포함, to 미포함
// 50 -> new Integer(50) 자동 형변환
System.out.println("From 40 to 80: "+set.subSet(40, 80));
}
}
|
Set.HashSet: 순서(인덱스)X, 중복X*
* 값이 추가될 때마다, hashcode()->equals() 비교하여 모두 true일 경우, 동일 객체로 판단
합집합, 교집합, 차집합
* 계산 시, 초기값을 변경하지 말고 새로운 객체 생성(향후 계산 시 문제 발생)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
import java.util.HashSet;
import java.util.Iterator;
public class Ex11_12 {
public static void main(String[] args) {
HashSet<Integer> setA = new HashSet<>();
HashSet<Integer> setB = new HashSet<>();
HashSet<Integer> setHab = new HashSet<>();
HashSet<Integer> setKyo = new HashSet<>();
HashSet<Integer> setCha = new HashSet<>();
setA.add(1);
setA.add(2);
setA.add(3);
setA.add(4);
setA.add(5);
System.out.println("setA: "+setA);
setB.add(4);
setB.add(5);
setB.add(6);
setB.add(7);
setB.add(8);
System.out.println("SetB: "+setB);
// 합집합
Iterator<Integer> it = setA.iterator(); // iterator는 일회용이므로 사용시마다 생성
while(it.hasNext()) { // 읽어올 다음 요소가 있는 동안
setHab.add(it.next()); // 요소 하나 꺼내오기
}
it = setB.iterator(); // iterator는 일회용이므로 사용시마다 생성
while(it.hasNext()) {
setHab.add(it.next());
}
System.out.println("setHab: "+setHab);
// setA와 setB를 직접 건드리는 것은 차후 계산에 영향을 미치게되므로 새로운 참조변수 생성하여 진행
// setA.addAll(setB); // 합집합, setB 모든 요소 추가(중복 제외)
// System.out.println("Hab: "+setA);
// 교집합
Iterator<Integer> it2 = setA.iterator(); // iterator는 사용시마다 생성
it2 = setB.iterator();
while(it2.hasNext()) {
Integer tmp = it2.next();
if(setA.contains(tmp)) {setKyo.add(tmp);}
}
System.out.println("setKyo: "+setKyo);
// setA.retainAll(setB); // 공통된 요소만 남기고 삭제
// System.out.println("Kyo: "+setA);
// 차집합
Iterator<Integer> it3 = setA.iterator();
it3 = setA.iterator();
while(it3.hasNext()) {
Integer tmp = it3.next();
if(!setB.contains(tmp)) {setCha.add(tmp);}
// 만일 setB가 tmp(setA의 각 요소)를 포함하고 있지 않다면 setCha에 추가
}
System.out.println("setCha: "+setCha);
// System.out.println(setA);
// System.out.println(setB);
// setA.removeAll(setB); // 차집합, 공통된 요소 모두 제거
// System.out.println("Cha: "+setA);
}
}
import java.util.*;
public class Ex11_15 {
public static void main(String[] args) {
// set: 중복 X, 순서 X
// treeSet: 중복 X, 순서 O
// Constructs a new, empty tree set, sorted according to the natural ordering of its elements.
TreeSet<Integer> set = new TreeSet<>();
int[] scope = {80, 95, 20, 45, 10, 55, 50, 30, 75, 100, 60};
for(int i=0; i<scope.length; i++) {
set.add(Integer.valueOf(scope[i]));
}
System.out.println("TreeSet: "+set);
System.out.println("50보다 작은 값: "+set.headSet(50));
// headSet: Returns a view of the portion of this set whose elements are strictly less than toElement.
System.out.println("50보다 큰 값: "+set.tailSet(Integer.valueOf(50)));
// from 포함, to 미포함
// 50 -> new Integer(50) 자동 형변환
System.out.println("From 40 to 80: "+set.subSet(40, 80));
}
}
|
treeSet: 이진탐색정렬 -> 정렬기준 필요, 중복X
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
import java.util.*;
public class Ex11_13 {
public static void main(String[] args) {
// TreeSet(): 범위 검색 유리, 자동 정렬, 중복X
Set<Object> treeSet = new TreeSet<>(new TestComp());
// 정렬기준으 2개일 때는, TreeSet(정렬기준)이 우선 적용됨
Set<Object> treeSet2 = new TreeSet<>();
// HashSet: 정렬X
Set<Object> hashSet3 = new HashSet<>();
treeSet2.add(1);
treeSet2.add(2);
treeSet2.add(3);
treeSet2.add(3); // 중복으로 treeSet에 저장X
// Test class에서는 comparable을 구현하고 있지 않으므로 set.add를 할 경우 오류 발생
for(int i=0; treeSet.size()<6; i++) {
int num = (int)(Math.random()*45)+1;
// treeSet.add(num); // AutoBoxing
treeSet.add(Integer.valueOf(num));
treeSet.add(new Test());
// ClassCastException(형변환 예외): class Test cannot be cast to class java.lang.Integer)
// set.add()는 이진탐색트리를 통해서 비교하면서 add()를 수행하는데 비교 기준이 없음
// 비교기준을 만들어 treeSet 정렬기준에 대입: new TreeSet<>(new TestComp())
hashSet3.add(num);
}
treeSet.add(new Test());
treeSet.add(new Test());
treeSet.add(new Test());
System.out.println("TreeSet: "+treeSet);
System.out.println("TreeSet2: "+treeSet2);
System.out.println("HashSet: "+hashSet3);
}
}
class Test implements Comparable<Object> {
// Test class와 달리 스스로 비교 기준을 마련할 경우, treeSet 사용가능(예: Integer)
// treeSet 객체 생성 시 따로 비교기준 입력 필요 X: new TreeSet<>()
@Override
public int compareTo(Object o) {
return 1;
}
}
class Test2 {}
// 비교 기준을 따로 구현하지 않았는데 Test2를 객체로하여 treeSet을 이용할 경우, Exception 발생
class TestComp implements Comparator<Object> {
// new Test2() 객체를 treeSet으로 구현하기 위한 비교 기준 마련
@Override
public int compare(Object o1, Object o2) {
return -1; // return을 0으로 했을 경우, o1, o2가 같다고 취급됨
}
}
|
subSet()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
import java.util.*;
public class Ex11_14 {
public static void main(String[] args) {
TreeSet<String> set = new TreeSet<>();
String from = "b";
String to = "d";
String to2 = "e";
set.add("abc");
set.add("apple");
set.add("bcd");
set.add("banana");
set.add("cde");
set.add("Car"); // 대문자가 가장 먼저 정렬
set.add("car");
set.add("document");
set.add("drop");
set.add("department");
set.add("element");
set.add("eating");
set.add("frequence");
set.add("flower");
set.add("generic");
set.add("grow");
System.out.println("set: "+set);
System.out.println("range search: "+set.subSet(from, to));
// 대문자 미포함, to 미포함
System.out.println("range search2: "+set.subSet(from, to2));
System.out.println("range search2: "+set.subSet(from, to+"zzz"));
// to+"zzz"="dzzz"
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.util.*;
public class Ex11_15 {
public static void main(String[] args) {
// set: 중복 X, 순서 X
// treeSet: 중복 X, 순서 O (이진탐색트리)
TreeSet<Integer> set = new TreeSet<>();
int[] scope = {80, 95, 20, 45, 10, 55, 50, 30, 75, 100, 60};
for(int i=0; i<scope.length; i++) {
set.add(Integer.valueOf(scope[i]));
// Integer는 자체적으로 Comparable을 구현하고 있으므로 따로 비교기준을 입력하지 않아도 됨
}
System.out.println("TreeSet: "+set);
System.out.println("50보다 작은 값: "+set.headSet(50));
// headSet: Returns a view of the portion of this set whose elements are strictly less than toElement.
System.out.println("50보다 큰 값: "+set.tailSet(Integer.valueOf(50)));
// from 포함, to 미포함
// 50 -> new Integer(50) 자동 형변환
System.out.println("From 40 to 80: "+set.subSet(40, 80));
}
}
|
HashMap(Key, Value): 순서X, Key 중복X
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
import java.util.*;
public class Ex11_16 {
public static void main(String[] args) {
// HashMap: 순서X, key 중복X
HashMap<Object, Object> map = new HashMap<>();
map.put("abc", "1234"); // put: 추가
map.put("bcd", "2345");
map.put("bcd", "3456"); // 최종 "bcd", "3456" 저장
System.out.println(map.size());
Scanner s = new Scanner(System.in);
for(int i=0; i<3; i++) {
System.out.println("Enter the ID and PW.");
System.out.print("ID: ");
String id = s.nextLine().trim(); // enter 단위로 입력 받음
System.out.print("PW: ");
String pw = s.nextLine().trim();
System.out.println();
if(!map.containsKey(id)) {
System.out.println("There is no Identification.");
System.out.println();
continue;
// 반복문 + continue = 아래 반복문 내용을 더이상 수행하지 않고 반복문 첫 문장으로 올라감
}
if(!map.get(id).equals(pw)) { // get(Object o): value값 반환
System.out.println("Incorrect Password.");
System.out.println();
} else {
System.out.println("Logined");
break; // 반복문 중단
}
} s.close(); // Resource leak: 's' is never closed
}
}
|
형변환
Collection type value 값 반환 -> (Set) 형변환 X
객체를 부모로 만들고 리모컨을 자손으로 설정 할 수 X (실행할 수 없는 method가 있을 수도 있기 때문)
Map과 Set
Set<Map.Entry<String, Integer>> set = map.entrySet() // Set<Map.Entry<K,V>> entrySet()
Iterator<Map.Entry<K, V>> it = set.iterator<Map.Entry<K, V>>();
set = map.keySet(); // Set<K> keySet()
Set의 Generics를 <Map.Entry<String, Integer>>로 선언 시, Set<K> keySet()를 사용하지 못하는 문제 발생 -> Generics 선언 X
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
import java.util.*;
public class Ex11_17 {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("Apple", Integer.valueOf(95));
map.put("Apple", Integer.valueOf(100));
map.put("Banana", Integer.valueOf(40));
map.put("Car", Integer.valueOf(75));
map.put("Document", Integer.valueOf(60));
Set set = map.entrySet();
// Set<Map.Entry<K, V>> entrySet(); -> 차후 Set<K> keySet() 사용 X (형변환X)
// entrySet(): key, value 참조
// set.iterator: map에서 쓸 수 없으므로 set으로 형 변환
Iterator it = set.iterator();
//<Map.Entry<String, Integer>>
while(it.hasNext()) { // 읽을 요소가 남아있는지 확인
Map.Entry e = (Map.Entry) it.next(); // 읽은 요소 map type으로 반환
// Map interface 안에 Entry interface:
System.out.println("Name: "+e.getKey()+", Score: "+e.getValue());
}
set = map.keySet(); // Set type key값 반환
System.out.println("NameList: "+set);
Collection<Integer> collection = map.values();
if(collection instanceof Set) {System.out.println("ScoreList: "+collection);}
// Collection type value 값 반환 -> (Set) 형변환X
// 객체를 부모로 만들고 리모컨을 자손으로 설정 할 수 X (실행할 수 없는 method가 있을 수도 있기 때문)
else {System.out.println("Something is Worng.");}
Collection<Integer> values = map.values();
it = values.iterator();
int total = 0;
while(it.hasNext()) {
Integer i = (Integer) it.next();
total += i.intValue(); // Integer -> int
// int i = (int) it.next(); // AutoBoxing
// total += i;
}
System.out.println("Total: "+total);
System.out.println("Average: "+(float)total/set.size());
System.out.println("Max: "+Collections.max(values));
System.out.println("Min: "+Collections.min(values));
}
}
|
조상 class의 가용 method가 적을 때는 자손 class를 활용하여 더 많은 method 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Ex11_18 {
public static void main(String[] args) {
String[] data = {"A", "B", "A", "D", "C", "B", "A", "B", "A", "D", "D", "C", "D"};
HashMap map = new HashMap();
for(int i=0; i<data.length; i++) {
if(map.containsKey(data[i])) {
// map이 data[0](A)값을 갖고 있다면,
int value = (int) map.get(data[i]);
// value에 map에서 data[0]인 value를 반환
map.put(data[i], value+1);
// map에 data[0](key) value(value)값에 1을 추가
} else {map.put(data[i], 1);}
// map이 data[0]이 없다면 map에 key-data[0] value-1추가
}
Iterator it = map.entrySet().iterator();
// Iterator: collection에 저장된 Element들을 읽어오는 방법을 표준화
// map.entrySet() : Set type
while(it.hasNext()) { // iteration이 읽어올 다음 요소가 있을 경우, true를 반환
Map.Entry entry = (Map.Entry) it.next(); // iteration의 다음 element를 읽어옴
int value = (int) entry.getValue(); // map에는 가용 method가 적으므로 map.entry 이용
System.out.println(entry.getKey()+": "
+printBar('*', value)+" "+value);
}
}
public static String printBar(char ch, int value) {
char[] bar = new char[value];
// bar에 길이가 value(4)인 char type 배열 생성
for(int i=0; i<bar.length; i++) {
bar[i] = ch;
} return new String(bar); // char[] -> String
}
}
|
list의 다양한 method()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
import java.util.*;
import static java.util.Collections.*;
public class Ex11_19 {
public static void main(String[] args) {
List list = new ArrayList();
System.out.println("list "+list);
addAll(list, 1,2,3,4,5);
// 원칙:Collections.addAll -> static을 import할 경우, class이름 생략 가능
System.out.println("addAll "+list);
rotate(list, 1);
// 맨뒤 -> 맨 앞으로 이동하면서 회전
System.out.println("rotate "+list);
swap(list, 0,2);
System.out.println("swap "+list);
shuffle(list);
System.out.println("shuffle "+list);
sort(list);
System.out.println("sort "+list);
sort(list, reverseOrder());
// 역순 정렬(reverse(list); 와 동일
System.out.println("reverseOrderSort "+list);
int idx = binarySearch(list, 3);
System.out.println("IDX of 3 is "+idx);
System.out.println("Max: "+max(list));
System.out.println("Min: "+min(list));
System.out.println("Min: "+max(list,reverseOrder()));
fill(list, 9);
System.out.println("fill "+list);
List newList = nCopies(list.size(),2);
// list와 같은 크기의 list를 생성하고, 2로 채움, 결과는 변경 불가
System.out.println("newList "+newList);
System.out.println("disjoint: "+disjoint(list, newList));
// 공통요소가 1개도 없으면 true
copy(list, newList); // newList에 있는 것을 list에 복사
System.out.println("newList "+newList);
System.out.println("list "+list);
replaceAll(list, 2, 1);
System.out.println("replaceAll "+list);
Enumeration e = enumeration(list);
// iterator와 동일
ArrayList list2 = list(e);
System.out.println("ArrayList "+list2);
}
}
|
소스 코드
참고 자료
'Java > Java' 카테고리의 다른 글
[자바의 정석_기초편] Chapter12. 제네릭스(Generics), 열거형(Enumeration), 애너테이션(Annotation)_1 (0) | 2023.07.25 |
---|---|
[자바의 정석_기초편] Chapter11. 컬렉션 프레임워크 (Collections framework)_2 (0) | 2023.06.03 |
[자바의 정석_기초편] Chapter11. 컬렉션 프레임워크 (Collections framework)_1 (1) | 2023.05.25 |
[자바의 정석_기초편] Chapter10. 날짜와 시간 & 형식화 (0) | 2023.05.20 |
[자바의 정석_기초편] Chapter09. java.lang package / Useful class_2 (0) | 2023.05.17 |