본문 바로가기
슬기로운 자바 개발자 생활/Java more

자바 스트림 Java stream 01

by 슬기로운 동네 형 2023. 5. 28.
반응형

Modern java stream 01

modern jacva in action

 이제야 스트림을 제대로 해보자는 생각이 들어 책을 구입하고 차근차근 예제를 따라 해 보는 중이다.

 다른 이들보다 재능이 적다는 사실을 잊고 무작정 spring webflux나 reactive, RxJava 공부를 했었는데, 기초가 중요하다는 사실을 다시 깨달았다.

 모던 자바 인 액션을 도서관에서 빌려와서 몇 번 대충 보고 반납했었는데 곁에 두고 익힐고 활용할 수 있을 수준이 될 때까지의 실력 향상을 도모하고자 구입했다.  10년 만에 구입하는 프로그래밍 책.

 

 오늘은 스트림 기본 공부

1. Dish.class 는 기본 vo객체.

package chaprer02;

import java.util.Arrays;
import java.util.List;

public class Dish {

  private final String name;
  private final boolean vegetarian;
  private final int calories;
  private final Type type;

  public Dish(String name, boolean vegetarian, int calories, Type type) {
    this.name = name;
    this.vegetarian = vegetarian;
    this.calories = calories;
    this.type = type;
  }

  public String getName() {
    return name;
  }

  public boolean isVegetarian() {
    return vegetarian;
  }

  public int getCalories() {
    return calories;
  }

  public Type getType() {
    return type;
  }

  public enum Type {
    MEAT,
    FISH,
    OTHER
  }

  @Override
  public String toString() {
    return "Dish{" +
            "name='" + name + '\'' +
            ", vegetarian=" + vegetarian +
            ", calories=" + calories +
            ", type=" + type +
            '}';
  }

  public static final List<Dish> menu = Arrays.asList(
      new Dish("pork", false, 800, Type.MEAT),
      new Dish("beef", false, 700, Type.MEAT),
      new Dish("chicken", false, 400, Type.MEAT),
      new Dish("french fries", true, 530, Type.OTHER),
      new Dish("rice", true, 350, Type.OTHER),
      new Dish("season fruit", true, 120, Type.OTHER),
      new Dish("pizza", true, 550, Type.OTHER),
      new Dish("prawns", false, 400, Type.FISH),
      new Dish("salmon", false, 450, Type.FISH)
  );

}

 

2. Edu0404.class 스트림 구현.

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Edu0404 {
    public static void main(String[] args) {

        List<String> names = Dish.menu.stream()
                .filter(dish -> dish.getCalories() > 300)
                .map(Dish::getName)
                .limit(3)
                .collect(Collectors.toList());
        System.out.println(names.toString());
    }
}

Dish.menu.stream() 연산은 기본 문법과도 같다. 이렇게 시작한다.

 

1. filter 연산은 Dish.menu 리스트 중에 칼로리 300 이상인 데이터를 필터링한다.

Stream<T> filter(Predicate<? super T> predicate);

Returns a stream consisting of the elements of this stream that match the given predicate.

boolean 형태로 프로그래머가 리턴 하고 싶은 지정된 조건자와 일치하는 정보(스트림)를 반환한다.

 

2. map 연산은 1번 연산의 결과로 나온 것들 중 getName 메서드를 이용해서 names에 저장한다.

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

Returns a stream consisting of the results of applying the given function to the elements of this stream.

주어진 함수를 적용해 인자로 받은 스트림을 리턴한다.

예제의 주어진 함수란 Dish 클래스의 getName.

 

3.limit 상위 3개만 리턴한다. maxSize...

Stream<T> limit(long maxSize);

Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.

지정된 MaxSize 만큼의 스트림 정보를 반환.

 

4. collect 최종연산

스트림을 리듀스 해서 리스트 맵, 정수 형식의 컬렉션을 만든다. (컬렉터는 따로 더 포스팅할 계획)


3. 어떤 일들이 벌어지는 쉽게 확인해 본다.

        List<String> names02 = Dish.menu.stream()
                .filter(dish ->{
                    System.out.println("filtering : " + dish.toString());
                    return dish.getCalories() > 300;
                })
                .map(dish -> {
                    System.out.println("mapping : " + dish.toString());
                    return dish.getName();
                })
                .limit(3)
                .collect(Collectors.toList());
                
                System.out.println(names02);

 실제 운영 환경에서는 디버그나 프린트 메서드는 추가하지 않는 것이 당연하다.

 하지만 출력문 덕분에 프로그램 실행 과정을 쉽게 확인할 수 있으므로 학습용으로 매우 좋은 기법이다.

 

모던 자바 인 액션

 

반응형

댓글