공부/JAVA
[Java] 스트림 - 스트림의 최종 연산
raptorhs
2024. 7. 8. 15:53
forEach()메서드는 대표적인 최종 연산자입니다.
스트림에는 forEach() 메서드 외에도 다양한 최종 연산자들이 존재합니다.
기본 집계(sum() , count() , average(), max() , min())
숫자와 관련된 기본적인 집계의 경우에는 대부분 최종 연산자라고 생각해도 됩니다.
package Stream;
import java.util.Arrays;
import java.util.OptionalDouble;
public class TerminalOperationExample {
public static void main(String[] args) {
//int형 배열 생성
int[] intArray = {1, 2, 3, 4, 5};
//카운팅
long count = Arrays.stream(intArray).count();
System.out.println("intArr의 전체 요소 개수 " + count);
//합계
long sum = Arrays.stream(intArray).sum();
System.out.println("intArr의 전체 요소 합 " + sum);
// double averatge = Arrays.stream(intArray).average().getAsDouble();
OptionalDouble average = Arrays.stream(intArray).average();
System.out.println(average);
//기본형으로 변환
double result = average.getAsDouble();
System.out.println("전체 요소의 평균값 " + result);
//최대값
int max = Arrays.stream(intArray).max().getAsInt();
System.out.println("최대값 " + max);
//최소값
int min = Arrays.stream(intArray).min().getAsInt();
System.out.println("최소값 " + min);
//배열의 첫번째 요소
int first = Arrays.stream(intArray).findFirst().getAsInt();
System.out.println( "배열의 첫 번째 요소 " + first);
}
}
average() 최종연산자가 반환하는 값의 타입이 OptionalDouble, 즉 래퍼 클래스 객체로 되어있기 때문에 우리가 원하는 기본형으로 변환하는 과정이 한 번 더 필요하다는 사실이 중요합니다. 이름에서 알 수 있듯이, getAsDouble()과 getAsInt()는 객체로 반환되는 값을 다시 기본형으로 변환하기 위해 사용되는 메서드로 스트림 파이프라인과는 관계가 없다는 사실을 기억하도록 합시다.
매칭(allMatch(), anyMatch(), noneMatch() )
match()메서드는 3가지 종류가 있습니다.
allMatch() - 모든 요소가 조건을 만족하는지 여부 판단
noneMatch() - 모든 요소가 조건을 만족하지 않는지 여부 판단
anyMatch() - 하나라도 조건을 만족하는 요소가 있는지 여부 판단
import java.util.Arrays;
public class TerminalOperationExample {
public static void main(String[] args) throws Exception {
// int형 배열 생성
int[] intArray = {2,4,6};
// allMatch()
boolean result = Arrays.stream(intArray).allMatch(element-> element % 2 == 0);
System.out.println("요소 모두 2의 배수인가요? " + result);
// anyMatch()
result = Arrays.stream(intArray).anyMatch(element-> element % 3 == 0);
System.out.println("요소 중 하나라도 3의 배수가 있나요? " + result);
// noneMatch()
result = Arrays.stream(intArray).noneMatch(element -> element % 3 == 0);
System.out.println("요소 중 3의 배수가 하나도 없나요? " + result);
}
}
// 출력값
요소 모두 2의 배수인가요? true
요소 중 하나라도 3의 배수가 있나요? true
요소 중 3의 배수가 하나도 없나요? false
요소 소모(reduce())
reduce()최종 연산자는 스트림의 요소를 줄여나가면서 연산을 수행하고 최종적인 결과를 반환합니다.
package Stream;
import java.util.Arrays;
import java.util.OptionalDouble;
public class TerminalOperationExample {
public static void main(String[] args) {
//int형 배열 생성
int[] intArray = {1,2,3,4,5};
//sum()
long sum = Arrays.stream(intArray).sum();
System.out.println("intArray 전체 요소 합: " + sum);
//초기값이 없는 reduce()
int sum1 = Arrays.stream(intArray)
.map(element -> element * 2)
.reduce((a,b) -> a+ b)
.getAsInt();
System.out.println("초기값이 없는 reduce(): " + sum1);
//초기값이 있는 reduce()
int sum2 = Arrays.stream(intArray)
.map(element -> element * 2)
.reduce(5, (a,b)-> a+b);
System.out.println("초기값이 있는 reduce(): " + sum2);
}
}
//출력값
intArray 전체 요소 합: 15
초기값이 없는 reduce(): 30
초기값이 있는 reduce(): 35
요소 수집(collect())
collect()메서드는 Collector인터페이스 타입의 인자를 받아서 처리할 수 있습니다.
좀 더 구체적으로, 스트림의 요소들을 List, Set, Map 등 다른 타입의 결과로 수집하고 싶은 경우에 collect() 메서드를 유용하게 사용할 수 있습니다.
package Stream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
public class TerminalOperationExample {
public static void main(String[] args) {
//Student 객체로 구성된 배열 리스트 생성
List<Student> totalList = Arrays.asList(
new Student("김코딩", 100, Student.Gender.Male),
new Student("박해커",80, Student.Gender.Male),
new Student("이자바",90, Student.Gender.Female),
new Student("나미녀",60, Student.Gender.Female)
);
//스트림 연산 결과를 Map으로 반환
Map<String,Integer> maleMap = totalList.stream()
.filter(s -> s.getGender() == Student.Gender.Male)
.collect(Collectors.toMap(
student -> student.getName(), // Key
student -> student.getScore() // Value
));
System.out.println(maleMap);
}
}
class Student {
public enum Gender {Male, Female};
private String name;
private int score;
private Gender gender;
public Student(String name, int score, Gender gender) {
this.name = name;
this.score = score;
this.gender = gender;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
public Gender getGender() {
return gender;
}
}