티스토리 뷰
📌 230816 TIL : 입출력 스트림, 스트림 공부, Reduce 연산
📝 입출력 스트림 분류
1. 데이터(이진 데이터, 문자)의 종류의 따른 분류
1) 바이트 스트림 : 이진데이터(바이너리 데이터)를 처리하는 스트림
- 바이트 입력 스트림 : InputStream - read() : 바이트 단위로 읽기.
- 바이트 출력 스트림 : OutputStream - write() : 바이트 단위로 쓰기.
- 파일 바이트 데이터를 읽기 : FileInputStream
- 파일 바이트 데이터로 저장 : FileOutputStream
2) 문자 스트림 : 문자 데이터를 처리하는 스트림 (스트림 내부에서 문자 인코딩이 적용된다.)
- 문자 입력 스트림 : Reader - read() : 문자 단위로 읽기.
- 문자 출력 스트림 : Writer - write(), print(), println() : 문자 단위로 쓰기
2. 처리 방식에 따른 분류
1) 노드 스트림
- 입출력 데이터에 가장 먼저 연결되는 스트림
- InputStream, OutputStream, FileInputStream, FileOutputStream, Reader, Writer
2) 필터 스트림
- 단독 사용 불가 -> 반드시 1) 노드 스트림에 연결하여 사용 => 생성자에서 연결해야함.
- 매번 읽고 쓰는 것보다 버퍼에 저장하여 한번에 처리하는 것이 훨씬 효율적이기 때문에 사용한다.
- 버퍼는 한 줄씩 읽는다. 메소드 : readLine();
- BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
//바이트 스트림 -> 문자 스트림 -> 버퍼 기능
System.out.print("문자열을 입력 하세요: ");
String line = bufferedReader.readLine();
System.out.println(line);
3) 브릿지 스트림
- 바이트 입력(출력) 스트림을 문자 입력(출력) 스트림으로 변환.
- 이걸 통해 한글도 입출력이 가능하다.
- 필터 스트림 계열임.
- 바이트 입력 스트림 -> 문자 입력 스트림 : InputStreamReader
- 바이트 출력 스트림 -> 문자 출력 스트림 : OutputStreamReader
📝 파일 핸들링 방법
방법 1) 파일 데이터를 한글자씩 읽어오는 노드 스트림 방법
방법 2) 파일 데이터를 읽는 노드스트림 -> 버퍼에 저장하는 필터 스트림
두 방법을 비교 해보았다.
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
/*
* 파일 핸들링하기
* 파일에 있는 데이터를 읽기 (이미지- 카피, 문자) - xml, json
*/
//파일에서 문자 데이터를 읽어 오기 위한 스트림의 연결 (member.txt)
//버퍼를 쓰면 3번만에 할 수 있는데 밑의 방법은 한글자씩 읽으므로 매번 돌아야해서 비효율.
System.out.println("= 방법 1 =");
FileReader fileReader = new FileReader("member.txt");
int data;
int cnt = 0;
while ((data = fileReader.read()) != -1) {
System.out.print((char)data);
cnt++;
}
System.out.println("반복문 돈 횟수: " + cnt);
System.out.println("= 방법 2 =");
BufferedReader br = new BufferedReader(new FileReader("member.txt"));
String line;
cnt = 0;
while((line = br.readLine()) != null) {
System.out.println(line);
cnt++;
}
System.out.println("반복문 돈 횟수: " + cnt);
}
}
방법 2) 이가 한 줄씩 읽어오므로 방법 1보다 훨씬 반복문이 적게 돌기 때문에 효율적이다.
📝 기타 스트림에 대해
💡 스트림이란?
1) 자료에 대상과 관계없이 동일한 연산을 수행하도록 함.
- 배열, 컬렉션을 대상으로 연산을 수행함.
- 일관성 있는 연산으로 인해 자료의 처리를 쉽고 간단하게 함.
2) 한번 생성한 스트림은 재사용이 불가능.
- 자료에 대한 스트림을 생성하여 연산을 실행하면 스트림은 소모됨. 다른 연산을 수행하기 위해서는 스트림을 다시 생성해야함.
- 스트림의 연산은 기존 자료를 변경하지 않음.
- 자료에 대한 스트림을 생성하면 스트림이 사용하는 메모리 공간은 별도로 생성되므로 연산이 수행되도 기존 자료에 대한 변경은 발생하지 않음.
3) 중간 연산과 최종 연산
- 스트림의 연산은 중간 연산과 최종 연산으로 구분된다.
- 중간 연산은 여러개의 연산이 적용될 수 있지만, 최종연산은 단 한번의 연산만 적용된다. 또한 최종이 호출되어야, 중간연산들도 수행된다. 따라서 중간 연산에 대한 결과를 연산중에는 알 수 없다. 이를 ‘지연 연산’이라고도 한다.
- 중간 연산 : filter(), map(), sorted()
- 최종 연산 : forEach(), count(), sum()
📝 사용 예시
1) forEach
int[] arr = {1,2,3,4,5};
Arrays.stream(arr).forEach(n->System.out.print(n+", "));
List<String> sList = new ArrayList<>();
sList.add("Tomas");
sList.add("Edward");
sList.add("Jack");
sList.stream().forEach(s-> System.out.print(s+"\t"));
2) sorted()
sList.stream().sorted().forEach(s-> System.out.print(s+"\t"));
//Edward Jack Tomas
3) filter()
//문자열 길이가 5이상인 문자열만 뽑아 출력
sList.stream().filter(s->s.length()>=5).forEach(s-> System.out.print(s+"\t"));
//5 6 4
4) map()
//문자열 길이만 뽑아 출력
sList.stream().map(s->s.length()).forEach(n-> System.out.print(n+"\t"));
//Tomas Edward
✏️ TravelCustomer 객체를 스트림으로 활용해보기
class TravelCustomer {
private String name;
private int age, price;
public TravelCustomer(String name, int age, int price) {
this.name = name;
this.age = age;
this.price = price;
}
@Override
public String toString() {
return "TravelCustomer{" +
"name='" + name + '\'' +
", age=" + age +
", price=" + price +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
public class TravelCustomerTest {
public static void main(String[] args) {
TravelCustomer customerLee = new TravelCustomer("이순신", 40, 100);
TravelCustomer customerKim = new TravelCustomer("김유신", 20, 200);
TravelCustomer customerHong = new TravelCustomer("홍길동", 13, 50);
ArrayList<TravelCustomer> customers = new ArrayList<>();
customers.add(customerLee);
customers.add(customerKim);
customers.add(customerHong);
//이름만 출력하기
System.out.println("= 고객 명단 출력 =");
customers.stream().map(c->c.getName()).forEach(c-> System.out.print(c+"\t"));
//여행비용 총합
System.out.println("\n= 여행 비용 총합 =");
System.out.println(customers.stream().mapToInt(c->c.getPrice()).sum());
//나이가 20살 이상인 고객만 출력, 정렬
System.out.println("= 20살 이상인 여행객들 =");
customers.stream().filter(c-> c.getAge()>=20).map(c->c.getName()).sorted().forEach(c->System.out.print(c+"\t"));
}
}
📝 Reduce 연산
- 정의된 연산이 아닌 프로그래머가 직접 구현한 연산을 적용.
- 인터페이스 구조 : T reduce(T identify, BinaryOperator<T> accumulator)
- 최종 연산으로 스트림의 요소를 소모하며 연산을 수행함.
// 배열의 모든 요소의 합을 구하는 reduce 연산 :
Arrays.stream(arr).reduce(0, (a,b) -> (a+b));
✏️ 사용예제 : 바이트가 가장 큰 문자열을 찾기
class CompareString implements BinaryOperator<String> {
@Override
public String apply(String s, String s2) {
if (s.getBytes().length >= s2.getBytes().length) return s;
return s2;
}
}
public class ReduceTest {
public static void main(String[] args) {
String[] greeting = {"안녕하세요!", "hello", "Good morning", "반갑습니다."};
//익명 함수
System.out.println(Arrays.stream(greeting).reduce("",(s1,s2) -> {
if ( s1.getBytes().length >= s2.getBytes().length) return s1;
else return s2;
}));
// BinaryOperator 인터페이스를 구현한 클래스를 활용한 예
String s = Arrays.stream(greeting).reduce(new CompareString()).get();
System.out.println(s);
}
}
'백엔드 공부하기 > TIL' 카테고리의 다른 글
230822 TIL : 직렬화, 역직렬화 (0) | 2023.08.22 |
---|---|
230817 TIL : 사용자 정의 예외클래스, Logging (0) | 2023.08.17 |
230811 TIL : 내부 클래스, 람다식 (0) | 2023.08.12 |
230810 TIL : HashSet, TreeSet, Comparable와 Comparator 차이 (0) | 2023.08.10 |
230808 TIL : 제네릭 프로그래밍, 제네릭 메소드, 와일드카드.. (0) | 2023.08.09 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 야놀자
- 과정중간회고
- 국비지원취업
- 그룹스터디워크샵
- springboot
- 스터디후기
- 패스트캠퍼스강의
- #국비지원취업
- 백엔드부트캠프
- 패스트캠퍼스
- 자료구조 #스택 #큐 #덱 #선형자료구조
- 백엔드개발자
- be
- TiL
- 백엔드
- 야놀자X패스트캠퍼스부트캠프
- qjzl
- 채팅기능개발
- 국비지원캠프
- 자료구조
- 부트캠프
- 국비지원
- 그룹스터디
- Java
- 데이터베이스
- 프로젝트후기
- 백준
- 카카오API
- boj
- 커리어멘토링
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함