스트림의 최종 처리 메소드에 대해서 알아보자.
매칭(allMatch(), anyMatch(), noneMatch())
매칭 메소드는 최종처리시 요소들이 특정 조건에 만족하는지 Predicate<T> 를 사용하여 조사한다. 어려울것이 없다.
public static void main (String[] args){
int[] intArr = new int[]{1,3, 5};
boolean isAllEvenNum = Arrays.stream(intArr).allMatch(a->a%2==0);
boolean isThereEvenNum = Arrays.stream(intArr).anyMatch(a->a%2==0);
boolean isAllOddNum = Arrays.stream(intArr).noneMatch(a->a%2==0);
System.out.println("isAllEvenNum : " + isAllEvenNum ); // false
System.out.println("isThereEvenNum : " + isThereEvenNum ); // false
System.out.println("isAllOddNum : " + isAllOddNum ); // true
}
기본집계(sum(), count(), average(), max(), min())
스트림이 제공하는 기본 집계 함수들은 그 내용이 어려울 것은 없지만, 주의할 것이 있다. sum()을 제외하고는 집계 메소드들의 리턴값이 int, long, double 과 같은 primitive type이 아니라 Optional 클래스라는 것이다. 이 객체에서 값을 얻기 위해서는 get(), getAsDouble(), getAsLong()을 호출해주어야 한다.
public static void main (String[] args){
int[] intArr = new int[]{1,3, 5};
System.out.println(Arrays.stream(intArr)
.average()
.getAsDouble()); // print 3.0
int first = Arrays.stream(intArr)
.filter(s->s%3==0)
.findFirst() // 가장 첫번째 3의 배수를 찾아라
.getAsInt();
System.out.println(first); // print 3
}
Optional Class
optional class들은 단순히 집계값을 저장하는 것 뿐 아니라 , Default값을 설정 할 수도 있고 집계값을 처리하는 Consumer를 등록할수도 있다. 만약 리스트가 선언만 되어있고 값이 저장되어있지 않다고 가정해보자. 그러면 해당 리스트에 stream의 average 메소드를 호출하면 java.util.NoSuchElementException과 같은 에러가 발생할 것이다. 이러한 경우 사용할 수 있는게 Optional Class이다.
List<Integer> list = new ArrayList<>(); // list에 아직 값이 없는 상태
double avg = list.stream()
.mapToInt(Integer::intValue)
.average()
.getAsDouble(); // 해당 라인에서 에러 발생
위와 같은 사례는 아래와 같이 Optional 객체를 사용하여 해결할 수 있다.
public static void main (String[] args){
List<Integer> list = new ArrayList<>(); // list에 아직 값이 없는 상태
System.out.println("*****Sol using optional.isPresent() ");
OptionalDouble optional = list.stream()
.mapToInt(Integer::intValue)
.average();
if( optional.isPresent() ) System.out.println("optional.getAsDouble() : " + optional.getAsDouble());
else System.out.println("default : "+ 0.0 + "\n");
System.out.println("*****Sol using orElse");
double avg = list.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);
System.out.println("avg is : " + avg + "\n");
System.out.println("***** sol using ifPresent lamda");
list.stream()
.mapToInt(Integer::intValue)
.average()
.ifPresent(a-> System.out.println("avg is : " + a))
;
}
커스텀 집계 reduce()
스트림은 사용자가 집계를 커스터마이징하여 사용할 수 있도록 reduce 메소드를 제공한다. 이 reduce 메소드의 특징은 스트림에 요소가 없을 경우 default로 사용할 수 있도록 identity 매개값을 설정해줄 수 있다는 것이다. 그리고 이 identity와 함께 매개값으로 Operator 인터페이스를 넘겨주어야 한다.
public static class Car {
public String name;
public int price;
public Car (String name, int price){
this.name =name;
this.price = price;
}
public int getPrice() { return this.price ; }
}
public static void main (String[] args){
List<Car> carList = Arrays.asList(
new Car("차 1" , 15000),
new Car("차 2" , 20000)
);
int Sum = carList.stream()
.map(Car::getPrice)
.reduce(0, (a,b) -> a+b );
System.out.println("sum is : " + Sum); // print 35000
}
'Study > Java' 카테고리의 다른 글
MyBatis vs JPA (0) | 2022.06.20 |
---|---|
자바 기본서를 다시 읽다. 8 - 스트림의 중간처리 메소드 (0) | 2022.04.06 |
자바 기본서를 다시 읽다. 7 - 스트림의 개념과 파이프라인 (0) | 2022.04.05 |
자바 기본서를 다시 읽다. 6 - 메소드 참조 (0) | 2022.03.29 |
자바 기본서를 다시 읽다. 5 - 함수적 인터페이스의 Default Method (0) | 2022.03.27 |