중간연산

스트림은 마치 데이터베이스에 질의를 하는 것과 같은 느낌, 중간 연산과 최종 연산으로 분류할 수 있으며 중간 연산은 연속해서 연결할 수 있다. 반면 최종 연산은 한번만 가능하다.

  1. 지연된 연산, 최종 연산이 수행되기 전까지 중간 연산은 수행되지 않는다.

skip(), limit() 자르기

class StreamTest {

    @Test
    public void 자르기() {
        // 1 ~ 9 까지 배열 생성
        int[] one2nine = IntStream.range(1, 10).toArray();
        assertThat(one2nine).isEqualTo(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9});

        // 3번째 요소까지 스킵, 그 후 두개만
        int[] four2five = Arrays.stream(one2nine)
                .skip(3)
                .limit(2)
                .toArray();
        assertThat(four2five).isEqualTo(new int[]{4, 5});

        // 소스에서 처음 5개만
        int[] one2five = Arrays.stream(one2nine).limit(5).toArray();
        assertThat(one2five).isEqualTo(new int[]{1, 2, 3, 4, 5});
    }
}

filter(), distinct() 거르기

class StreamTest {
    @Test
    public void 거르기() {
        int[] numbers = new int[]{1, 1, 2, 2, 4, 5, 5, 7, 9};

        // 짝수만
        // Stream<T> filter(Predicate<T> predicate);
        int[] evenNumbers = Arrays.stream(numbers)
                .filter(v -> v % 2 == 0)
                .toArray();
        assertThat(evenNumbers).isEqualTo(new int[]{2, 2, 4});

        // 중복제거
        // Stream<T> distinct()
        int[] distinctNumbers = Arrays.stream(numbers)
                .distinct()
                .toArray();
        assertThat(distinctNumbers).isEqualTo(new int[]{1, 2, 4, 5, 7, 9});
    }
}

sorted() 정렬

Stream<T> sorted();
Stream<T> sorted(Comparator<? super T>comparator);

Comparator 대신 int값을 반환하는 람다식을 사용하는 것도 가능함, 파라미터가 없는 매서드는 스트림을 기본정렬한다. 단, 스트림의 요소가 Comparable을 구현하지 않았다면 예외가 발생한다.

Comparator는 많은 API가 있지만 가장 기본적인 메서드는 아래와 같다.

comparing(Function<T, U> keyExtractor);
comparing(Function<T, U> keyExtractor,Comparator<U> keyComparator);

스트림의 요소가 comparable을 구현했을 경우 파라미터가 한개인 메서드를 사용하고, 그렇지 않은경우는 Comparator를 지정한다. 기본형의 경우 comparing() 대신 comparing기본형()을
사용한다. 정렬 조건을 추가할 때는 thenComparing()을 사용한다.

학생스트림을 학년순, 반순, 성적으로 정렬하는 방법은 아래와 같다.

Arrays.stream(stuArr).sorted(Comparator.<Student>comparingInt(v->v.getHak())
                .thenComparingInt(v->v.getBan())
                .thenComparingInt(v->v.getScore())
).forEach(System.out::println);

map()

스트림의 요소에서 원하는 값만 뽑아내거나 특정 형태로 변환해야 할때 사용한다. mapToInt, mapToDouble, mapToLong등 기본형 스트림으로 변환하는
메서드도 있다.

mapToInt의 경우 IntStream이 반환되는데 count()만 지원하던 Stream과 달리 기본형스트림은 숫자를 다루는데 편리한 메서드들을 제공한다.
아래의 메서드는 최종연산으로 호출 후에는 스트림이 닫힌다.

sum()
average()
max()
min()

위의 네가지 결과를 얻으려면 스트림을 네번 생성해야되는데 그 귀찮음을 방지한 summaryStatistics() 라는 메서드가 제공된다.

@Test
public void 써머리(){
  IntSummaryStatistics scoreStat = Arrays.stream(stuArr).mapToInt(v -> v.getScore()).summaryStatistics();

  log.info(String.valueOf(scoreStat.getSum()));
  log.info(String.valueOf(scoreStat.getMax()));
  log.info(String.valueOf(scoreStat.getMin()));
  log.info(String.valueOf(scoreStat.getAverage()));
  log.info(String.valueOf(scoreStat.getCount()));
}

peek()

연산과 연산 사이에 올바르게 처리되었는지 확인하고 싶을때 사용한다. foreach와 달리 스트림의 요소를 소모하지 않기때문에
중간연산들 사이에 넣어도 문제가 되지 않는다.

flatMap()

스트림의 요소가 배열이거나, map의 연산결과가 배열일 경우, 즉 스트림의 타입이 Stream<T[]>의 경우 Stream로 다룰 수 있도록 한다.

  1. 스트림의 요소가 배열일때, map의 연산결과가 배열일때
  2. 그 배열에서 모든 요소를 꺼내 하나의 스트림으로 감쌀때
Stream<String[]> -> Stream<String>

'Main > Java' 카테고리의 다른 글

[JAVA] Stream  (0) 2021.03.30
[JAVA] 람다식 기본  (0) 2021.03.30
[JAVA] Stream skip(), limit() 사용법  (0) 2021.03.17
[JAVA] 리눅스 자바 한글 폰트 설정  (0) 2020.10.20
[JAVA] PNG 파일에 문자열 삽입하기  (2) 2020.10.14

+ Recent posts