본문 바로가기

JAVA

Lambda & Stream을 이용하여 특정 값보다 큰 값들만 조회하기

Lambda

Lambda란 인스턴스를 생성하지 않고 작성할 수 있는 익명함수!

  • 메서드는 클래스에 포함되어야 하기 때문에 번거로운 제약들이 많음 → 람다의 등장으로 메서드를 변수처럼 다루는 것이 가능 → 람다를 통해서 메서드가 1급 객체가 됨 (이를 통해 자바는 객체지향프로그래밍 뿐만 아닌 함수지향 프로그래밍도 가능)
    • 1급객체 : 메서드(함수)를 변수, 인자, 리턴값에 할당 가능한 것
  • 람다식은 사실 메서드가 아닌, 익명 클래스의 객체

사용법

  • 람다의 모든 매개변수 타입은 생략하는 것이 좋음
  • 매개변수가 하나라면 괄호도 생략  (a) -> a * a 이 아닌 a -> a * a

실체

(int a, int b) -> a > b ? a : b; 의 실제 모습은 아래와 같음 즉, 람다식은 익명 클래스의 객체

new Objcet() {
  int max(int a, int b) {
    return a > b ? a : b;
  }
}

 

Stream

연속적인 데이터들의 순회로, 여러 필터링, 변환과 같은 작업들을 할 수 있게 도와주는  자바의 API

  • 한번에 한개씩 만들어지는 연속적인 데이터 항목들의 모임
  • 프로그램들은 입력 스트림을 통해 데이터를 하나씩 읽고, 출력 스트림을 통해 한개씩 기록
  • 기존에 반복문과 조건문을 활용하여 만든 로직보다 각 단계별로 어떤 "무엇을" 수행할 것인지 확실하게 명시되어 있어 의도를 파악하기 좋음
  • 스트림은 데이터 소스를 변경하지 않음
  • 일회용임

 

특정 값보다 큰 값들만 조회하기

1.  첫 번째 시도

  • cannot resolve symbol “r” 에러
 public List<Double> getResult(int minimum){
        return this.results.stream()
                .filter( r > minimum)
                .collect(Collectors.toList());
    }

 

의문이 들었다.. 내가 찾아본 예시와 다를게 없었기 때문이다. 아래 예시랑 다를게 없다고 생각했는데 이건 정말 실행이 잘 됐기 때문이다.

void filterTest3() {
    List<Human> tmpHumans = humans.stream()
            .filter(h -> h.getMoney() > 2000)
            .collect(Collectors.toList());

 

2.  두 번째 시도

  • 아직 리스트 내부의 값들이 선언이 안되서 그런건가 싶어서 한번 값을 선언해보고 했는데 이것도 동일한 에러가 뜨면서 실행되지 않음
  • 아까와 동일한 cannot resolve symbol “r” 에러
List<Integer> ra = Arrays.asList(1, 2, 3, 4);

    public List<Integer> getResult(int minimum){
        List<Integer> filterdResults = this.ra.stream()
                .filter( r > minimum)
                .collect(Collectors.toList());

        return filterdResults;
    }

 

하지만...!! 아주 바보같은 실수를 하고 만 것이다...!!

다시 차분히 진정하고 비교해보니 람다 표현식에서 매개변수 값을 안넣어버린 것이다...!! (바보🙈)

매개변수는 안넣고 냅다 리턴만 해버리면 될리가 없지..!

 

3.  완성

이번엔 람다 표현식을 정확하게 썼더니 에러가 발생하지 않았다!

public String getResult(int minimum){
        String filterdResults =  this.results.stream()
                .filter( result -> result > minimum)
                .collect(Collectors.toList())
                .toString();
        
        return filterdResults;
    }

 

 

덕분에 람다식을 쓸 때 앞으로는 확실히 알 수 있을 것 같다!!

람다는  매개변수 -> 리턴 형식!