참조: https://marcus-biel.com/java-collections-framework/
http://hackersstudy.tistory.com/26
http://www.libqa.com/wiki/99
1. ArrayList (배열리스트)
1. 장점: 검색/조회 속도
n 번째 데이터에 대한 검색/조회 속도가 빠르다!
왜? 배열은 고정크기 연속된 메모리 공간에 있기 때문에 배열첨자연산 → 포인터 연산으로 매우 빠르게 n 번째 데이터 가져올 수 있다.2. 단점: 삽입, 삭제
배열이니까. length(데이터 개수) 범위 내에서 운용.
사용하지 않는 데이터에 대해서도 메모리에 차지하고 있다.
동적으로 데이터가 늘어나고 줄어드는 것이 힘들다.
→ 데이터 삭제, 삽입이 어렵고, 시간이 많이 걸린다.
가변적으로 길이 늘리고, 줄이는데 걸리는 비용… (시간)
삭제, 생성 의 어려움.
이유: 배열은 ‘연속된 메모리 공간’ 에 구축된 자료이니까.
[삭제예시]
[삽입예시]
2. LinkedList (배열리스트)
1. 장점 : 삽입, 삭제, 추가
2. 단점: 조회
[삭제예시]
[삽입예시]
package com.lec.java.collection01;
import java.util.ArrayList;
import java.util.Iterator;
/* ArrayList<E>
※계층도 숙지 중요
Collection<E>
|__ List<E>
|__ ArrayList<E>, LinkedList<E>
List 특징(ArrayList와 LinkedList의 공통점)
1. 중복 저장 허용
2. 저장 순서 유지 (인덱스 존재 > 인덱스로 접근 가능)
ArrayList: (배열로 만듦) > 실무에서 많이 쓰임
1. 저장 용량을 늘리는 데 많은 시간 소요 - 단점
2. 데이터를 삭제하는 데 많은 연산 - 단점
3. 데이터 참조 매우 빠름 - 장점
LinkedList:
1. 저장 용량을 늘리는 과정이 매우 간단 - 장점
2. 데이터를 삭제하는 과정이 간단 - 장점
3. 데이터 참조가 불편 - 단점
※ Vector<E> <-- ArrayList 와 비슷하나... ArrayList 추천.
※ 데이터 자료구조를 다룰시 각 자료구조에서 데이터에 대한 다음 동작들이 어떻게 되는지 주목하자
- C (Create) 생성
- R (Read) 조회
- U (Update) 수정
- D (Delete) 삭제
*/
public class Collection01Main {
public static void main(String[] args) {
System.out.println("ArrayList<E>");
// ArrayList 선언 - ArrayList 인스턴스 생성
ArrayList<Integer> list1 = new ArrayList<Integer>();
// 데이터 추가(저장): add(element) 메소드 사용
// add(index, element) -> index 번째 삽입
list1.add(100);
list1.add(400);
list1.add(500);
list1.add(200);
list1.add(2, 700); // 2번째 삽입
list1.add(2, 200); // 2번째 삽입 (같은값 중복저장 허용)
// 데이터 참조(읽기, 검색): get(index) 메소드 사용
// size(): ArrayList의 크기를 반환(리턴)
System.out.println("size(): " + list1.size());
for(int i = 0 ; i < list1.size(); i++) {
System.out.println(i + ":" + list1.get(i));
}
// System.out.println(list1.get(100)); // IndexOutOfBoundsException
// 데이터 삭제: remove(index) 메소드 사용
list1.remove(2);
System.out.println("삭제후");
for(int i = 0; i < list1.size(); i++) {
System.out.println(i + ":" + list1.get(i));
}
// 데이터 수정: set(index, element) 메소드 사용
list1.set(2, 333);
System.out.println("수정후");
for(int i = 0; i < list1.size(); i++) {
System.out.println(i + ":" + list1.get(i));
}
// ArrayList 출력 방법
// 1) for
// 2) Enhanced-for 사용
// 3) Iterator(반복자) 사용
// 4) forEach() 사용
System.out.println("Enhanced for를 사용한 출력");
// Enhanced for 사용 가능
for (Integer e : list1) {
System.out.println(e);
}
System.out.println("Iterator 를 사용한 출력"); // 데이터들을 순서대로 일렬로 줄세워서 하나하나씩 뽑아내기
// Iterator(반복자) 사용법
// iterator() 메소드를 사용해서 인스턴스 생성
Iterator<Integer> itr = list1.iterator();
// hasNext(): iterator가 다음 원소를 가지고 있는 지(true/false)
// next(): 현재 iterator 위치의 원소를 값을 리턴하고,
// iterator의 위치를 다음 원소의 위치로 변경
while(itr.hasNext()) {
System.out.println(itr.next());
}
System.out.println("forEach() 를 사용한 출력");
// forEach() + functional interface
// Java8 부터 등장
list1.forEach(System.out::println);
System.out.println("toString() 사용");
// Collection<> 대부분은 toString() 오버라이딩 되어 있다.
System.out.println(list1);
System.out.println("\n프로그램 종료");
} // end main
} // end class
[코드예시1]
package com.lec.java.collection02;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
public class Collection02Main {
public static void main(String[] args) {
System.out.println("ArrayList 연습");
//TODO:
// String 타입을 담는 ArrayList를 만들고
// 5개 이상의 String을 저장하고
// set(), remove() 등의 메소드 사용하여
// 임의의 것을 수정, 삭제도 해보시고
// 3가지 방식으로 출력해보세요
// for, Enhanced-for, Iterator
// String 타입을 저장할 수 있는 ArrayList 인스턴스 생성
ArrayList<String> list = new ArrayList<String>();
// 데이터 저장: add()
list.add("Java");
list.add("C++");
list.add("C#");
list.add("Python");
list.add("Swift");
Scanner sc = new Scanner(System.in);
System.out.println("5개 문자열을 입력해주세요");
for(int i = 0; i < 5; i++) {
list.add(sc.nextLine());
}
sc.close();
System.out.println("삽입(insertion) 도 add(i, 데이타) ");
list.add(2, "Python");
for(int i = 0; i < 5; i++) {
System.out.println(list.get(i));
}
// 데이터 검색: get(), size()
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 데이터 삭제: remove()
list.remove(1);
System.out.println("삭제:");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 데이터 수정: set()
list.set(2, "Object-C");
System.out.println("수정:");
// enhanced for
for (String lang : list) {
System.out.println(lang);
}
System.out.println("for 를 사용한 출력");
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("Enhanced-for 를 사용한 출력");
for(String i : list) {
System.out.println(i);
}
// Iterator 사용
// ArrayList에 있는 iterator() 메소드를 사용해서 인스턴스 생성
System.out.println("Iterator 사용: ");
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
[코드예시1]
package com.lec.java.collection03;
import java.util.ArrayList;
public class Collection03Main {
public static void main(String[] args) {
System.out.println("ArrayList 연습");
//TODO:
// Student 타입을 담는 ArrayList를 만드고
// 사용자로부터 3개의 Student 데이터 을 입력받아서
// 3가지 방법으로 출력해보세요.
// for, Enhanced-for, Iterator
ArrayList<Student> list = new ArrayList<Student>();
Score score1 = new Score(100, 90, 80);
Student stu1 = new Student(1, "김남주", score1);
list.add(stu1);
Score score2 = new Score(80, 100, 90);
Student stu2 = new Student(2, "김동혁", score2);
list.add(stu2);
Student stu3 = new Student(3, "김병기", new Score(80, 73, 36));
list.add(stu3);
for(Student s : list) {
System.out.println(s);
}
// 김동혁 학생의 정보 수정 (김동혁 학생이 List의 몇번째 저장되었는지 모른다고 하면?)
// id 값 -> 10
// 국어, 영어, 수학 -> 99, 88, 76
for(int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
if("김동혁".equals(stu.getName())) {
stu.setId(10);
stu.getScore().setKorean(99);
stu.getScore().setEnglish(88);
stu.getScore().setMath(76);
}
}
// 수정후 출력
System.out.println("수정후");
for(Student s : list) {
System.out.println(s);
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
package com.lec.java.collection03;
public class Student {
private int id;
private String name;
private Score score;
public Student() {}
public Student(int id, String name, Score s) {
this.id = id;
this.name = name;
this.score = s;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Score getScore() {
return score;
}
public void setScore(Score score) {
this.score = score;
}
// com.lec.java.colleciton07 이후
@Override
public String toString() {
String str = "";
str += "id:" + id + "\n";
str += "name:" + name + "\n";;
str += "국어:" + score.getKorean() + "\n";
str += "영어:" + score.getEnglish() + "\n";
str += "수학:" + score.getMath() + "\n";
return str;
}
public static void printTotal(Student stu){
System.out.println("id:" + stu.getId());
System.out.println("이름:" + stu.getName());
System.out.println("총점:" + (stu.getScore().getEnglish() + stu.getScore().getKorean() + stu.getScore().getMath()));
}
} // end class Student
package com.lec.java.collection03;
public class Score {
private int korean;
private int english;
private int math;
public Score() {}
public Score(int kor, int eng, int math) {
this.korean = kor;
this.english = eng;
this.math = math;
}
public int getKorean() {
return korean;
}
public void setKorean(int korean) {
this.korean = korean;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
} // end class Score
package com.lec.java.collection06;
import java.util.HashSet;
import java.util.Iterator;
/* Set, HashSet<E>
Collection<E>
|__ Set<E>
|__ HashSet<E>, TreeSet<E>
Set:
1. 자료의 중복 저장이 허용되지 않는다. (hashCode() 값의 중복여부!)
2. 저장 순서가 유지되지 않는다.(인덱스 없다.)
(예) {1, 2, 3} = {1, 1, 2, 2, 3} : 중복 저장이 안되기 때문에 같은 Set
(예) {1, 2, 3} = {1, 3, 2}: 저장 순서가 중요하지 않기 때문에 같은 Set
HashSet: 매우 빠른 검색 속도를 제공, TreeSet: 정렬에 특화
(※ HashXXX ← '검색속도 향상'을 쓰는 자료구조 입니다)
*/
public class Collection06Main {
public static void main(String[] args) {
System.out.println("HashSet 클래스");
// Integer 타입을 저장할 수 있는 HashSet 인스턴스 생성
HashSet<Integer> set = new HashSet<Integer>();
// 데이터 저장: add()
set.add(100);
set.add(200);
set.add(300);
set.add(100);
set.add(400);
set.add(500);
set.add(1);
set.add(2);
// HashSet의 크기: size()
System.out.println("Set의 크기: " + set.size());
// Set은 중복 저장을 허용하지 않는다.
// 데이터 검색:
// Set은 인덱스가 없기 때문에 get() 메소드를 제공하지 않습니다. > get은 index를 사용하기 때문
// 데이터 검색을 위해서는 Iterator를 사용해야 함
System.out.println();
Iterator<Integer> itr = set.iterator();
while(itr.hasNext()) {
System.out.println(itr.next());
}
// ↑ 출력결과를 통해 Set 은 저장된 순서가 유지안됨을 알 수 있다.
// 데이터 삭제
// remove(element): Set에 있는 element를 찾아서 삭제
// element 있다면 삭제 후 true를 리턴
// element 없다면 false 리턴
// TODO
System.out.println();
System.out.println("삭제 후: ");
System.out.println("삭제결과: " + set.remove(2)); // index 2번째를 삭제하는게 아니다!. 데이터 2 를 삭제하는 것이다!
System.out.println("삭제결과: " + set.remove(2));
itr = set.iterator(); // 한 번 사용한 iterator는 다시 사용할 수 없다. (새로 생성해야 한다)
while(itr.hasNext()) {
System.out.println(itr.next());
}
// Set 자료형 데이터 변경을 할 수 있는 set() 메소드를 제공하지 않습니다.
// 삭제(remove) 후 추가(add)하면 변경하는 효과
// TODO : 500 -> 555 로 변경하고 싶다면?
set.remove(500);
set.add(555);
System.out.println("변경후");
itr = set.iterator();
while(itr.hasNext()) {
System.out.println(itr.next());
}
// enhanced-for 사용
System.out.println();
System.out.println("Enhanced for 사용 출력");
for(Integer x : set) {
System.out.println(x);
}
// forEach() 메소드 사용
System.out.println();
System.out.println("forEach() 사용 출력");
// TODO
// toString() 제공됨
System.out.println();
System.out.println(set);
System.out.println("\n프로그램 종료");
} // end main()
} // end class
[코드예시]
package com.lec.java.collection07;
import java.util.HashSet;
import java.util.Iterator;
public class Collection07Main {
public static void main(String[] args) {
System.out.println("HashSet 연습");
// TODO
// String 타입을 저장할 수 있는 HashSet 를 생성하고
// 5개 이상의 데이터는 저장, 수정, 삭제 등의 동작을 해보고,
// iterator, enhanced-for 문을 사용해서 출력해보기
HashSet<String> set = new HashSet<String>();
// 데이터 저장
System.out.println("add 결과: " + set.add("One"));
System.out.println("add 결과: " + set.add("Two"));
System.out.println("add 결과: " + set.add("Three"));
System.out.println("add 결과: " + set.add("Four"));
System.out.println("add 결과: " + set.add("Five"));
System.out.println("add 결과: " + set.add("Two"));
System.out.println("add 결과: " + set.add("Three"));
System.out.println();
System.out.println("데이터 저장");
System.out.println("데이터 개수: " + set.size());
System.out.println();
// 데이터 검색 - Iterator 사용
Iterator<String> itr = set.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
System.out.println();
// 데이터 삭제
set.remove("Five");
System.out.println("삭제 후:");
itr = set.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
System.out.println();
// enhanced for는 인덱스가 필요 없는 for문이기 때문에
// Set 타입의 자료형에서도 사용 가능
System.out.println("enhanced for 사용");
for (String str : set) {
System.out.println(str);
}
System.out.println("\n프로그램 종료");
} // end main()
} // end class
package com.lec.java.collection09;
import java.util.Iterator;
import java.util.TreeSet;
/* TreeSet
Collection<E>
|__ Set<E>
|__ HashSet<E>, TreeSet<E>
TreeSet: 데이터가 정렬된 상태로 저장(오름차순, 내림차순)
(※ TreeXXX ← 주로 '정렬'에 특화된 자료구조 입니다)
*/
public class Collection09Main {
public static void main(String[] args) {
System.out.println("TreeSet 클래스");
// Integer 타입을 저장할 수 있는 TreeSet 인스턴스 생성
TreeSet<Integer> tset = new TreeSet<Integer>();
// 데이터 저장 : add()
tset.add(11);
tset.add(2);
tset.add(14);
tset.add(1);
tset.add(7);
tset.add(15);
tset.add(5);
tset.add(8);
// 데이터 검색 - Iterator 사용
// TreeSet인 경우에 iterator() 메소드 오름차순 정렬
System.out.println("오름차순:");
Iterator<Integer> itr = tset.iterator();
while(itr.hasNext()) {
System.out.println(itr.next());
}
System.out.println();
System.out.println("내림차순:");
// 내림차순 Iterator : descendingIterator() 사용
itr = tset.descendingIterator();
while(itr.hasNext()) {
System.out.println(itr.next());
}
// enhanced for
System.out.println();
System.out.println("enhanced for");
for(Integer num: tset) {
System.out.println(num);
}
// 삭제 등의 동작은 HashSet 과 동일.
System.out.println("\n프로그램 종료");
} // end main()
} // end class
[코드예시]
package com.lec.java.collection10;
import java.util.Iterator;
import java.util.TreeSet;
public class Collection10Main {
public static void main(String[] args) {
System.out.println("TreeSet 연습");
// String 타입을 저장할 수 있는 TreeSet 인스턴스 생성
// 5개 이상의 데이터를 저장해보고
// 오름차순, 내림차순으로 출력해보기
TreeSet<String> tset = new TreeSet<String>();
// 데이터 저장
tset.add("qwerty");
tset.add("asdf");
tset.add("zxcv");
tset.add("bnm");
tset.add("jkl");
tset.add("AaAa 1"); // 1.
tset.add("aaaa 2"); // 2.
tset.add("aAaA 3"); // 3.
tset.add("AAaa 4"); // 4.
tset.add("aaAA 5"); // 5.
// 오름 차순 결과 4 1 3 5 2
// 데이터 검색 - Iterator(오름차순, 내림차순)
Iterator<String> itr = tset.iterator();
System.out.println("오름차순:");
while (itr.hasNext()) {
System.out.println(itr.next());
}
System.out.println();
System.out.println("내림차순:");
Iterator<String> itr2 = tset.descendingIterator();
while (itr2.hasNext()) {
System.out.println(itr2.next());
}
System.out.println("\n프로그램 종료");
} // end main
} // end class
package com.lec.java.collection11;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/* Map<K, V>, HashMap<K, V>
Collection<E>
|__ List<E>, Set<E>
List<E>
|__ ArrayList<E>, LinkedList<E>
Set<E>
|__ HashSet<E>, TreeSet<E>
Map<K, V>
|__ HashMap<K, V> (검색특화) , TreeMap<K, V> (정렬특화)
Map: key-value 저장 방식의 자료 구조
1. key는 중복되지 않는 값만 허용
2. value는 같더라도 key 값이 다르면 저장 가능
3. 검색, 수정, 삭제를 할 때 key를 사용
*/
public class Collection11Main {
public static void main(String[] args) {
System.out.println("HashMap 클래스");
// HashMap 인스턴스 생성
// Key - Integer 타입
// Value - String 타입
HashMap<Integer, String> hmap =
new HashMap<Integer, String>();
// 데이터 저장: put() 메소드 사용
System.out.println("put 결과" + hmap.put(1, "최진형")); // 생성
System.out.println("put 결과" + hmap.put(2, "최민영"));
System.out.println("put 결과" + hmap.put(3, "정은선"));
System.out.println("put 결과" + hmap.put(1, "조은이")); // 수정
// 기존에 없던 key 값으로 put 하면 null 리턴하고
// 같은 키 값으로 데이터를 put하게 되면, 기존 값이 수정(replace)되고 기존 값을 리턴함
// 저장된 데이터 개수 확인 : size()
System.out.println("데이터 개수: " + hmap.size());
System.out.println();
// 데이터 읽기
// get(key) 사용해서 value 읽기
System.out.println(hmap.get(1)); // 조회
System.out.println(hmap.get(2));
System.out.println(hmap.get(3));
// 데이터 삭제
// remove(key) : 삭제된 value 리턴
// 없는 key 를 삭제하면 null 리턴
System.out.println("삭졔: " + hmap.remove(2));
System.out.println("삭졔: " + hmap.remove(2));
// 방법1 HashMap에서 Iterator 사용
// 1. HashMap의 keySet() 메소드를 사용해서
// 저장된 키(key)값들만 이루어진 Set을 만듬.
// 2. 1에서 만들어진 Set에 있는 iterator() 메소드를 사용해서
// Iterator를 생성
System.out.println();
Set<Integer> keySet = hmap.keySet();
Iterator<Integer> itr = keySet.iterator();
while(itr.hasNext()) {
int key = itr.next();
System.out.println(key + " : " + hmap.get(key));
}
System.out.println();
// 방법2 : Map.Entry 사용
// entrySet() 은 Set<Entry<Integer, String>> 리턴함
for(Map.Entry<Integer, String> m : hmap.entrySet()) {
System.out.println(m.getKey() + " : " + m.getValue());
}
// 방법3 : toString()
System.out.println(hmap);
System.out.println();
// 도전과제
// arr[] = {2, 4, 5, 4, 3, 3, 4}
// 주어진 배열이 위와 같을때 다음과 같이 발생회수 나타내기
// 2 : 1개
// 3 : 2개
// 4 : 3개
// 5 : 1개
System.out.println("HashMap 응용: 배열에서 발생빈도 구하기");
int arr[] = {11, 12, 2, 4, 5, 4, 3, 3, 4, 3, 3, 3, 9, 9, 9, 11, 12, 12, 12};
printFreq(arr);
System.out.println("\n프로그램 종료");
} // end main()
static void printFreq(int[] arr) {
// TODO Auto-generated method stub
/*
* 첫등장이면 -> 개수 1번 -> put (숫자, 1)
* 두번째부터 등장 -> 기존개수 +1 -> put (숫자, 기존값 + 1)
*/
// 발생빈도 담을 Map 준비
// key : 등장 숫자
// value : 등장 횟수
Map<Integer, Integer> hmap = new HashMap<Integer, Integer>();
// 발생빈도 작성
for (int i = 0; i < arr.length; i++) {
Integer v = hmap.get(arr[i]); // get() 의 결과값은 등장 횟수, 없으면 null 리턴
if(v == null) { // 첫등장이면 -> 개수 1번 -> put (숫자, 1)
hmap.put(arr[i], 1);
} else {
hmap.put(arr[i], v + 1); // 두번째부터 등장 -> 기존개수 +1 -> put (숫자, 기존값 + 1)
}
} // end for
// 결과 출력.
for(Map.Entry<Integer, Integer> e: hmap.entrySet()) {
System.out.println(e.getKey() + " : " + e.getValue() + "개");
}
}
// TODO
} // end class
package com.lec.java.collection12;
import java.util.HashMap;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeMap;
// Hash: 검색을 빠르게 하기 위한 용도
// Tree: 데이터 정렬을 하기 위한 용도
public class Collection12Main {
public static void main(String[] args) {
System.out.println("TreeMap 클래스");
// TreeMap<Integer, String> 타입 인스턴스 생성
TreeMap<Integer, String> tmap = new TreeMap<Integer, String>();
// 데이터 저장: put(key, value) 메소드 사용
tmap.put(1, "aaa");
tmap.put(3, "asdf");
tmap.put(4, "zxcv");
tmap.put(2, "qwertt");
// values() : value 들로 이루어진 Collection 리턴
System.out.println("values()");
for(String value : tmap.values()) {
System.out.println(value);
}
// ↑ value 에 대해 정렬된건 아니라는 사실을 알 수 있다.
// 데이터 검색: get(key) 메소드를 사용
// 1. 키값들로만 이루어진 Set을 만듬
Set<Integer> kset = tmap.keySet();
// 2. keySet을 가지고 iterator를 만듬
Iterator<Integer> itr = kset.iterator();
while(itr.hasNext()) {
int key = itr.next();
System.out.println(key + " : " + tmap.get(key));
}
// ↑ key 에 대해서 정렬되어 있다!
System.out.println();
// key 역순 출력
// TreeMap에만 있는 KeySet을 만들어 내는 메소드
NavigableSet<Integer> navi = tmap.navigableKeySet();
Iterator<Integer> itr2 = navi.descendingIterator();
while(itr2.hasNext()) {
int key = itr2.next();
System.out.println(key + " : " + tmap.get(key));
}
// HashMap --> TreeMap 전환하기
System.out.println("HashMap() -> TreeMap() ");
HashMap<String, Integer> hmap = new HashMap<String, Integer>();
hmap.put("이순신", 50000);
hmap.put("강감찬", 70000);
hmap.put("최영", 20000);
System.out.println(hmap);
TreeMap<String, Integer> tmap2 = new TreeMap<String, Integer>(hmap);
System.out.println(tmap2);
System.out.println("\n프로그램 종료");
} // end main()
} // end class
java.util.Collections 클래스
- Collections 클래스는 여러 유용한 알고리즘을 구현한 메소드들을 제공
- 대부분 클래스메소드 (static) 형태로 제공됨
정렬(sort)
섞기(shuffle)
탐색(search)
package com.lec.java.collection14;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class Collection14Main {
public static void main(String[] args) throws ParseException {
System.out.println("Collections 메소드");
List<String> list1 = new LinkedList<String>();
list1.add("장길산");
list1.add("김철수");
list1.add("구자철");
System.out.println(list1);
System.out.println("sort()");
// sort()
// 기본적으로 속도가 비교적 빠르고 안전성이 보장되는 Merge Sort 사용
Collections.sort(list1);
System.out.println(list1);
// String 타입이면 알파벳 순으로 정렬된다.
// Date, Calendar, java.time.* 타입이면 날짜/시간순으로 정렬된다
// ↑ 이들은 기본적으로 Comparable<T> 인터페이스가 구현되었기 때문.
// ※ String 온라인 도움말 확인해보자
System.out.println();
List<LocalDate> list2 = new LinkedList<LocalDate>();
list2.add(LocalDate.parse("2018-08-16"));
list2.add(LocalDate.parse("2017-05-21"));
list2.add(LocalDate.parse("2022-02-09"));
System.out.println(list2);
Collections.sort(list2);
System.out.println(list2);
System.out.println();
List<Student> list3 = new ArrayList<Student>();
list3.add(new Student("Susie", 50));
list3.add(new Student("James", 80));
list3.add(new Student("Kevin", 30));
System.out.println(list3);
System.out.println("Comparable 구현, sort() 적용");
Collections.sort(list3); // Student 는 Comparable<> 이 구현안되어 있으므로 에러난다.
System.out.println(list3);
// 역순 정렬
System.out.println("reverseOrder() 적용");
Collections.sort(list3, Collections.reverseOrder());
System.out.println(list3);
System.out.println("reverse() 적용"); // 뒤집기
Collections.reverse(list3);
System.out.println(list3);
// Comparator<> 적용
// Collections.sort 메소드는 두 번째 인자로 Comparator 인터페이스를 받을 수 있도록 해놓았습니다.
// Comparator 인터페이스의 compare 메소드를 오버라이드 하면 됩니다.
System.out.println("Comparator<> 적용");
Collections.sort(list3); // 기본 정렬 동작은 Comparable
Collections.sort(list3, new Asc()); // Acs . 이름 오름차순
System.out.println("Asc적용" + list3);
Collections.sort(list3, new Desc()); // Desc . 이름 내림차순
System.out.println("Desc적용" + list3);
// Collections 에서 많이 쓰이는 인터페이스임
// Comparable<> 은 클래스 자체에 구현하는 인터페이스 compareTo(자기사진 vs 매개변수)
// Comparator<> 는 두개의 객체 비교하는 기능제공 인터페이스 compare(매개변수1 vs 매개변수2)
// 구현된 객체가 매개변수 등에 넘겨지는 형태로 많이 쓰임
// Shuffling 하기 (섞기)
System.out.println();
System.out.println("shuffle()");
Collections.shuffle(list1);
System.out.println(list1);
Collections.shuffle(list1);
System.out.println(list1);
// 배열에서 랜덤으로 3명만 뽑기
String [] arr = {"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg"};
// 배열 -> List<>
List<String> arrList = Arrays.asList(arr);
Collections.shuffle(arrList);
arrList = arrList.subList(0, 3); // index 0 부터 3 전까지의 List<> 생성
System.out.println(arrList);
// min(), max()
// Comparable 메소드 영향 받음
System.out.println();
System.out.println("min(), max()");
System.out.println("min():" + Collections.min(list3));
System.out.println("max():" + Collections.max(list3));
// copy()
System.out.println();
List<Student> list4 = new ArrayList<Student>();
list4.add(new Student("aaa", 10));
list4.add(new Student("bbb", 10));
list4.add(new Student("ccc", 10));
System.out.println("copy()전: " + list4);
Collections.copy(list4, list3);
System.out.println("copy()후: " + list4);
// System.out.println(list4); // Source does not fit in dest
System.out.println("\n프로그램 종료");
} // end main
} // end class
// 우선은 Comparable 구현 없이 해보자
class Student implements Comparable<Student>{
String name;
double point;
public Student(String name, double point) {
super();
this.name = name;
this.point = point;
}
@Override
public String toString() {
return this.name + ":" + this.point + "점";
}
//comparaTo() 메소드는 매개변수 객체를 현재의 객체와 비교하여
// 정렬순위가 낮으면 음수, 같으면 0, 높으면 양수를 반환한다.
@Override
public int compareTo(Student o) {
// 점수(point) 오름차순
if(o.point > this.point) return -1;
if(this.point > o.point) return 1;
return 0;
// 점수(point) 내림차순
// if(o.point < this.point) return -1;
// if(this.point < o.point) return 1;
// return 0;
// // 이름(name) 오름차순
// return this.name.compareTo(o.name);
// 이름(name) 내림차순
// return -this.name.compareTo(o.name);
}
// TODO
} // end class
class Asc implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
// 이름(name) 오름차순
return o1.name.compareTo(o2.name);
}
// TODO
} // end Asc
class Desc implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
// 이름(name) 내림차순
return -o1.name.compareTo(o2.name);
}
// TODO
} // end Desc