<< Back
blog 프로그래밍

자바 :: 3.자바 스트림API 최종연산

이미지출처: medium.com, Charles Scalfani


최종 연산 메서드

대표적인 유형과 메서드는 다음과 같습니다. 대부분의 최종연산은 결과값만 리턴되므로 별도의 출력문을 연결해 사용하기 어렵습니다. 각 메서드 설명에 사용된 예제에서는 주석으로 결과를 표기 했으며 일부 가능한 경우만 직접 출력하고 있습니다.

1) forEach()

스트림의 요소들을 순환 하면서 반복해서 처리해야 하는 경우 사용 합니다.

intList.stream().forEach(System.out::println); // 1,2,3
intList.stream().forEach(x -> System.out.printf("%d : %d\n",x,x*x)); // 1,4,9

2) reduce()

map 과 비슷하게 동작하지만 개별연산이 아니라 누적연산이 이루어진다는 차이가 있습니다.

두개의 인자 즉 n, n+1 을 가지며 연산결과는 n 이 되고 다시 다음 요소와 연산을 하게 됩니다. 즉 1,2 번째 요소를 연산하고 그 결과와 3번째 요소를 연산하는 식입니다.

int sum = intList.stream().reduce((a,b) -> a+b).get();
System.out.println("sum: "+sum);  // 6

3) findFirst(), findAny()

두 메서드는 스트림에서 지정한 첫번째 요소를 찾는 메서드 입니다.

보통 filter() 와 함께 사용되고 findAny() 는 parallelStream() 에서 병렬 처리시 가장 먼저 발견된 요소를 찾는 메서드로 결과는 스트림 원소의 정렬 순서와 상관 없습니다.

strList.stream().filter(s -> s.startsWith("H")).findFirst().ifPresent(System.out::println);  //Hwang
strList.parallelStream().filter(s -> s.startsWith("H")).findAny().ifPresent(System.out::println);  //Hwang or Hong

4) anyMatch(), allMatch(), noneMatch()

스트림의 요소중 특정 조건을 만족하는 요소를 검사하는 메서드

원소중 일부, 전체 혹은 일치하는 것이 없는 경우를 검사하고 boolean 값을 리턴합니다. noneMatch()의 경우 일치하는 것이 하나도 없을때 true.

boolean result1 = strList.stream().anyMatch(s -> s.startsWith("H"));  //true
boolean result2 = strList.stream().allMatch(s -> s.startsWith("H"));  //false
boolean result3 = strList.stream().noneMatch(s -> s.startsWith("T")); //true
System.out.printf("%b, %b, %b",result1,result2, result3);

5) count(), min(), max()

스트림의 원소들로 부터 전체 개수, 최소값, 최대값을 구하기 위한 메서드 입니다.

min(), max() 의 경우 Comparator 를 인자로 요구 하고 있으므로 기본 Comparator 들을 사용하거나 직접 람다 표현식으로 구현해야 합니다.

intList.stream().count();	// 3
intList.stream().filter(n -> n !=2 ).count(); 	// 2
intList.stream().min(Integer::compare).ifPresent(System.out::println);; 		// 1
intList.stream().max(Integer::compareUnsigned).ifPresent(System.out::println);; // 3

strList.stream().count();	// 3
strList.stream().min(String::compareToIgnoreCase).ifPresent(System.out::println);	// Hong
strList.stream().max(String::compareTo).ifPresent(System.out::println);	// Kang

6) sum(), average()

스트림 원소들의 합계를 구하거나 평균을 구하는 메서드 입니다.

reduce() 와 map() 을 이용해도 구현이 가능 합니다. 이경우 리턴값이 옵셔널이기 때문에 ifPresent()를 이용해 값을 출력할 수 있습니다.

intList.stream().mapToInt(Integer::intValue).sum();	// 6
intList.stream().reduce((a,b) -> a+b).ifPresent(System.out::println); // 6

intList.stream().mapToInt(Integer::intValue).average();	// 2
intList.stream().reduce((a,b) -> a+b).map(n -> n/intList.size()).ifPresent(System.out::println); // 2

7) collect()

스트림의 결과를 모으기 위한 메서드로 Collectors 객체에 구현된 방법에 따라 처리하는 메서드 입니다.

최종 처리후 데이터를 변환하는 경우가 많기 때문에 잘 알아 두어야 합니다. 용도별로 사용할 수 있는 Collectors 의 메서드는 기능별로 다음과 같습니다.

strList.stream().map(String::toUpperCase).collect(Collectors.joining("/"));	 	// Hwang/Hong/Kang
strList.stream().collect(Collectors.toMap(k -> k, v -> v.length()));	// {Hong=4, Hwang=5, Kang=4}

intList.stream().collect(Collectors.counting());
intList.stream().collect(Collectors.maxBy(Integer::compare));
intList.stream().collect(Collectors.reducing((a,b) -> a+b));	// 6
intList.stream().collect(Collectors.summarizingInt(x -> x));	//IntSummaryStatistics{count=3, sum=6, min=1, average=2.000000, max=3}

Map<Boolean, List<String>> group = strList.stream().collect(Collectors.groupingBy(s -> s.startsWith("H")));
group.get(true).forEach(System.out::println);  // Hwang, Hong

Map<Boolean, List<String>> partition = strList.stream().collect(Collectors.partitioningBy(s -> s.startsWith("H")));
partition.get(true).stream().forEach(System.out::println);  // Hwang, Hong
<< Back