저번에 람다식에 대해서 포스팅 했을때에도 Stream이 연관이 있었고, 알고리즘 문제를 풀면서 다른 사람들의 풀이를 보면 Stream을 사용한 코드가 굉장히 자주 보였다.
그래서 이번 시간에는 자바에서 Stream이 무엇인지 알아보는 시간을 가져보려고 한다.
자바 8에서 추가된 스트림(Stream)은 기존 자바 I/O에서 나오는 InputStream, OutputStream과는 다른것으로
함수형 프로그램에서 단계적으로 정의된 계산을 처리하기 위한 인터페이스 이다.
Stream은 데이터의 흐름으로 배열 또는 컬렉션 인스턴스에 함수를 조합하여 원하는 결과를 필터링하고 가공된 결과를 손쉽게 처리할 수 있다.
Stream의 특징
->Stream을 이용하면 코드가 간결해지는 이유 중 하나는 '내부 반복' 때문이다. 기존에는 반복문을 사용하기 위해서 for이나 while 등과 같은 문법을 사용해야 했지만, stream에서는 그러한 반복 문법을 메소드 내부에 숨기고 있기 때문에, 보다 간결한 코드의 작성이 가능하다.
간단히 말하면 Stream은 함수형 인터페이스를 람다식으로 구현하여 내부 반복을 통해 데이터를 처리할 수 있도록 한 것이다.
스트림을 쓰지 않은 코드와 스트림을 사용한 코드를 비교해보겠다.
// 빨간색 사과 필터링
List<Apple> redApples = forEach(appleList, (Apple apple) -> apple.getColor().equals("RED"));
// 무게 순서대로 정렬
redApples.sort(Comparator.comparing(Apple::getWeight));
// 사과 고유번호 출력
List<Integer> redHeavyAppleUid = new ArrayList<>();
for (Apple apple : redApples)
redHeavyAppleUid.add(apple.getUidNum());
List<Integer> redHeavyAppleUid = appleList.stream()
.filter(apple -> apple.getColor().equals("RED")) // 빨간색 사과 필터링
.sorted(Comparator.comparing(Apple::getWeight)) // 무게 순서대로 정렬
.map(Apple::getUidNum).collect(Collectors.toList()); // 사과 고유번호 출력
확실히 간결하고 보기좋게 바뀐 것을 확인할 수 있다.
이번에는 stream().sorted() 메소드를 사용한 후, 원본 데이터가 바뀌었는지 확인해보았다.
원본 데이터는 정렬되지 않은 상태 그대로 유지가 되어 있음을 확인할 수 있었다.
Stream을 사용하는 이유
위와 같은 이유로 Stream을 적절히 활용하면 더욱 훌륭한 코드를 완성할 수 있다.
+Stream이 for문을 사용한 반복문보다 속도가 느리다고 한다. 하지만 코드가 깔끔해 지기 때문에 유지보수 측면에서 용이하기 때문에, 앞으로 어떤 코드를 작성해야하는지 더욱 고민해봐야 할 필요성을 느낀다.
참고자료