package com.greedy.section02.userexception.exception;
public class MoneyNegativeException extends NegativeException {
public MoneyNegativeException() {}
public MoneyNegativeException(String message) {
super(message);
}
}
package com.greedy.section02.userexception.exception;
public class NegativeException extends Exception {
public NegativeException() {}
public NegativeException(String message) {
super(message);
}
}
package com.greedy.section02.userexception.exception;
public class NotEnoughMoneyException extends Exception {
public NotEnoughMoneyException() {}
public NotEnoughMoneyException(String message) {
super(message);
}
}
package com.greedy.section02.userexception.exception;
public class PriceNegativeException extends NegativeException {
public PriceNegativeException() {}
public PriceNegativeException(String message) {
super(message);
}
}
package com.greedy.section03.uses;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Application1 {
public static void main(String[] args) {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("test.dat"));
String s;
while((s = in.readLine()) != null) {
System.out.println(s);
}
/* FileNotFoundException과 EOFException을 동시에 처리할 수 있다.
* 같은 레벨의 자손을 한번에 처리할 수도 있는것이다.
* */
} catch (FileNotFoundException | EOFException e) {
e.printStackTrace();
} catch (IOException e) {
/* catch블럭은 여러개를 작성할 시 상위 타입이 하단에 오고 후손 타입이 먼저 작성되어야 한다.*/
e.printStackTrace();
} finally {
try {
if(in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
java.io.FileNotFoundException: test.dat (지정된 파일을 찾을 수 없습니다)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:216)
at java.base/java.io.FileInputStream.(FileInputStream.java:157)
at java.base/java.io.FileInputStream.(FileInputStream.java:111)
at java.base/java.io.FileReader.(FileReader.java:60)
at com.greedy.section03.uses.Application1.main(Application1.java:17)
ackage com.greedy.section03.uses;
import java.awt.image.ImagingOpException;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Application2 {
public static void main(String[] args) {
/* try-with-resource
*
* JDK 1.7에서 추가된 문법이다.
*
* close해야 하는 인스턴스의 경우 try옆에 괄호안에서 생성하면
* 해당 try-catch블럭이 완료될 때 자동으로 close처리 해준다.
* */
try(BufferedReader in = new BufferedReader(new FileReader("test.dat"));){
String s;
while((s = in.readLine()) != null) {
System.out.println(s);
}
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
컬렉션
자료구조 데이터(자료)를 메모리에서 효율적으로 저장하기 위한 방법론
List 자료들을 순차적으로 나열한 자료구조로 인덱스로 관리됨
중복해서 인스턴스 저장이 가능
기본자료형은 (정수) object타입에 들어가지 않는다.
package com.greedy.section01.list.run;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Application1 {
public static void main(String[] args) {
/* 컬렉션 프레임워크(Collection Framework)
* 자바에서 컬렉션 프레임워크는 여러 개의 다양한 데이터를 쉽고 효과적으로 처리할 수 있도록
* 표준화된 방법을 제공하는 클래스들의 집합이다.
* -> 데이터를 효율적으로 저장하는 자료구조와 데이터를 처리하는 알고리즘을 미리 구현해놓은 클래스이다.
* */
/*
* Collection Framework는 크게 3가지 인터페이스 중 한가지를 상속받아 구현해놓았다.
* 1. List 인터페이스
* 2. Set 인터페이스
* 3. Map 인터페이스
*
* List 인터페이스와 Set 인터페이스의 공통부분을 Collection 인터페이스에서 정의하고 있다.
* 하지만 Map은 구조상의 차이로 Collection 인터페이스에서 정의하고 있지 않다.
* */
/* List계열
* List 인터페이스를 구현 모든 클래스는 요소의 저장 순서가 유지되며, 중복 저장을 허용한다.
* ArrayList, LinkedList, Vector, Stack 등이 있다.
* */
/* ArrayList
* 가장 많이 사용되는 컬렉션 클래스이다.
* JDK 1.2부터 제공된다.
* 내부적으로 배열을 이용하여 요소를 관리하며, 인덱스를 이용해 배열 요소에 빠르게 접근할 수 있다.
* */
/* ArrayList는 인스턴스를 생성하게 되면 내부적으로 10칸짜리 배열을 생성해서 관리한다.*/
ArrayList alist = new ArrayList();
/* 다형성을 적용하여 상위 레퍼런스로 ArrayList 객체를 만들수도 있다.
*
* List 인터페이스 하위의 다양한 구현체들로 타입 변경이 가능하기 때문에
* 레퍼런스 타입은 List로 해두는 것이 더 유연한 코드를 작성하는 것이다.
* */
List list = new ArrayList();
Collection clist = new ArrayList();
/* ArrayList는 저장순서가 유지되며 index(순번)이 적용된다.
* */
alist.add("apple");
alist.add(123); // autoBoxing 처리됨(값-> 객체)
alist.add(45.78);
alist.add(new Date());
/* toStrig() 오버라이딩되어있다. */
System.out.println("alsit : " + alist.toString());
/* ArrayList의 크기는 size()메소드로 확인할 수 있다.
* 단, size()메소드는 배열의 크기가 아닌 요소의 갯수를 반환한다.
* -> 내부적으로 관리되는 배열의 사이즈는 외부에서 알 필요가 없기 때문에 기능을 제공하지 않는다.
* */
System.out.println("alist의 size : " + alist.size());
for(int i = 0; i < alist.size(); i++) {
/* 인덱스에 해당하는 값을 가져올 때는 get() 메소드를 사용한다. */
System.out.println(i + " : " + alist.get(i));
}
/* 데이터의 중복 저장을 허용한다.
* 배열과 같이 인덱스로 요소들을 관리하기 때문에 인덱스가 다른 위치에 동일한 값을 저장하는 것이 가능하다.
* */
alist.add("apple");
System.out.println("alist : " + alist);
/* 원하는 인덱스 위치에 값을 추가할 수도 있다.
* 값을 중간에 추가하는 경우 인덱스 위치에 덮어쓰는 것이 아니고
* 새로운 값이 들어가는 인덱스 위치에 값을 넣고 이후 인덱스는 하나씩 뒤로 밀리게된다.
* */
alist.add(1, "banana");
System.out.println("alist : " + alist);
/* 저장된 값을 삭제할 때는 remove() 메소드를 사용한다.
*
* 중간 인덱스의 값을 삭제하는 경우 자동으로 인덱스를 하나씩 앞으로 당긴다.
* */
alist.remove(2);
System.out.println("alist : " + alist);
/* 지정된 위치의 값을 수정할 때 인덱스를 활용할 수 있다. */
alist.set(1, new Boolean(true));
System.out.println("alist : " + alist);
List<String> stringList = new ArrayList<>();
// stringList.add(123); // 제네릭 타입으로 지정하면 지정한 타입 외의 인스턴스는 저장하지 못한다.
stringList.add("banana");
stringList.add("orange");
stringList.add("mago");
stringList.add("grape");
System.out.println("stringList : " + stringList);
/*
* 저장 순서를 유지하고 있는 stringList를 오름차순 정렬
* Collection 인터페이스가 아닌 Collections 클래스이다.
* --> Collection에서 사용되는 기능을 static 메소드로 구현한 클래스이며
* 인터페이스명 뒤에 s가 붙은 클래스들은 관례상 비슷한 방식으로 작성된 클래스를 의미하게된다.
* */
Collections.sort(stringList);
System.out.println("stringList : " + stringList);
/* 조금 복잡하지만 내림차순 정렬을 할 수 있다.
*
* 하지만 ArrayList에는 역순으로 정렬하는 기능이 제공되지 않는다.
*
* 역순 정렬 기능은 LinkedList에 정의되어 있는 현재 사용하는 ArrayList를
* LinkedList로 변경할 수 있다.
* */
stringList = new LinkedList<>(stringList);
/* Iterator반복자 인터페이스를 활용해서 역순으로 정렬한다.
* LinkedList타입으로 형변환 한 후 descendingIterator() 메소드를 사용하면
* 내림차순으로 정렬된 Iterator 타입의 목록으로 반환을 해준다.
* 제네릭을 적용하는 것이 좋다.
*
* Iterator란?
* Collection 인터페이스의 iterator() 메소드를 이용해서 인스턴스를 생성할 수 있다.
* 컬렉션에서 값을 읽어오는 방식을 통일된 방식으로 제공하기 위해 사용한다.
*
* -> 인덱스로 관리되는 컬렉션이 아닌 경우에는 반복문을 사용해서 요소에 하나씩 접근할 수 없기 때문에
* 인덱스를 사용하지 않고도 반복문을 사용하기 위한 목록을 만들어주는 역할이라고 보면된다.
*
* hashNext() : 다음 요소를 가지고 있는 true, 더 이상 요소가 없는 경우 false를 반환
* next() : 다음 요소를 반환
* */
Iterator<String> dIter = ((LinkedList<String>) stringList).descendingIterator(); //현재 list 타입
/* 한번 next()로 값을 꺼내면 다시 쓸 수 없다. */
// while(dIter.hasNext()) {
//
//
// System.out.println(dIter.next());
// }
// while(dIter.hasNext()) {
//
//
// System.out.println(dIter.next());
// }
/* 역순으로 정렬된 결과를 저장하기 위해 새로운 ArrayList를 생성 및 저장 */
List<String> descList = new ArrayList<>();
while(dIter.hasNext()) {
descList.add(dIter.next());
}
System.out.println("descList : " + descList);
}
}
alsit : [apple, 123, 45.78, Wed Oct 26 14:45:28 KST 2022]
alist의 size : 4
0 : apple
1 : 123
2 : 45.78
3 : Wed Oct 26 14:45:28 KST 2022
alist : [apple, 123, 45.78, Wed Oct 26 14:45:28 KST 2022, apple]
alist : [apple, banana, 123, 45.78, Wed Oct 26 14:45:28 KST 2022, apple]
alist : [apple, banana, 45.78, Wed Oct 26 14:45:28 KST 2022, apple]
alist : [apple, true, 45.78, Wed Oct 26 14:45:28 KST 2022, apple]
stringList : [banana, orange, mago, grape]
stringList : [banana, grape, mago, orange]
descList : [orange, mago, grape, banana]
package com.greedy.section01.list.dto;
public class BookDTO {
/* 도서 정보를 저장*/
private int number;
private String title;
private String author;
private int price;
public BookDTO() {
}
public BookDTO(int number, String title, String author, int price) {
super();
this.number = number;
this.title = title;
this.author = author;
this.price = price;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "BookDTO [number=" + number
+ ", title=" + title
+ ", author=" + author
+ ", price=" + price + "]";
}
}
package com.greedy.section01.list.run;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.greedy.section01.list.comparator.AscendingPrice;
import com.greedy.section01.list.dto.BookDTO;
public class Application2 {
public static void main(String[] args) {
List<BookDTO> bookList = new ArrayList<>();
// System.out.println(bookList);
// System.out.println(bookList.get(0).getPrice());
/* 도서 정보 추가*/
bookList.add(new BookDTO(1, "홍길동전", "허균", 50000));
bookList.add(new BookDTO(2, "목민심서", "정약용", 30000));
bookList.add(new BookDTO(3, "동의보감", "허준", 40000));
bookList.add(new BookDTO(4, "삼국사기", "김부식", 46000));
bookList.add(new BookDTO(5, "삼국유사", "일연", 58000));
for(BookDTO book: bookList) {
System.out.println(book);
}
/* 제네릭의 타입 제한에 의해 Comparable 타입을 가지고 있는 경우에만 sort가 사용가능하다.*/
// Collections.sort(bookList);
bookList.sort(new AscendingPrice());
System.out.println("가격 오름차순 정렬 ========================================");
for(BookDTO book: bookList) {
System.out.println(book);
}
/* 익명클래스(Anonymous Class)를 이용한 정렬 */
/* 인터페이스이기 때문에 바로 인스턴스를 생성할 수 없다.*/
// bookList.sort(new Comparator());
/* 익명클래스는 뒤에 {}을 만들어서 마치 Comparator 인터페이스를 상속받은 클래스인데
* 이름이 없다고 생각하고 사용하는 것이다.
* */
bookList.sort(new Comparator<BookDTO>() {
@Override
public int compare(BookDTO o1, BookDTO o2) {
/* 내림차순 정렬이 되어 있어서 순서를 바꾸는 경우 양수, 바꾸지 않은 경우에만 음수를 반환*/
return o1.getPrice() >= o2.getPrice()? -1: 1;
}
});
System.out.println("가격 내림차순 정렬 ========================================");
for(BookDTO book: bookList) {
System.out.println(book);
}
/* 제목 순 오름차순으로 정렬 */
bookList.sort(new Comparator<BookDTO>() {
@Override
public int compare(BookDTO o1, BookDTO o2) {
/* 문자열은 대소비교를 할 수 없다.*/
/* 문자 배열로 변경 후 인덱스 하나하나를 비교해서 어느 것이 더 큰 값인지
* 확인해야하는데 String클래스의 compareTo() 메소드에서 이미 정의해 놓았다.
* */
/* 앞에 값이 더 작은 경우(즉, 바꾸지 않아도 되는 경우)음수반환,
* 같으면 0 반환
* 앞에 값이 더 큰 경우 양수 반환(즉, 바꿔야 하는 경우)
* */
return o2.getTitle().compareTo(o1.getTitle());
}
});
System.out.println("책 제목 오름차순 정렬 ========================================");
for(BookDTO book: bookList) {
System.out.println(book);
}
/* 람다식(->)을 이용한 표기법*/
bookList.sort((BookDTO b1, BookDTO b2) -> b1.getTitle().compareTo(b2.getTitle()));
System.out.println("책 제목 내림차순 정렬 ========================================");
for(BookDTO book: bookList) {
System.out.println(book);
}
}
}
package com.greedy.section01.list.comparator;
import java.util.Comparator;
import com.greedy.section01.list.dto.BookDTO;
public class AscendingPrice implements Comparator {
@Override
public int compare(BookDTO o1, BookDTO o2) {
/* sort()에서 내부적으로 사용하는 메소드이다.
* 인터페이스를 상속받아서 메소드 오버라이딩 하는 것을 강제화 해 놓았다.
* */
int result = 0;
if(o1.getPrice() > o2.getPrice()) {
/* 오름차순을 위해 순서를 바꿔야 하는 경우 양수를 반환*/
result = 1;
} else if(o1.getPrice() < o2.getPrice()) {
/* 이미 오름차순 정렬로 되어 있는 겨우 음수를 반환*/
result = -1;
} else {
/* 두 값이 같은 경우는 0을 반환 */
result = 0;
}
return result;
}
}
BookDTO [number=1, title=홍길동전, author=허균, price=50000]
BookDTO [number=2, title=목민심서, author=정약용, price=30000]
BookDTO [number=3, title=동의보감, author=허준, price=40000]
BookDTO [number=4, title=삼국사기, author=김부식, price=46000]
BookDTO [number=5, title=삼국유사, author=일연, price=58000]
가격 오름차순 정렬 ========================================
BookDTO [number=2, title=목민심서, author=정약용, price=30000]
BookDTO [number=3, title=동의보감, author=허준, price=40000]
BookDTO [number=4, title=삼국사기, author=김부식, price=46000]
BookDTO [number=1, title=홍길동전, author=허균, price=50000]
BookDTO [number=5, title=삼국유사, author=일연, price=58000]
가격 내림차순 정렬 ========================================
BookDTO [number=5, title=삼국유사, author=일연, price=58000]
BookDTO [number=1, title=홍길동전, author=허균, price=50000]
BookDTO [number=4, title=삼국사기, author=김부식, price=46000]
BookDTO [number=3, title=동의보감, author=허준, price=40000]
BookDTO [number=2, title=목민심서, author=정약용, price=30000]
책 제목 오름차순 정렬 ========================================
BookDTO [number=1, title=홍길동전, author=허균, price=50000]
BookDTO [number=5, title=삼국유사, author=일연, price=58000]
BookDTO [number=4, title=삼국사기, author=김부식, price=46000]
BookDTO [number=2, title=목민심서, author=정약용, price=30000]
BookDTO [number=3, title=동의보감, author=허준, price=40000]
책 제목 내림차순 정렬 ========================================
BookDTO [number=3, title=동의보감, author=허준, price=40000]
BookDTO [number=2, title=목민심서, author=정약용, price=30000]
BookDTO [number=4, title=삼국사기, author=김부식, price=46000]
BookDTO [number=5, title=삼국유사, author=일연, price=58000]
BookDTO [number=1, title=홍길동전, author=허균, price=50000]
package com.greedy.section01.list.run;
import java.util.LinkedList;
import java.util.List;
public class Applicaiton3 {
public static void main(String[] args) {
/* LinkedList
*
* ArrayList가 배열을 이용해서 발생할 수 있는 성능적인 단점을 보완하고자 고안되었다.
* 내부는 이중 연결리스트로 구현되어있다.
*
* 단일 연결 리스트
* : 저장한 요소가 순서를 유지하지 않고 저장되지만 이러한 요소들 사이를 링크로 연결하여
* 구성하며 마치 연뎔된 리스트 형태인 것 처럼 만든 자료구조이다.
* 요소의 저장과 삭제 시 다음 요소를 가리키는 참조 링크만 변경하면 되기 때문에
* 요소의 저장과 삭제가 빈번히 일어나는 경우 ArrayList보다 성능면에서 우수하다.
*
* 하지만 단일 연결리스는 다음 요소만 링크하기 때문에 이전 요소로 접근하기가 어렵다.
* 이를 보완하고자 만든 것이 이중 연결 리스트이다.
*
* 이중 연결 리스트
* : 단일 연결 리스트는 다음 요소만 링크하는 반면 이중 연결 리스트는 이전 요소도 링크하여
* 이전 요소로 접근하기 쉽게 고안된 자료구조이다.
*
*
*
* */
List<String> linkedList = new LinkedList<>();
linkedList.add("apple");
linkedList.add("banana");
linkedList.add("orange");
linkedList.add("mango");
linkedList.add("grape");
for(int i = 0; i < linkedList.size(); i++) {
System.out.println(i + " : " + linkedList.get(i));
}
linkedList.remove(1);
for(String s : linkedList) {// 향상된 for문의 오른쪽은 반복할 대상객체 왼쪽은 반복할 대상객체중의 하나
System.out.println(s);
}
linkedList.set(0, "fineapple");
/* toString() 메소드가 오버라이딩 되어있어서 모든 요소 정보를 쉽게 볼 수 있다.*/
System.out.println(linkedList);
/* isEmpty() 메소드는 list가 비어있는지를 확인할 때 사용*/
System.out.println(linkedList.isEmpty());
linkedList.clear();
System.out.println(linkedList.isEmpty());
}
}
0 : apple
1 : banana
2 : orange
3 : mango
4 : grape
apple
orange
mango
grape
[fineapple, orange, mango, grape]
package com.greedy.section01.list.run;
import java.util.Stack;
public class Application4 {
public static void main(String[] args) {
/* stack */
/* Stack은 리스트 계열의 클래스
* 스택 메모리 구조는 선형 메모리 공간에 데이터를 저장하며
* 후입선출(LIFO - Last Input First Out) 방식의 자료구조
* */
Stack<Integer> integerStack = new Stack<>();
/* Stack에 값을 넣을 때에는 push() 메소드를 이용
* *** 참고 ***
* add()도 이용가능하지만 Vector의 메소드이다 그래서
* push()를 사용하는 것이 좋다.
* */
integerStack.push(1);
integerStack.push(2);
integerStack.push(3);
integerStack.push(4);
integerStack.push(5);
System.out.println(integerStack);
/* 스택에서 요소를 찾을 때 search()를 이용
* 인덱스가 아닌 위에서부터의 순번을 의미한다.
* 또한 가장 상단의 위치가 0이 아닌 1부터 시작한다.
* */
System.out.println(integerStack.search(1));
/* stack에서 값을 꺼내는 메소드는 크게 2가지로 볼 수 있다.
* peek() : 해당 스택의 가장 마지막에 있는(상단에 있는) 요소 반환
* pop() : 해당 스택의 가장 마지막에 있는(상단에 있는) 요소 반환 및 제거
* */
System.out.println("peek() : " + integerStack.peek());
System.out.println(integerStack);
System.out.println("pop() : " + integerStack.pop());
System.out.println("pop() : " + integerStack.pop());
System.out.println("pop() : " + integerStack.pop());
System.out.println("pop() : " + integerStack.pop());
System.out.println("pop() : " + integerStack.pop());
// System.out.println("pop() : " + integerStack.pop());
/ 더이상 pop()으로 꺼내올 요소가 없는 경우 EmptyStackException이 발생한다/
System.out.println(integerStack);
}
}
[1, 2, 3, 4, 5]
5
peek() : 5
[1, 2, 3, 4, 5]
pop() : 5
pop() : 4
pop() : 3
pop() : 2
pop() : 1
[]
package com.greedy.section01.list.run;
import java.util.LinkedList;
import java.util.Queue;
public class Application5 {
public static void main(String[] args) {
/* Queue
*
* Queue는 선형 메모리 공간에 데이터를 저장하는
* 선입선출(FIFO - First Input First Out)방식의 자료구조
* */
/* Queue 자체로는 인터페이스이기 때문에 인스턴스 생성이 불가능하다.*/
// Queue que = new Queue<>();
/* Queue 인터페이스를 상속받는 하위 인터페이스들ㅇ느
* Deque, BlockingQueue, BlockingDeque, TransferQueue 등등 다양하지만
* 대부분 큐는 LinkedList를 이용한다.
* */
Queue<String> que = new LinkedList<>();
que.offer("first");
que.offer("second");
que.offer("third");
que.offer("fourth");
que.offer("fifth");
System.out.println(que);
/* 큐에서 데이터를 꺼낼 때는 2가지가 있다.
* peek() : 해당 큐의 가장 앞에 있는 요소(먼저 들어온 요소)를 반환
* poll() : 해당 큐의 가장 앞에 있는 요소(먼저 들어온 요소)를 반환하고 제거한다.
* */
System.out.println("peek() : " + que.peek());
System.out.println("peek() : " + que.peek());
System.out.println(que);
System.out.println("poll() : " + que.poll());
System.out.println("poll() : " + que.poll());
System.out.println(que);
}
}
[first, second, third, fourth, fifth]
peek() : first
peek() : first
[first, second, third, fourth, fifth]
poll() : first
poll() : second
[third, fourth, fifth]