stream

OneTwoThree·2023년 6월 18일
0

자바

목록 보기
9/19

출처 : 열혈 java 프로그래밍


      int[] arr = {1,2,3,4,5};

      int sum = Arrays.stream(arr) //스트림 생성
                      .filter(n -> n%2==1) // filter 통과 
                              .sum(); // sum 통과, 결과 반환 

      System.out.println(sum);
  • Arrays 클래스에는 stream이라는 메소드가 다수 정의되어 있음
  • 배열을 대상으로 stream을 생성할 때 호출하는 메소드임
  • 스트림 : 데이터의 복사본(중간,최종 연산을 수행하기 좋게 배치된)
  • filter와 sum은 IntStream의 메소드
  • filter가 중간연산, sum이 최종연산
  • 스트림의 연산은 지연 처리 방식으로 동작함
  • 최종연산(sum)을 해야 중간연산(filter)의 결과가 스트림에 반영됨

스트림 생성방법

배열

Arrays 클래스의 메소드
public static <T> Stream<T> stream(T[] array)

import java.util.*;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args){
        String[] arr = {"김","나","박","이"};
        Stream<String> s = Arrays.stream(arr);
        s.forEach(singer->System.out.println(singer));
        }
}
  • 배열은 Arrays.stream(배열명) 으로 스트림을 생성할 수 있음
  • forEach는 스트림의 인스턴스 메소드도 있으며 최종연산에 해당함
import java.util.*;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        String[] arr = {"김", "나", "박", "이"};
        Arrays.stream(arr)
                .forEach(singer -> System.out.println(singer));
    }
}
  • 보편적인 형태는 위와 같음
  • String이나 기본 자료형이나 똑같이 하면됨

컬렉션 인스턴스

import java.util.*;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("김","나","박","이");
        list.stream()
                .forEach(singer->System.out.println(singer));
    }
}
  • 컬렉션 프레임워크의 stream() 메소드를 호출해주면 됨

  • 스트림을 생성했으면 스트림에 중간 연산과 최종 연산을 할 수 있음
  • 필터링과 매핑은 배열 스트림인지 컬렉션 인스턴스 스트림인지 상관 없이 적용 가능한 연산들임

스트림 직접 생성

Stream.of(11,22,33,44)
Stream.of("a","b","c")
와 같이 스트림을 직접 생성할 수 있다

기본 타입 스트림

스트림은 Stream<T> 인터페이스이므로 기본 타입이 올 수가 없어서 DoubleStream IntStream LongStream 이 정의되어 있다.
Instream.of(1,2,3) 으로 Stream<Integer>가 아닌 int 형 스트림 IntStream을 생성할 수 있다.
IntStream의 경우 IntStream.range(5,8)로 5,6,7 에 해당하는 스트림을 만들 수 있다.

스트림 연결

두 개의 스트림을 concat으로 연결할 수 있다.
Stream.concat(s1,s2)

중간연산

필터링

필터링은 스트림을 구성하는 데이터 중 일부를 조건에 따라 걸러내는 것이다.
Stream<T> filter(Predicate<? super T> predicate)
매개변수가 Predicate 형이다. 따라서 Predicate의 boolean test(T t) 를 구현하는 람다식을 인자로 전달해야 한다.
filter는 스트림 데이터를 하나씩 인자로 전달하면서 test를 호출한다.
true를 반환하면 해당 데이터를 스트림에 남긴다. false를 반환하면 해당 데이터를 스트림에서 버린다.

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
        list.stream()
                .filter(a->a%2==0)
                .forEach(a->System.out.println(a));

    }
}

맵핑

맵핑도 필터링과 마찬가지로 중간 연산이다.
맵핑은 스트림의 데이터 형이 달라진다는 특징이 있다.

import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("love","dream","car"));
        list.stream()
                .map(a->a.length()) // 매핑 
                .forEach(a->System.out.println(a));

    }
}

전달하는 람다식에 의해 반환되는 값을 모아 새로운 스트림을 생성한다.


필터링 후 맵핑을 진행하는 등 중간 연산을 두번 이상 진행할 수 있다.

import java.util.*;

public class Main {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6,7,8,9,10};
        int sum = Arrays.stream(arr)
                .filter(i->i%2==0)
                .mapToObj(i->String.valueOf(i))
                .mapToInt(s->s.length())
                .sum();
        System.out.println(sum);
    }
}
  • map은 int를 Integer로 오토 박싱해준다.
  • 기본 자료형을 반환하는 경우를 위해 다음 메소드들도 있다
    mapToInt mapToLong mapToDouble
  • sum으로 마지막에 합을 구했다

정렬

Stream<T> sorted(Comparator<? super T> comparator)
Stream<T> sorted()
정렬 기준 메소드를 정하는 방법은 동일하다

import java.util.*;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
        list.stream()
                .sorted((a,b)->b-a)
                .forEach(i->System.out.println(i));
    }
}

루핑

foreach는 스트림을 이루는 모든 데이터를 대상으로 특정 연산을 진행한다. 하지만 이것은 최종연산이다. 중간연산에서는 peek를 사용하면 된다.

최종연산

참고하면 좋은 링크
sum
count
average
min
max
forEach
allMatch(Predicate<? super T> predicate
anyMatch(Predicate<? super T> predicate
noneMatch(Predicate<? super T> predicate
findAny
findFirst

  • findAny와 findFirst는 Optional로 반환함
import java.util.*;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
        Optional<Integer> any = list.stream()
                .sorted((a, b) -> b - a)
                .findAny();
        System.out.println("any.get() = " + any.get());
    }
}

0개의 댓글