JAVA/JAVA

스트림 Stream

호두밥 2021. 11. 7. 00:47

Stream 스트림

스트림은 자바 8부터 추가되었으며, 람다식을 이용해 컬랙션의 요소를 하나씩 함수적 프로그래밍으로 처리할 수 있도록 해주는 기능입니다.

ArrayList<Integer>의 값을 모두 합산하려고 한다면 반복문을 사용해야 합니다.

List<Integer> arrayList = Arrays.asList(1,2,3,4,5);
Integer sum = 0;
for(Integer a : arrayList){
	sum += a;
}

스트림을 사용하면 아래와 같이 값을 합산할 수 있습니다.

int sum1 = arrayList.stream().mapToInt(a->a).sum();

스트림의 특징

① 람다식을 이용해 요소를 처리합니다.

    람다식을 이용해 기능을 구현하거나, 메소드를 호출하여 컬랙션의 요소를 하나씩 처리할 수 있습니다.

② 병렬 처리할 수 있습니다.

    병렬 처리 스트림 parallelStream을 사용하면 작업을 여러개로 나누고, 결과를 자동으로 결합해서 최종 결과물을 생성합니다.

③ 중간처리와 최종처리를 할 수 있습니다.

   매핑, 필터링, 정렬의 중간처리와 반복, 카운팅, 평균, 총합등을 이용한 집계 처리(최종처리)를 수행할 수 있습니다. 예를 들어 컬랙션 요소 중 특정 조건에 부합하는 것을 선별하는 것을 중간처리, 선별된 요소의 갯수를 세는 것을 최종처리라고 할 수 있습니다.

 

중간처리 메소드

필터링 distinct(), filter()

특정 조건에 부합하는 요소를 걸러내는 기능을 수행합니다.

distinct()는 Object.equals메소드로 동일한 요소라고 판단되면 중복을 제거합니다.

filter(Predicate)는 Predicate가 true를 리턴하는 요소만 선별합니다.

 List<Integer> arrayList = Arrays.asList(1,2,3,4,4);
 arrayList.stream().distinct().forEach(a-> System.out.print(a));
1234
 List<Integer> arrayList = Arrays.asList(1,2,3,4,4);
 arrayList.stream().filter(a->a>2).forEach(a-> System.out.print(a));
344

매핑 flatMap(), Map(), asStream(), boxed()

flatMap()은 한 요소를 여러개의 요소로 바꾸어 새로운 Stream을 반환합니다.

List<String> arrayList = Arrays.asList("10:10","20:20");
arrayList.stream().flatMap(a-> Arrays.stream(a.split(":"))).forEach(System.out::print);
10102020

Map()은 요소를 다른 요소로 대체하여 새로운 Stream을 생성합니다.

 List<String> arrayList = Arrays.asList("001","002","003");
 arrayList.stream().mapToInt(Integer::parseInt).forEach(System.out::print);
123

asDoubleStream()은 int나 long을 받아 double로 반환하고, asLongStream()은 int를 받아 long으로 반환합니다.

 int[] arr = {1,2,3,4};
 Arrays.stream(arr).asDoubleStream().forEach(System.out::println);
1.0
2.0
3.0
4.0

boxed()는 int는 Integer로 long은 Long으로, double은 Double로 반환합니다.

int[] arr = {1,2,3,4};
Arrays.stream(arr).boxed()
	.forEach(a -> System.out.println("a.getClass() = " + a.getClass()));
a.getClass() = class java.lang.Integer
a.getClass() = class java.lang.Integer
a.getClass() = class java.lang.Integer
a.getClass() = class java.lang.Integer

정렬 sorted()

기준에 따라 정렬해주는 메소드로, Comparator를 매개변수로 받을 수도 있습니다.

 Arrays.asList(1,2,5,4,3).stream().sorted().forEach(System.out::print);
 System.out.println();
 Arrays.asList(1,2,5,4,3).stream().sorted((o1, o2) -> (o1-o2)*-1).forEach(System.out::print);
12345
54321

루핑 peek()

peek()은 최종처리 전 추가적으로 작업을 해주려고 할 때 사용하는 메소드입니다. peek이후에 최종처리 메소드를 추가해주지 않으면 동작하지 않습니다.

Stream.of("one", "two", "three", "four")
         .filter(e -> e.length() > 3)
         .peek(e -> System.out.println("Filtered value: " + e))
         .map(String::toUpperCase)
         .peek(e -> System.out.println("Mapped value: " + e))
         .collect(Collectors.toList());

 

최종처리 메소드

매칭 Match()

Match(Predicate)는 요소들이 특정 조건을 만족하는지 여부를 boolean으로 반환하는 메소드입니다.

allMatch(Predicate)는 모든 요소들이 조건을 만족하는지, anyMatch(Predicate)는 조건을 만족하는 요소가 한개라도 있는 지, noneMatch(Predicate)는 모든 요소들이 조건을 만족하지 않는지를 판단합니다.

boolean result = Arrays.asList(1,2,5,4,3).stream().allMatch(a->a>10);
System.out.println("result = " + result);
result = false

합계 sum(), count(), average(), max(), min()

int sum1 = arrayList.stream().mapToInt(a->a).sum();
int min = arrayList.stream().mapToInt(Integer::parseInt).min().getAsInt();

 

커스텀 합계 reduce()

합계하는 방식을 프로그램화 할 때 reduce(Operator)를 사용합니다. 값을 받으려면 get() 메소드를 사용해야 합니다.

int sum =  Arrays.asList(1,2,3,4,5,6,7,8,9)
                        .stream().reduce((a,b)->(a+b)/2).get();

reduce를 이용하면 요소가 null인 경우 default값을 지정할 수 있습니다. 아래는 null일 때는 0을 default값으로 지정한 코드입니다.

 Integer sum = integers.reduce(0, (a, b) -> a+b);

루핑 forEach()

forEach()는 요소 전체를 반복하는 메소드입니다.

 arrayList.stream().filter(a->a>2).forEach(a-> System.out.print(a));

수집 collect()

특정 조건을 만족하는 요소만 뽑아 새로운 컬랙션 만들기

List<Integer> arr = Arrays.asList(1,2,3,4,5,6,7,8,9);
List<Integer> sub = arr.stream().filter(a->a>5).collect(Collectors.toList());
System.out.println("sub.toString() = " + sub.toString());
sub.toString() = [6, 7, 8, 9]

특정 조건을 기준으로 그룹핑 하기

Map<Integer, List<Integer>> groups
= arr.stream().collect(Collectors.groupingBy(a->Math.floorMod(a,2)));
System.out.println("groups.toString() = " + groups.toString());
groups.toString() = {0=[2, 4, 6, 8], 1=[1, 3, 5, 7, 9]}

참조

신용권, 이것이 자바다, 한빛미디어

Oracle, Stream(Java Platfrom SE 8) , Java™ Platform Standard Ed. 8

 

 

 

'JAVA > JAVA' 카테고리의 다른 글

인터페이스  (0) 2021.11.30
Optional  (0) 2021.11.07
Comparator와 Comparable  (0) 2021.10.29
Lambda Expressions 람다식  (0) 2021.10.28
Collection 컬렉션  (0) 2021.10.25