이름이 없는 클래스(객체)
반드시 인터페이스를 사용해서 생성(상속 관계 이용)
public class Ex76_Anonymous {
public static void main(String[] args) {
// 요구사항) 좌표를 저장할 객체 생성
// Case.1
// - 장점 : 간단
// - 단점 : 관리가 힘듬
int x1=100;
int y1=200;
// Case.2
// - 장점 : 집합
// - 단점 : 가독성 낮음
int[] p2=new int[2];
p2[0]=100;
p2[1]=200;
// Case.3
// - 장점 : 집합, 가독성 높음, 동일한 틀 사용으로 모든 좌표 객체의 성질과 사용법이 동일.
// - 단점 : 고비용
// - 가장 추천하는 방법
Point p3=new Point();
p3.x=100; // 어떻게 써야할지 모를 때 .찍으면 인텔리센스로 어떤 변수가 있는지 확인 가능하고,
p3.y=200; // 사용해본 경험이 있을 때 똑같이 사용 가능. 비유하자면 객관식!
// Case.4
// - 장점 : 클래스 사용과 동일한 효과
// - 단점 : 틀이 없음
// 동일한 구조를 가진 객체를 여러 개 만들어내야하면 클래스를 쓰고,
// 아니면 해시맵 사용하는 게 이득.
HashMap<String, Integer> p4=new HashMap<String, Integer>();
p4.put("x", 100); // p4의 규칙
p4.put("y", 200); // 규칙이 해시맵에 넣을 때 만들어지기 때문에 사용경험을 적용하기 어려움. 비유하자면 주관식!
// Case.5
// 익명 객체 사용
// - 데이터 저장용 객체(X)
// - 메서드 호출용 객체(O)
// AAA a=new AAA(); 불가능! 인터페이스니까.
BBB b=new BBB(); // 변수 앞에 붙은 타입을 보고 어떤 객체가 들어있구나하고 유추 가능.
AAA c=new BBB(); // 업캐스팅
// 위의 경우는 AAA라고 써있으니까 AAA가 들어있을거라고 생각.
// c에는 BBB클래스의 메서드 두 개가 있는데,
// 인텔리센스에서는 AAA라고 써있으니까 AAA에 있는 메서드 하나만 보여줌.
// 그럼에도 많이 쓰는 이유는 구조화를 위해서.
// 익명객체 스타일로 다시 만들기
AAA d=new AAA() { //The type new AAA(){} must implement the inherited abstract method AAA.test()
@Override
public void test() {
System.out.println("구현");
}
}; // 이 문법은 아래의 class BBB implements AAA...를 구현해놓은 것.
// 위의 예와 아래의 예를 비교해보면 확연하게 보인다.
// AAA d=class BBB implements AAA{ // 위의 예에서는 클래스 이름을 붙이지 않고(익명), AAA 이름을 빌려다쓴다.
//
// @Override
// public void test() {
// System.out.println("인터페이스를 구현한 객체의 test() 메서드");
//
// }
// }
d.test();
// 결론!!!
// 인터페이스 AAA클래스를 만들고, 상속받을 클래스를 만들어서 써도 되고,
// 아니면 만든 AAA클래스를 가져다가 쓰고, 클래스를 만들지 말고 구현부를 추가하여 (익명으로) 사용할 수 있다.
// 들어가는 비용은 비슷.
// 장점 : 익명으로 하는 건 클래스를 따로 만들지 않아도 됨!
// 단점 : 재사용이 불가능! 이름이 없으니까.
// 붕어빵먹자고 붕어빵 틀을 사올 수 없는 것처럼!
}
}
class Point{ // p3의 규칙
public int x;
public int y;
}
interface AAA{ // 구현부가 없어서 실행 불가 -> 인스턴스 생성 불가!
void test();
}
class BBB implements AAA{
@Override
public void test() {
System.out.println("인터페이스를 구현한 객체의 test() 메서드");
}
public void ouput() {
System.out.println("본인이 직접 구현한 output() 메서드");
}
}
public class Ex77_Anonymous {
public static void main(String[] args) {
// 익명 객체 활용 -> 컬렉션 정렬
ArrayList<Integer> nums=new ArrayList<Integer>();
nums.add(10);
nums.add(30);
nums.add(50);
nums.add(20);
nums.add(40);
System.out.println(nums);
Collections.sort(nums); // 컬렉션 정렬
System.out.println(nums);
Collections.reverse(nums);
System.out.println(nums);
ArrayList<String> names=new ArrayList<String>();
names.add("홍길동");
names.add("아무개");
names.add("이순신");
names.add("강호동");
names.add("유재석");
System.out.println(names);
Collections.sort(names);
System.out.println(names);
names.add("이훈");
names.add("김진");
names.add("남궁창민");
System.out.println(names); // 문자 코드값에 의한 오름차순
// 익명객체를 만들어서
// 글자수로 정렬해보자!
names.sort(new Comparator<String>(){
@Override
public int compare(String o1, String o2) {
// return o1.length()-o2.length(); // 단순히 글자수 비교라서 사전처럼 정렬 안됨
int result=o1.length()-o2.length();
if(result==0) { // 글자수가 같을 때 2차 정렬
result=o2.compareTo(o1); // 사전정렬의 역정렬
}
return result;
}
});
System.out.println(names);
ArrayList<Calendar> dates=new ArrayList<Calendar>();
Calendar c1 = Calendar.getInstance();
c1.set(2020, 10, 1);
dates.add(c1);
Calendar c2 = Calendar.getInstance();
c2.set(2020, 10, 25);
dates.add(c2);
Calendar c3 = Calendar.getInstance();
c3.set(2020, 10, 3);
dates.add(c3);
Calendar c4 = Calendar.getInstance();
c4.set(2020, 10, 19);
dates.add(c4);
Calendar c5 = Calendar.getInstance();
c5.set(2020, 10, 30);
dates.add(c5);
Collections.sort(dates);
// System.out.println(dates);
for(Calendar c:dates) {
System.out.printf("%tF %tA\n", c, c);
}
// 요일에 따라 정렬
dates.sort(new Comparator<Calendar>() {
@Override
public int compare(Calendar o1, Calendar o2) {
return o1.get(Calendar.DAY_OF_WEEK)-o2.get(Calendar.DAY_OF_WEEK);
}
});
for(Calendar c:dates) {
System.out.printf("%tF %tA\n", c, c);
}
ArrayList<Book> books = new ArrayList<Book>();
books.add(new Book("자바의 정석", 999, "프로그래밍"));
books.add(new Book("오라클 데이터베이스", 555, "데이터베이스"));
books.add(new Book("HTML5 기초", 345, "웹프로그래밍"));
books.add(new Book("CSS 디자인", 543, "웹프로그래밍"));
books.add(new Book("JavaScript 프로그래밍", 819, "웹프로그래밍"));
System.out.println(books);
// Collections.sort(books); // 객체들 자체를 정렬하지는 못함!
// System.out.println(books);
// JDK 구현된 정렬 기능
// 1. 있으면.. 사용(완제품)
// 2. 없으면.. 직접 구현
// 2-1. 모든걸 직접 구현(주문제작) - 지난번에 배운 버블정렬.
// 2-2. 틀을 제공+구현(반제품) - 오늘 배울 것.
// interface Comparator
// interface Comparable
// 1. interface Comparator 상속해서 정렬 -> 객체들을 비교하는 데에만 쓰기엔 고비용
// MyComparator mc=new MyComparator(); // Book끼리 비교하는 능력이 있음
// books.sort(mc);
// System.out.println(books); // 오름차순 정렬
// 2. interface Comparator를 익명객체로 만들어서 정렬 -> 일회용!
// 객체 정렬은 대부분 이렇게 한다!
// Comparator
// 정렬알고리즘 -> 퀵정렬 이용!
books.sort(new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
return o1.category.compareTo(o2.category);
}
});
System.out.println(books);
}
}
class MyComparator implements Comparator<Book>{ // interface Comparator를 MyComparator에 상속
@Override
public int compare(Book o1, Book o2) { // 반환값 int!
// 두 매개변수의 우위 비교(오름차순기준)
// 1. o1 크면 > 양수 반환
// 2. o2 크면 > 음수 반환
// 3. 같으면 > 0 반환
// if(o1.pages>o2.pages) {
// return 1;
// }else if (o1.pages<o2.pages) {
// return -1;
// }else {
// return 0;
// }
// if문 쓸 것도 없이 이렇게 가능!
// 페이지수 정렬
// return o1.pages-o2.pages;
// 제목 정렬
// return o1.title.compareTo(o2.title);
// 카테고리 정렬
return o1.category.compareTo(o2.category);
}
}
class Book {
public String title;
public int pages;
public String category;
public Book(String title, int pages, String category) {
this.title = title;
this.pages = pages;
this.category = category;
}
@Override
public String toString() {
return "{title=" + title + ", pages=" + pages + ", category=" + category + "}\n";
}
}
public static void main(String[] args) {
// 자바 컬렉션 인터페이스(*** 면접용 질문 준비할 것!!!)
// 1. Collection 인터페이스
// - List와 Set의 부모
// 2. List 인터페이스
// - ArrayList, Stack, LinkedList, Vector, Queue
// - 순서가 있는 집합 (*** 리스트를 한줄로 나타낼 때 이렇게 말하면 됨!)
// - 방번호(첨자)가 있다. -> 요소 접근!
// - 데이터 중복을 허용 (*****) -> 같은 데이터도 첨자를 이용해서 구분할 수 있음
// 3. Set 인터페이스
// - HashSet, TreeSet
// - 순서가 없는 집합 (*** 셋을 한줄로 나타낼 때 이렇게 말하면 됨!)
// - 방번호(첨자)가 없다.
// - 데이터 중복을 허용XXX (*****)
// 4. Map 인터페이스
// - HashMap, TreeMap, HashTable, Properties
// - 순서가 없는 집합(***)
// - 키와 값을 사용하는 컬렉션 -> 연관 배열, Dictionary구조
// - 키(key) : 식별자역할 -> 유일해야함!(중복XXX) -> Set으로 구성되어있음
// - 값(value) : 데이터역할(최종목적) -> 중복 허용 > List로 구성되어있음
// Vector, HashTable, Properties
// 사용안함. Legary Class. 예전 시스템의 호환성을 위해 남겨놓은 문법.
// 언젠가 버전업이 되면서 사라질 수도 있는 문법
// 되도록이면 쓰지 말 것! (있는거야 고쳐서 써야겠지만)
// Vector -> ArrayList로 대체.
// HashTable -> HashMap으로 대체.
// Properties -> 폐기 -> XML, JSON 기술로 대체.
// List 계열
// 1. Vector : 동기화 지원
// 2. ArrayList : 동기화 지원안함
// 동일하다고 생각하면 됨!
ArrayList<String> list1=new ArrayList<String>();
Vector<String> list2=new Vector<String>();
list1.add("홍길동");
list1.add("아무개");
list1.add("하하하");
list2.add("빨강");
list2.add("파랑");
list2.add("노랑");
System.out.println(list1.size());
System.out.println(list1.size());
System.out.println(list1.get(0));
System.out.println(list1.get(0));
}
// ArrayList, HashMap, LinkedList, Stack, HashSet : 연습 많이
// LinkedList
// - List 계열(List 인터페이스를 상속받았다는 것)
// -> ArrayList와 사용법 비슷 but 구현 내부는 서로 다름!
// LinkedList 종류
// 1. LinkedList
// 2. Double LinkedList
// 3. Double Circular LinkedList
// ArrayList vs LinkedList
// - 순서를 가지는 집합
// ArrayList 장점 : 마지막에 데이터를 삽입하는 경우 속도가 탁월하게 빠름!
// LinkedList 장점 : 중간에 데이터를 삽입하는 경우 속도가 탁월하게 빠름!
ArrayList<Integer> nums1=new ArrayList<Integer>();
LinkedList<Integer> nums2=new LinkedList<Integer>();
nums1.add(10);
nums1.add(20);
nums1.add(30);
nums2.add(10);
nums2.add(20);
nums2.add(30);
for(int i=0;i<nums1.size();i++) {
System.out.println(nums1.get(i));
}
for(int i=0;i<nums2.size();i++) {
System.out.println(nums2.get(i));
}
long begin=0, end=0; // 시간을 재기 위한 변수
// 1. 순차적으로 데이터 추가하기(Append)
System.out.println("1. 순차적으로 데이터 추가하기(Append)");
begin=System.nanoTime(); // 10의 -9승까지의 초도 가능
// 작업
for(int i=0;i<1000000;i++) {
nums1.add(i);
}
end=System.nanoTime();
System.out.printf("ArrayList 작업시간 : %,dns\n", end-begin);
begin=System.nanoTime(); // 10의 -9승까지의 초도 가능
// 작업
for(int i=0;i<1000000;i++) {
nums2.add(i);
}
end=System.nanoTime();
System.out.printf("LinkedList 작업시간 : %,dns\n", end-begin);
// 2. 배열 중간에 데이터 추가하기(Insert)
System.out.println("2. 배열 중간에 데이터 추가하기(Insert)");
begin=System.nanoTime(); // 10의 -9승까지의 초도 가능
// 작업
for(int i=0;i<100000;i++) {
nums1.add(0, i);
}
end=System.nanoTime();
System.out.printf("ArrayList 작업시간 : %,dns\n", end-begin);
begin=System.nanoTime(); // 10의 -9승까지의 초도 가능
// 작업
for(int i=0;i<100000;i++) {
nums2.add(0, i);
}
end=System.nanoTime();
System.out.printf("LinkedList 작업시간 : %,dns\n", end-begin);
// 3. 배열 중간에 데이터 삭제하기(Delete)
System.out.println("3. 배열 중간에 데이터 삭제하기(Delete)");
begin=System.nanoTime(); // 10의 -9승까지의 초도 가능
// 작업
for(int i=0;i<100000;i++) {
nums1.remove(0);
}
end=System.nanoTime();
System.out.printf("ArrayList 작업시간 : %,dns\n", end-begin);
begin=System.nanoTime(); // 10의 -9승까지의 초도 가능
// 작업
for(int i=0;i<100000;i++) {
nums2.remove(0);
}
end=System.nanoTime();
System.out.printf("LinkedList 작업시간 : %,dns\n", end-begin);
// 4. 순차적으로 데이터 삭제하기(Delete)
// 끝에서 처음으로 가면서 삭제
System.out.println("4. 순차적으로 데이터 삭제하기(Delete)");
begin=System.nanoTime(); // 10의 -9승까지의 초도 가능
// 작업
for(int i=nums1.size()-1;i>=0;i--) {
nums1.remove(i);
}
end=System.nanoTime();
System.out.printf("ArrayList 작업시간 : %,dns\n", end-begin);
begin=System.nanoTime(); // 10의 -9승까지의 초도 가능
// 작업
for(int i=nums2.size()-1;i>=0;i--) {
nums2.remove(i);
}
end=System.nanoTime();
System.out.printf("LinkedList 작업시간 : %,dns\n", end-begin);
// ArrayList
// - 순차적인 추가/제거 양호
// - 중간 추가/제거 불량
// - 한번 넣어두고 순차적으로 탐색하는 용도 -> 목록
// LinkedList
// - 순차적인 추가/제거 보통
// - 중간 추가/제거 양호
// - 집합의 요소를 수시로 넣었다뺐다 하는 용도