-
Stream, 왜 재사용 할 수 없을까Java 2021. 3. 1. 18:04
Stream
Stream 이란?
A sequence of elements supporting sequential and parallel aggregate operations.
Oracle Java8 Document를 보면 위와 같이
순차 및 병렬 집계 작업들을 지원하는 일련의 요소들
이라고 나와있다. Stream을 이용하면 컬렉션 데이터를 처리하는데 필요한 기능들 (ex> 특정 조건에 맞는 대상 수집, 정렬, 특정객체로 변환)을 연결하여 간결하게 처리가 가능하다.만약 7천원 이하 메뉴들의 이름을 확인해야할 경우 아래처럼 구현할 수 있다.
public class Menu { private String name; private int price; public Menu(String name, int price) { this.name = name; this.price = price; } public boolean canBuy(int money) { return money >= price; } public String getName() { return this.name; } } public class Menus { private List<Menu> menus; public Menus(List<Menu> menus) { this.menus = menus; } public List<String> getMenuList(int money) { return menus.stream() .filter(menu -> menu.canBuy(money)) .map(Menu::getName) .collect(toList()); } }
Menus.getMenuList()
를 보면 Stream을 이용하여 구매가능한 메뉴들의 이름 List를 반환하고 있다.filter()
부분을 보면 List에 속한 요소들을 하나씩 조건에 해당하는지 판단하고 있다. 여기서는 주어진 금액으로 해당 메뉴를 구매할 수 있는지 판단하고 있다.그 다음으로
map()
인데 여기서 map은 HashMap과 같은 map이 아니라A를 B로 매핑한다
의 의미이다. filter에서 통과한 Menu 요소를 메뉴이름이라는 String으로 매핑하는 과정을 처리한다. 마지막으로 이렇게 변환된 메뉴이름들을 한대 모아 List로 반환하는 과정을.collect(toList())
에서 처리한다.@DisplayName("구매가능한 메뉴이름 확인") @Test void getMenuListByMoney() { //given Menu 김치볶음밥 = new Menu("김치볶음밥", 6_500); Menu 소불고기김밥 = new Menu("소불고기김밥", 4_500); Menu 철판제육볶음밥 = new Menu("철판제육볶음밥", 8_000); List<Menu> menuList = Arrays.asList(김치볶음밥, 철판제육볶음밥, 소불고기김밥); Menus menus = new Menus(menuList); //when, then assertThat(menus.getMenuList(7_000)).containsExactly(김치볶음밥.getName() , 소불고기김밥.getName()); } // 7_000원으로 구매가능한 메뉴는 김치볶음밥, 소불고기김밥 이다.
재사용 불가 🙅
스트림을 선언해두고 재사용하려고 한다면
IllegalStateException
예외를 만나게 된다.java.lang.IllegalStateException: stream has already been operated upon or closed
이미 작동되었거나 종료됐기때문에 사용할 수 없다고 한다.
Stream Document를 보면 Stream은 재사용 할 수 없다고 나온다. 스트림은
BaseStream.close()
메서드를 갖고 있고AutoCloseable
을 상속한다. 하지만, 대부분의 Stream은 사용 후 close 할 필요가 없으며 IO자원을 사용하는 (ex> Files.lines(Path, Charset)) 경우에만 close가 필요하다고 말하고 있다.Most streams are backed by collections, arrays, or generating functions, which require no special resource management. (If a stream does require closing, it can be declared as a resource in a try-with-resources statement.)
대부분의 경우는 필요없다고 명시하지만 그래도 재사용은 안된다. 그냥 규칙인 것 같다.
StackOverflow에도 Stream 재사용 방법에 대한 질문이 있었는데, 해결책으로 Supplier를 이용하는 방법을 제안하고 있었다. ( 좋은방법인지는 모르겠다. 결국 stream을 매번 만들어서 사용함 )
'Java' 카테고리의 다른 글
자바 - SRP (Single Responsibility Principle, 단일책임원칙) (0) 2023.11.22 자바 - OCP (Open Closed Principle / 개방-폐쇄원칙) (0) 2023.11.22 BufferedReader, BufferedWriter (0) 2021.05.21 json을 자바 객체로 변환하기 (0) 2021.05.20 visualVM으로 remote host 모니터링하기 (0) 2021.05.17