본문 바로가기

프로그래밍/자바

[자바/기본] Stream 사용하는법 (Feat. Java)

728x90
반응형
SMALL
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 라는 함수형 인터페이스를 사용한다.
    • 즉, 람다식으로도 표현이 가능하다.
     

 

출처 : https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

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() 의 사용법에 대해서 알게 되었다.

출처 : https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

  • sorted() 안에 매개변수가 없다면
    • 사용자 지정 비교를 기반으로 정렬
  • Comparator 가 있다면 
    • Comparator를 통해서 정렬 할 수 있다.
    • 아래와 같은 방법으로 지정되어 있는 비교를 역순으로 사용 할 수도 있고, 위의 예시처럼 comparing 메소드를 사용하여 객체의 특정 필드의 값을 가져와서 비교할 수도 있다.
sorted(Comparator.reverseOrder());

 


 

728x90
반응형
LIST