티스토리 뷰
0. Comparable과 Comparator
- TreeSet의 객체와 TreeMap의 키는 저장과 동시에 자동으로 오름차순으로 정렬된다.
- 숫자 타입일 경우에는 값으로, 문자열 타입일 경우에는 유니코드 기준으로 정렬된다.
- TreeSet과 TreeMap은 정렬을 위해서 Comparable을 구현 객체로 요구한다.
- 숫자 타입이나 문자열 타입의 경우 모두 Comparable 인터페이스가 구현되어 있다.
- 그 외의 타입일 경우에는 직접 comparable을 구현해야 한다.
- 만약, comparable을 구현하고 있지 않을 경우에는 저장하는 순간 예외가 발생하게 된다.
1. LIFO와 FIFO 컬렉션
- 1 ) Stack 클래스 :
- 특징 : 후입선출( LIFO : Last In First Out 가장 마지막 것이 가장 먼저 나온다. ) 구조
- 첫번째로 넣은 것이 First이고, 가장 마지막에 넣은 것이 Last이다.
- First가 가장 밑에, Last가 가장 위에 쌓이게 되며 가장 마지막에 넣은 Last가 먼저 나오게 된다.
- Stack <E> stack = new Stack <E> ( );
- 응용 예 : JVM 스택 메모리
- 2 ) Queue 인터페이스 :
- 특징 : 선입선출( FIFO : First In First Out 가장 첫번째 것이 먼저 나온다. ) 구조
- 들어오고 나가는 통로가 정해져 있기에 순서가 보장되고 있다.
- 응용 예 : 작업 큐, 메시지 큐 . . .
- 구현 클래스 : LinkedList
- Queue queue = new LinkedList ( ) ;
2. Java.io 패키지
- 자바의 기본적인 데이터 입출력 ( IO : input/output ) API 제공
- Java.io 패키지의 주요 클래스 :
- File : 파일 시스템의 파일의 정보를 얻어내기 위한 클래스
- Console : 콘솔로부터 문자를 입출력하기 위한 클래스
- InputStream / OutputStream : 바이트 단위 입출력을 위한 최상위 입출력 클래스
- ( File / Data / Object / Buffered ) + InputStream / OutputStream : 하위 클래스
- Reader / Writer : 문자 단위 입출력을 위한 최상위 입출력 스트림 클래스
3. 입력 스트림과 출력 스트림의 개념
- 우리가 만든 프로그램을 기준으로 입력과 출력을 판단하게 된다.
- 프로그램을 기준으로 데이터가 들어오는 길목이 입력 스트림, 데이터가 나가는 길목이 출력 스트림이다.
- 입력 스트림 출발지의 예시 : 키보드, 파일, 프로그램
- 출력 스트림 도착지의 예시 : 모니터, 파일, 프로그램
- 입출력은 Java.io를 통해 받아들이고 흘러 보내게 된다.
- 프로그램끼리 입/출력을 하게 될 경우에는, 입장에 따라서 한 쪽이 입력 스트림을 가지고 있을 때 다른 한쪽이 출력 스트림을 가져야 한다.
- 이렇게 스트림은 입력과 출력을 동시에 할 수는 없기에 단방향이다.
4. 입력 스트림과 출력 스트림
- 1 ) 바이트 기반 스트림 : 그림, 멀티미디어, 문자 등 모든 종류의 데이터를 받고 보내는 것이 가능하다.
- 바이트 기반 입력 스트림 : InputStream / 하위 클래스 : xxxInputStream
- 바이트 기반 출력 스트림 : OutputStream / 하위 클래스 : xxxOutputStream
- 2 ) 문자 기반 스트림 : 문자만 받고 보낼 수 있도록 특화
- 문자 기반 입력 스트림 : Reader / 하위 클래스 : xxxReader
- 문자 기반 출력 스트림 : Writer / 하위 클래스 : xxxWriter
- 입력과 출력은 프로그램 기준으로 판단해야 한다!
5. InputStream
- 바이트 기반 입력 스트림의 최상위 클래스로 추상 클래스이다.
- 하위 클래스 : FileInputStream, BufferedInputStream(임시), DataInputStream
- BufferedInputStream을 통해 효율성을 높일 수 있다.
- DataInputStream는 바이트로 바꿔야 하는 다른 것과 다르게 변수들을 바로 사용할 수 있다.
- InputStream은 사용이 끝나면 close( )로 반드시 닫아야 한다!!!
6. OutputStream ( p. 1000 )
- 바이트 기반 출력 스트림의 최상위 클래스로 추상 클래스이다.
- 하위클래스: FileOutputStream, PrintStream, BufferedOutputStream, DataOutputStream
- InputStream과 같이 OutputStream도 사용이 끝나면 close( )해야 한다.
- OutputStream은 InputStream과 다르게 flush( )라는 주요 메소드를 지니고 있다.
- 그 이유는 OutputStream은 InputStream과 다르게 버퍼에 일단 담고 있다가 버퍼가 꽉 차면 흘러 보내게 되는데, 혹시나 버퍼가 차지 않아서 보내지 못하고 잔류하는 데이터가 있을 수 있기에 반드시 flush( )를 통해 버퍼에 잔류하는 모든 바이트를 출력해야 한다.
7. Try – with – resources ( p.438 )
- 사용했던 리소스 객체의 close( ) 메소드를 호출해서 리소스(자원)를 닫는다.
- Java.lang.AutoCloseable 인터페이스를 구현하고 있어야 한다.
- 자동적으로 is.close( )를 해준다.
01. TreeMap 1 - 주요 메소드
package TreeSet;
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
TreeMap <Integer,String> scores = new TreeMap<>();
scores.put(87, "홍길동");
scores.put(98, "이동수");
scores.put(75, "박길순");
scores.put(95, "신용권");
scores.put(80, "김자바");
System.out.println(scores);
System.out.println();
// 출력 : {75=박길순, 80=김자바, 87=홍길동, 95=신용권, 98=이동수}
// 키 값을 기준으로 오름정렬되고 있음을 알 수 있다.
// =============================
Map.Entry<Integer, String> entry = null;// key와 value의 값을 쌍으로 강제형변환 없이 가져온다.(***)
entry = scores.firstEntry(); // 키의 값을 비교
System.out.println("가장 낮은 점수 : " + entry.getKey() + " - " + entry.getValue());
// 출력 : 가장 낮은 점수 : 75 - 박길순
System.out.println();
// =============================
entry = scores.lastEntry(); // 키의 값을 비교
System.out.println("가장 높은 점수 : " + entry.getKey() + " - " + entry.getValue());
// 출력 : 가장 높은 점수 : 98 - 이동수
System.out.println();
// =============================
entry = scores.lowerEntry(95);
System.out.println("95점 아래 점수 : " + entry.getKey() + " - " + entry.getValue());
// 출력 : 95점 아래 점수 : 87 - 홍길동
System.out.println();
// =============================
entry = scores.higherEntry(95);
System.out.println("95점 위의 점수 : " + entry.getKey() + " - " + entry.getValue());
// 출력 : 95점 위의 점수 : 98 - 이동수
System.out.println();
// =============================
entry = scores.floorEntry(95);
System.out.println("95점 이거나 바로 아래의 점수 : " + entry.getKey() + " - " + entry.getValue() );
// 출력 : 95점 이거나 바로 아래의 점수 : 95 - 신용권
System.out.println();
// =============================
entry = scores.ceilingEntry(85);
System.out.println("85점 이거나 바로 위의 점수 : " + entry.getKey() + " - " + entry.getValue() );
// 출력 : 85점 이거나 바로 위의 점수 : 87 - 홍길동
System.out.println();
// =============================
while( !scores.isEmpty() ) { // 계속 첫번째의 것을 끄집어 내는 while문이다. (****)
entry = scores.pollFirstEntry();
System.out.println(entry.getKey() + " - " + entry.getValue() + " ( 남은 객체 수 : " + scores.size() + " )");
} // while
// 출력 :
// 75 - 박길순 ( 남은 객체 수 : 4 )
// 80 - 김자바 ( 남은 객체 수 : 3 )
// 87 - 홍길동 ( 남은 객체 수 : 2 )
// 95 - 신용권 ( 남은 객체 수 : 1 )
// 98 - 이동수 ( 남은 객체 수 : 0 )
// =============================
} // main
} // end class
02. TreeSet 1 - 주요 메소드
package TreeSet;
import java.util.TreeSet;
public class TreeSetExample { // TreeSet
// TreeSet은 이진 트리를 통해, 요소를 미리 정렬시켜주고
// 정렬된 데이터를 이용해서, 빠른 검색을 해주는 장점이 있다!!(**)
public static void main (String [] args) {
TreeSet<Integer> scores = new TreeSet<Integer>();
// =========================
// Auto-Boxing
scores.add(87);
scores.add(98);
scores.add(75);
scores.add(95);
scores.add(80);
// scores.add(new Integer(100)); : 구버전
System.out.println(scores);
// 출력 : [75, 80, 87, 95, 98] < - - 데이터를 자동으로 정렬해 준다.
// =========================
Integer score = null;
score = scores.first(); // 가장 작은 값을 의미한다.
System.out.println("가장 낮은 점수 : " + score);
// =========================
score = scores.last(); // 가장 큰 값을 의미한다.
System.out.println("가장 높은 점수 : " + score + "\n");
// =========================
score = scores.lower(95);
System.out.println("95점 바로 아래의 점수 : " + score);
// 95점 바로 아래의 점수 : 87
// =========================
score = scores.higher(95);
System.out.println("95점 바로 위의 점수 : " + score);
// 95점 바로 위의 점수 : 98
// =========================
score = scores.floor(95);
System.out.println("95점이거나 바로 아래의 점수 : " + score);
// 95점이거나 바로 아래의 점수 : 95
// =========================
score = scores.ceiling(85);
System.out.println("85점이거나 바로 위의 점수 : " + score);
// 85점이거나 바로 위의 점수 : 87
// =========================
while ( !scores.isEmpty() ) { // 전체가 다 빠져나가면 비어버리기 때문에 자동으로 flase가 되어 끝나버린다.
score = scores.pollFirst(); // 첫번째 요소를 빼낸다. ( 아예 TreeSet에서 없애버린다. )
System.out.println(score + " ( 남은 객체의 수 : " + scores.size() + " )");
} // while
// 출력
// 75 ( 남은 객체의 수 : 4 )
// 80 ( 남은 객체의 수 : 3 )
// 87 ( 남은 객체의 수 : 2 )
// 95 ( 남은 객체의 수 : 1 )
// 98 ( 남은 객체의 수 : 0 )
// =========================
} // main
} // end class
03. TreeSet 2 - 정렬하기
package TreeSet;
import java.util.NavigableSet;
import java.util.TreeSet;
public class TreeSetExample2 { // TreeSet - 정렬하기
public static void main (String [] args) {
TreeSet<Integer> scores = new TreeSet<Integer>();
// =========================
// Auto-Boxing
scores.add(87);
scores.add(98);
scores.add(75);
scores.add(95);
scores.add(80);
// scores.add(new Integer(100)); : 구버전
System.out.println(scores);
// 출력 : [75, 80, 87, 95, 98] < - - 데이터를 자동으로 오름차순으로 정렬해 준다.
// =========================
// 내림차순(descending)으로 정렬하기
NavigableSet<Integer> descendingSet = scores.descendingSet();
for ( Integer score : descendingSet ) {
System.out.print(score + " ");
} // enhanced for
// 출력 : 98 95 87 80 75
System.out.println();
// =========================
// 오름차순으로 정렬하기 - descendingSet을 한 번 더 해주면 내림차순으로 바꾼 것이 다시 오름차순으로 변경된다.
NavigableSet<Integer> ascendingSet = descendingSet.descendingSet();
for ( Integer score : ascendingSet ) {
System.out.print( score + " ");
} // enhanced for
// 출력 : 75 80 87 95 98
System.out.println();
// =========================
} // main
} // end class
04. TreeSet 3 - 범위 검색
package TreeSet;
import java.util.NavigableSet;
import java.util.TreeSet;
public class TreeSetExample3 { // TreeSet - 정렬하기
public static void main (String [] args) {
TreeSet<String> treeSet = new TreeSet<String>();
// =========================
// TreeSet은 요소의 차입이 숫자뿐만이 아니라, 아래와 같이 문자열도 이진 트리로 자동정렬이 가능하다.
// 문자열은 사전 순서대로 정렬된다.
// Auto-Boxing
treeSet.add("apple");
treeSet.add("forever");
treeSet.add("description");
treeSet.add("ever");
treeSet.add("zoo");
treeSet.add("base");
treeSet.add("guess");
treeSet.add("cherry");
System.out.println(treeSet);
// 출력 : [apple, base, cherry, description, ever, forever, guess, zoo]
System.out.println();
// =========================
// 범위검색
System.out.println(" [ c ~ f 사이의 단어를 검색 ] ");
NavigableSet <String> rangeSet = treeSet.subSet("cherry", true, "forever", true);
// 정한 범위 내에서 검색한다. 만약 true가 아닌 false로 작성하면 cherry와 forever은 출력되지 않는다.
for ( String word : rangeSet ) {
System.out.println(word);
} // enhanced for
// 출력 :
// [ c ~ f 사이의 단어를 검색 ]
// cherry
// description
// ever
// forever
System.out.println();
// =========================
} // main
} // end class
05. Comparable
package comparable;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class Person implements Comparable <Person> {
public String name;
public int age;
@Override
public int compareTo(Person o) { // 나이로 대소 비교하는 Comparable
if(age < o.age) return -1;
else if (age == o.age) return 0;
else return 1;
} // compareTo
// String이나 Integer과 다르게 이렇게 직접 타입을 생성할 때는
// 기본적으로 대소 비교가 불가능하기에 Comparable해줘야 한다.(**)
} // end class
package comparable;
import java.util.Iterator;
import java.util.TreeSet;
public class ComparableExample {
public static void main (String[] args) {
TreeSet<Person> treeSet = new TreeSet<>();
// ========================================
// 객체 생성
treeSet.add(new Person("홍길동", 45));
treeSet.add(new Person("홍길동", 25));
treeSet.add(new Person("홍길동", 31));
// String이나 Integer과 다르게 이렇게 직접 타입을 생성할 때는
// 기본적으로 대소 비교가 불가능하기에 Comparable해줘야 한다.(**)
// 만약 Comparable 하지 않으면, 정렬이 불가능 하여 예외가 발생하게 된다.
// ========================================
// Traverse 순회
Iterator<Person> iterator = treeSet.iterator();
while ( iterator.hasNext() ) {
Person person = iterator.next();
System.out.println(person.name + " : " + person.age);
} // while
// ========================================
for ( Person i : treeSet) {
System.out.println(i.name + " : " + i.age);
} // enhanced for
} // main
} // end class
06. Comparator
package comparable;
import lombok.AllArgsConstructor;
import lombok.ToString;
@ToString
@AllArgsConstructor
public class Fruit { // POJO : Plan Old Java Object
public String name;
public int price;
} // end class
package comparable;
import java.util.Comparator;
public class DescendingComparator implements Comparator<Fruit> { // Comparator 생성 ( 외부비교자 )
@Override
public int compare(Fruit o1, Fruit o2) { // if문은 실행문장이 1개면 생략할 수도 있다.
if(o1.price < o2.price) {
return 1;
} else if ( o1.price == o2.price ) {
return 0;
} else {
return -1;
} // if - else if - else
} // compare
} // end class
package comparable;
import java.util.Comparator;
import java.util.TreeSet;
public class ComparatorExample {
public static void main (String [] args) {
Comparator<? super Fruit > comparator = new DescendingComparator();
TreeSet<Fruit> treeSet = new TreeSet<>(comparator);
// TreeSet<Fruit> treeSet = new TreeSet<>(new DescendingComparator());
// 위의 2개의 코드를 합치면 이렇게 작성된다.
// ===================================================
treeSet.add(new Fruit("포도", 3000));
treeSet.add(new Fruit("수박", 10000));
treeSet.add(new Fruit("딸기", 6000));
System.out.println(treeSet);
// 출력 : [Fruit(name=수박, price=10000), Fruit(name=딸기, price=6000), Fruit(name=포도, price=3000)]
// ===================================================
// 정렬이 가격기준 내림으로 되어있는 것을 볼 수 있는데, (****)
// 이는 DescendingComparator에서 compare을 내림차순으로 오버라이드 했기 때문이다.
// 오름차순으로 바꾸고 싶다면 리턴값을 음수에서 양수로, 양수에서 음수로 바꾸면 된다.
// ===================================================
} // main
} // end class
07. Stack
package stack;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
@ToString
@Getter
@AllArgsConstructor
public class Coin { // 동전을 모델링을 해서 만든 클래스
private int value; // 고유 속성
} // end class
package stack;
import java.util.Stack;
public class StackExample { // stack
public static void main(String [] args) {
Stack<Coin> coinBox = new Stack<>();
// ========================================
coinBox.push(new Coin(100)); // First
coinBox.push(new Coin(50));
coinBox.push(new Coin(500));
coinBox.push(new Coin(10)); // Last
System.out.println(coinBox);
// 출력 : [Coin(value=100), Coin(value=50), Coin(value=500), Coin(value=10)]
// ========================================
// 순회 ( traverse )
while( !coinBox.isEmpty() ) {
Coin coin = coinBox.pop(); // 스택의 가장 마지막의 것을 빼오고, 이것을 스택에서 제거한다. poll과 유사하다.
System.out.println("꺼내온 동전 : " + coin.getValue() + "원");
} // while
// 출력 :
// 꺼내온 동전 : 10원
// 꺼내온 동전 : 500원
// 꺼내온 동전 : 50원
// 꺼내온 동전 : 100원
// ========================================
} // main
} // end class
08. queue
package queue;
import lombok.AllArgsConstructor;
import lombok.ToString;
@ToString
@AllArgsConstructor
public class Message {
public String command;
public String to;
} // end class
package queue;
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
// 대표적인 Message Q : IBM websphere MQ, Active MQ, Rabbit MQ
Queue <Message> mq = new LinkedList<Message>(); // List - 순서가 보장된다.
// LinkedList는 객체의 추가나 삭제가 빈번할 때 유리한 list이다.
mq.offer(new Message("sendMail","홍길동"));
mq.offer(new Message("sendSNS","신용권"));
mq.offer(new Message("sendKaKaotalk","홍두께"));
System.out.println(mq);
// 출력 : [Message(command=sendMail, to=홍길동), Message(command=sendSNS, to=신용권), Message(command=sendKaKaotalk, to=홍두께)]
// ==========================================================
while ( !mq.isEmpty() ) {
Message message = mq.poll();
switch ( message.command ) {
case "sendMail" :
System.out.println(message.to + "님에게 메일을 보냅니다.");
break;
case "sendSNS" :
System.out.println(message.to + "님에게 SNS를 보냅니다.");
break;
case "sendKaKaotalk" :
System.out.println(message.to + "님에게 카톡을 보냅니다.");
break;
} // switch
// ==========================================================
// Switch Expression 새로운 구문으로 대체 코드로 작성할 것! (***)
String command = switch(message.command) {
case "sendMail","sendSNS" -> { yield message.command + 10; }
default -> { yield message.command;} // 디폴트는 반드시 넣어야 한다.
}; // switch expression
System.out.println(command);
} // while
// ================================================================
// 출력 :
// 홍길동님에게 메일을 보냅니다.
// sendMail10
// 신용권님에게 SNS를 보냅니다.
// sendSNS10
// 홍두께님에게 카톡을 보냅니다.
// sendKaKaotalk
} // main
} // end class
09. InputStream 1 - 파일입력
package inputstream_read;
import java.io.FileInputStream;
import java.io.InputStream;
public class ReadExample1 { // InputStream
public static void main(String[] args) throws Exception {
// is.read()를 보면 int java.io.InputStream.read() throws IOException라고 적혀 있는 것을 보아
// IOException이라는 예외가 발생할 수 있으니 미리 알리기 위헤 throws와 같이 예외를 작성하였다. ( 다형성1 )
// 입력 스트림 객체를 생성하는 순간 -> 실제 타겟과 연결된다.
// 만약 실제 타겟이 실존하지 않다면 예외가 발생하게 된다.
InputStream is = new FileInputStream("C:/Temp/TTT.txt"); // 다형성1 (*****)
// (" ") 주소에 있는 파일의 데이터를 읽어서 출력하자!
// =============================================================================
while(true) { // 파일의 끝이 언제 도달할지 모르기 때문에 무한루프를 돌린다.(***)
int readByte = is.read(); // 입력 스트림으로 들어오는 바이트를 1 바이트씩 읽어 들인다.(***)
// 무한 루프의 탈출조건 만들기
if(readByte == -1) { // 파일의 끝( End Of File (EOF) )의 값인 -1이 들어오면
break;
} // if
System.out.print((char)readByte); // byte -> char 강제형변환
// C:/Temp/TTT.txt는 문자로 구성된 파일이기에 char로 강제형변환하여 문자로 표시해야 한다.
// =============================================================================
// 출력 :
// Yoseph
// dididi
// nonono
// momomomom
// kikikikiki
// hahahahaha
// opopopopohohohohhoh
// í길ë // = 홍길동
// 한글은 1바이트씩 읽어들이기 때문에 한글이 깨지게 된다. (한계점)
// =============================================================================
} // while
is.close(); // 자원 해제 (***)
} // main
} // end class
10. InputStream 2 - try - catch - finally 버전
package inputstream_read;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ReadExample2 { // InputStream
public static void main(String[] args) { // try - catch - finally(****)
// 다중 catch를 사용할 때는 부모/자식관계의 예외인지를 파악하여 자식을 위에, 부모를 아래에 적어야 한다!!(****)
// catch에서 예외를 작성한 후에는 반드시 import문을 생성해야 한다.
// 다른 예외가 발생했을 때, 같은 예외처리 코드를 사용하고 싶을 때는 |를 활용하여 multi catch로 사용해야 한다.
// 지역변수는 선언만으로 끝내지 말고, 적절한 초기값으로 정의해줘야 한다!!!!!(***)
InputStream is = null;
try {
is = new FileInputStream("C:/Temp/TTT.txt");
// =============================================================================
while(true) { // 파일의 끝이 언제 도달할지 모르기 때문에 무한루프를 돌린다.(***)
int readByte = is.read(); // 입력 스트림으로 들어오는 바이트를 1 바이트씩 읽어 들인다.(***)
// 무한 루프의 탈출조건 만들기
if(readByte == -1) { // 파일의 끝( End Of File (EOF) )의 값인 -1이 들어오면
// -1인 이유는 원래는 음수가 나올 수가 없는데, 음수가 나오면 파일이 끝난거기 때문이다.
break;
} // if
System.out.print((char)readByte); // byte -> char 강제형변환
// C:/Temp/TTT.txt는 문자로 구성된 파일이기에 char로 강제형변환하여 문자로 표시해야 한다.
} // while
// =============================================================================
is.close(); // 자원 해제 (***)
} catch (IOException e) {
e.printStackTrace(); // 예외가 발생한 곳을 추적해주기 때문에 무조건 작성하는 것이 좋다.(**)
} finally{ //try 블록에서 예외가 발생하든 발생하지 않든 반드시 실행하는 블록
// 자원 해제 코드 작성
try {
is.close(); // 자원 해제 - 예외발생 ( is가 try블록 내에서만 유효하기 때문이다. )
// 선언만 하면 class블록에서 해서 is를 살려놔도 초기화가 발생하지 않아 오류가 발생하기에
// 일단 null 정의해야 하고, 후에 값을 바꾸는 형태로 활용해야 한다. (****)
} catch (IOException e) {
e.printStackTrace();
} // inner try - catch ( 너무 효율적이지 않다. )
}// try - catch - finally
} // main
} // end class
11. InputStream 3 - try - with - resource 버전
package inputstream_read;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class ReadExample3 { // InputStream
public static void main(String[] args) { // try - with - resource (****)
// Type Hierachy로 AutoCloseable이 있는지 확인해야 한다.
try { // 이 처럼 닫아야 하는 자원이 여러개여도 자동으로 닫아주기에 걱정하지 않아도 된다.
InputStream is = new FileInputStream("C:/Temp/TTT.txt");
InputStream is2 = new FileInputStream("C:/Temp/TTT.txt");
InputStream is3 = new FileInputStream("C:/Temp/TTT.txt");
InputStream is4 = new FileInputStream("C:/Temp/TTT.txt");
try ( is; is2; is3; is4;) { // 자바 8이후 버전
// 자원을 닫는 순서는 ( ) 안에서 오른쪽에서 왼쪽 순으로 닫히게 된다. (***)
// ex. is4 - is3 - is2 - is 순으로 자원이 닫히게 된다.
// 이것을 활용하여 먼저 닫혀야 하는 자원을 가장 마지막에 작성하면 된다.
while(true) {
int readByte = is.read();
if(readByte == -1) {
break;
} // if
System.out.print((char)readByte);
} // while
// is.close(); //try - with - resource는 자동으로 닫아 주기에 작성하지 않아야 한다.
} // inner - try ( 자원을 활용 )
} catch (IOException e) {
e.printStackTrace();
} // try - with - resource
// ================================================================
// InputStream is2 = new FileInputStream("C:/Temp/TTT.txt");
// InputStream is3 = new FileInputStream("C:/Temp/TTT.txt");
// 이 처럼 닫아야 하는 자원이 여러개여도 자동으로 닫아주기에 걱정하지 않아도 된다.
// try ( InputStream is = new FileInputStream("C:/Temp/TTT.txt"); is2; is3;) {
//
// while(true) {
// int readByte = is.read();
// if(readByte == -1) {
// break;
// } // if
// System.out.print((char)readByte);
// } // while
//
//// is.close(); //try - with - resource는 자동으로 닫아 주기에 작성하지 않아야 한다.
//
// } catch(IOException e){
// e.printStackTrace(); // 예외 추적
// } // try - with - resources
} // main
} // end class
12. InputStream 4 - @Cleanup 버전 (***)
package inputstream_read;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import lombok.Cleanup;
public class ReadExample4 { // InputStream
public static void main(String[] args) { // try -catch + @Cleanup (****)
// Type Hierachy로 AutoCloseable이 있는지 확인해야 한다.
try { // @Cleanup은 위치가 지정되어 있기에 객체를 생성할 때 작성해야 한다.
// @Cleanup은 is.close()를 대체해주는 롬복이다.
// @Cleanup( )에서 ( ) 안에 다른 것을 작성하여, 닫는 것을 바꿀 수도 있다. ( default는 close이다. )
@Cleanup // 자원을 블록이 끝날 때, 예외 발생과 상관없이 자동으로 닫아주는 롬복, 예외처리를 해주지는 않는다.(****)
InputStream is = new FileInputStream("C:/Temp/TTT.txt");
InputStream is2 = new FileInputStream("C:/Temp/TTT.txt");
InputStream is3 = new FileInputStream("C:/Temp/TTT.txt");
InputStream is4 = new FileInputStream("C:/Temp/TTT.txt");
while(true) {
int readByte = is.read();
if(readByte == -1) {
break;
} // if
System.out.print((char)readByte);
} // while
} catch (IOException e) { // 롬복이 예외처리를 해주지는 않는다.
e.printStackTrace();
} // try - catch
} // main
} // end class
'KH 정보교육원 [ Java ]' 카테고리의 다른 글
KH 25일차 - 콘솔 (0) | 2022.04.01 |
---|---|
KH 24일차 - 자바 입출력 ( Reader / Writer ) (0) | 2022.03.31 |
KH 22일차 - 컬렉션 프레임워크 (0) | 2022.03.29 |
KH 21일차 - 함수적 인터페이스 및 컬렉션 프레임 워크 (0) | 2022.03.28 |
KH 20일차 - 람다식과 함수적 인터페이 (0) | 2022.03.26 |