Dev./java

[Java] 스트림(Stream)

인쥭 2020. 10. 14. 10:08
반응형

다음의 링크로부터 훨씬 자세한 내용을 확인하실 수 있습니다 : 

 

Java 스트림 Stream (1) 총정리

이번 포스트에서는 Java 8의 스트림(Stream)을 살펴봅니다. 총 두 개의 포스트로, 기본적인 내용을 총정리하는 이번 포스트와 좀 더 고급 내용을 다루는 다음 포스트로 나뉘어져 있습니다. Java 스트�

futurecreator.github.io

 

자바(Java) 8: 람다식에서 콜론 두개 (:: - 이중 콜론 연산자, 메소드 참조 표현식)의 용도와 사용법

자바8 람다식: 자바(Java): 람다식 (Lambda Expression) 기초 (Java 8 이상)   콜론 두개 (:: - 이중 콜론 연산자)의 정식 명칭은 메소드 참조 표현식(method reference expression)이며, 결론부터 말하자면 람다식에

yoonbumtae.com

0. Collection과 stream 메소드

  • Java에서 제공하는 컬렉션들의 조상인 Collection에는 아래와 같이 Stream 메소드가 정의되어 있다.
  • 따라서 인터페이스인 Collection을 구현한 모든 클래스는 stream()을 통해 스트림을 생성할 수 있다.
public interface Collection<E> extends Iterable<E> {
  /*
  중략
  */
  default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
  }
  /*
  후략
  */
}

 

1. Stream이란?

  • Java 8에 Stream이 도입되기 전에는 Collection으로부터 구현된 인스턴스를 다루기 위해 for / forEach문을 사용해야만 했다.
    • 이러한 방식은 코드가 복잡해질수록 코드의 양이 많아지고 가독성이 떨어지기 쉬웠다고 함.
  • 스트림은 Collection 인스턴스에 여러 함수를 조합하여 원하는 결과를 필터링하거나 가공하는 방법을 제공한다.
    • 여러 함수의 조합에서 람다식을 사용하여 코드 양을 줄일 수 있으며, 보다 간결한 코딩을 가능케 한다. 때문에 스트림은 람다식과 밀접한 관련이 있다!

 

2. Stream 사용하기

  • Stream은 크게 세가지 단계로 나눠 생각해볼 수 있다.
    1. 생성 : Stream 인스턴스 생성
    2. 가공 : 필터링 / 매핑 등을 통한 중간 가공
    3. 결과 : 최종적으로 결과를 만들어 반환

i). 생성하기

// 배열 스트림
String[] tmpArray = new String[]{"a", "b", "c"};
Stream<String> tmpStream = Arrays.stream(tmpArray);
Stream<String> partOfTmpStream = Arrays.stream(tmpArray, 1, 2); // 배열의 일부만 사용

// 컬렉션 스트림
// 컬렉션 인터페이스를 구현한 Collection, List, Set 등은 .stream() 메소드를 통해 스트림을 만들 수 있다.
List<String> tmpList = Arrays.asList("a", "b", "c");
Stream<String> tmpStream = tmpList.stream();

// 빈 스트림
Stream<Object> tmpStream = Stream.empty();

 

ii). 가공하기

List<String> strList = Arrays.asList("abc", "bcd", "cde", "def", "efg");

// filter는 각 요소를 평가
Stream<Integer> tmpStream = strList.stream().filter(str -> str.contains("e"));

// map은 Stream 내부의 각 요소를 변환
Stream<Integer> tmpStream = strList.stream().map(String::toUpperCase);

 

iii). 결과 생성

// Collect는 종료 작업으로서 Collector 타입의 인자를 받아 처리

List<TmpClass> tmpList = Arrays.asList(
  new TmpClass("tmp0"),
  new TmpClass("tmp1"),
  new TmpClass("tmp2"),
  new TmpClass("tmp3")
);

// 아래의 Collectors.toList()는 tmpList의 Stream으로부터 getter를 활용한 리스트를 반환
List<String> toListTest =
  tmpList.stream()
    .map(TmpClass::getAttr)
    .collect(Collectors.toList());

 

 

번외. stream().map()을 통해 생성자의 매개변수가 하나인 DTO 생성하기

List<String> tmpStr = Arrays.asList("abc", "cde");

// TmpClass는 생성자의 매개변수가 하나이며, 아래의 두 내용은 같은 의미를 갖는다.
List<String> firstStr = tmpStr.stream()
  .map(x -> new TmpClass(x))
  .collect(Collectors.toList());

List<String> secondStr = tmpStr.stream()
  .map(TmpClass::new)
  .collect(Collectors.toList());