728x90
반응형
SMALL
- 이전 글(Stream 이란)에 이어서 Stream의 여러가지 메소드 들을 사용해 보고자 한다.
public class Customer {
String name;
int age;
public Customer(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return String.format("[name:%s, age:%d]", name, age);
}
} // end Customer
- 위와 같은 객체를 만들어서 Stream으로 사용해보고자 한다.
reduce()
- reduce() 연산은 두개의 스트림의 데이터를 전달 받아 연산을 진행한다.
- 하나의 결과값을 리턴한다.
- 공식 문서를 보면 BinaryOperator 및 BiFunction 라는 함수형 인터페이스를 사용한다.
- 즉, 람다식으로도 표현이 가능하다.
int [] arr = {1, 2, 3, 4, 5}; // 배열을 하나 선언
System.out.println(Arrays.stream(arr) // IntStream
.reduce((a, b) -> a + b) // OptionalInt[15]
);
- 위의 코드의 결과 값과 공식문서 발췌 한것을 확인 해보면 reduce 연산에서 Optional<T> 의 결과를 반환하는 것을 알 수 있다.
System.out.println(Arrays.stream(arr)
.reduce(100, (a, b) -> a + b) //115
);
- 공식 문서에서 identity로 구분 되어있는 것을 확인 하면 100에서 부터 15를 더한 115를 반환하는 것을 볼 수 있다.
- 이 identity 위치에 있는 매개변수를 우리는 초기값이라고 부르며 처음 지정되는 초기값의 타입을 reduce연산자가 반환한다고 볼 수 있다.
- 초기 값이 있을 때!!!!!
예시
List<Customer> personList = List.of(
new Customer("zayson", 28),
new Customer("chaeyoung", 26),
new Customer("maeng", 30)
);
- 맨 위에서 선언한 Customer 객체를 List에 담아서 Stream 을 사용해보고자 한다.
// 나이가 28이하인 사람들의 나이의 합
var sum = personList.stream() //Stream<Customer>
.filter(o -> o.getAge() <= 28) // filter 중간연산을 통해 나이가 28이하인 사람들 filter
.mapToInt(Customer::getAge) // filter를 통해 걸러진 Customer들의 getAge를 통해
// Customer들의 나이로만 이루어진 IntStream 으로 변환,
.reduce((o1, o2) -> o1 + o2) // reduce연산의 초기값이 없기 때문에 OptionalInt
.getAsInt(); // OptionalInt의 int 값, Optional의 .get()의 행동
System.out.println("나이 합 = " + sum); // 나이 합 = 54
- 위와 같이 중간 연산과 결과 연산을 적절히 구상하여 원하는 값을 가져올 수 있다.
- Optional<T> 에 대해서는 이글을 참조 [Optional 이란]
더 다양한 실습
TravelCustomer {
private String name; //이름
private int age; //나이
private int price; //가격
public TravelCustomer(String name, int age, int price) {
this.name = name;
this.age = age;
this.price = price;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getPrice() {
return price;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setPrice(int price) {
this.price = price;
}
public String toString() {
return "name: " + name + "age: " + age + "price: " + price;
}
- 위의 객체로 여러가지 stream을 사용해보고자 한다.
기본 세팅
TravelCustomer customerLee = new TravelCustomer("이순신", 40, 100);
TravelCustomer customerKim = new TravelCustomer("김유신", 20, 100);
TravelCustomer customerHong = new TravelCustomer("홍길동", 13, 50);
List<TravelCustomer> customerList = new ArrayList<>();
customerList.add(customerLee);
customerList.add(customerKim);
customerList.add(customerHong);
- customerList 를 stream으로 사용하여 원하는 값을 가져와 보는 연습
// 이름을 추가된 순서대로 출력
customerList.stream()
.forEach(c -> System.out.println(c.getName()));
// 총 여행 비용
var sum = customerList.stream() //Stream<TravelCustomer>
.mapToInt(c -> c.getPrice()) //IntStream
.reduce(0, (prev, cur) -> prev+cur);
System.out.println("sum = " + sum);
// 20세 이상 의 이름을 정렬하여 출력
customerList.stream()
.filter(c -> c.getAge()>=20)
.sorted(Comparator.comparing(TravelCustomer::getName))
.forEach(c -> System.out.println(c.getName()));
- 추가적으로 sorted() 의 사용법에 대해서 알게 되었다.
- sorted() 안에 매개변수가 없다면
- 사용자 지정 비교를 기반으로 정렬
- Comparator 가 있다면
- Comparator를 통해서 정렬 할 수 있다.
- 아래와 같은 방법으로 지정되어 있는 비교를 역순으로 사용 할 수도 있고, 위의 예시처럼 comparing 메소드를 사용하여 객체의 특정 필드의 값을 가져와서 비교할 수도 있다.
sorted(Comparator.reverseOrder());
728x90
반응형
LIST
'프로그래밍 > 자바' 카테고리의 다른 글
[자바/기본] ArrayList 란? (0) | 2024.02.23 |
---|---|
[자바/기본] Stream 이란? (0) | 2024.02.20 |
[자바/기본] Optional 이란? (0) | 2024.02.19 |
[자바/기본] 람다식 (Lambda) 란? (0) | 2024.02.16 |
[자바/기본] 내부 클래스(InnerClass) (0) | 2024.02.14 |