Develope Story

2019-04-04 [java-study] java8 람다식

|

자바 람다식

람다식이란?

: 함수를 변수처럼 사용

  • 함수가 필요한 이유

    이급시민(구조체가 값의 구조를 자유롭게 전달 할 수 없음) -> 일급시민

장점

  • 불필요한 코드를 줄여줌

  • 가독성을 높여줌

    => 부정적인 입장도 있음.

  • 병렬 프로그래밍

  • 메소드로 행동방식을 전달

  • 성능

    => 부정적인 입장도 있음.

가독성 및 성능에 대한 부정적 입장 + 주의사항 - https://okky.kr/article/329818

단점

  • 람다식의 호출을 위해 직접 메소드를 불러야 함

  • 재귀 람다식 호출이 까다로움

  • 클로저가 지원되지 않음

    • 클로저 : 자신을 둘러싼 context 내의 변수에 접근함. 즉, 외부 범위의 변수를 함수 내부로 바인딩하는 기술

      • 자신을 둘러싼 외부 함수가 종료되더라도 이 값이 유지
        private Stream<Integer> calculate(Stream<Integer> stream, Integer a) {
          //a = 10 값 변경 X
          return stream.map(t -> t * a + b);
        }
      

      => calculate 메소드에서 map메소드 호출

      => a,b는 final로 간주

  • 함수 외부의 값을 변경함

메소드

int min(int x, inty){
  return x < y ? x : y;
}

=> 람다 표현식

(x,y) -> x < y ? x : y;
  • 클래스를 작성하고 객체를 생성하지 않아도 메소드를 사용할 수 있음.

  • 익명 클래스와 같음

    • 익명 클래스 : 클래스의 선언과 동시에 객체를 생성하기 때문에 하나의 객체만을 생성할 수 있는 클래스
    new Object(){
      int min(int x, int y){
        return x < y ? x : y;
      }
    }
    

기본 문법

(매개변수목록) -> {함수 몸체}

  • 매개변수의 타임을 추론할 수 있을 경우 타입 생략가능

    (x, y) -> {return x + y}; // (int x, int y) -> {return x + y;}
    
  • 매개변수가 하나인 경우 ()를 생각할 수 있음.

    a -> a*4

  • 함수의 몸체가 하나의 명령문만으로 이루어졌을 때 중괄호 {}를 생략 할 수 있음. ( 세미콜론 ; 은 붙이지 않는다 )

    (String name, int i) -> System.out.println(name + "="+i)
    
  • 함수의 몸체가 하나의 return 문으로 이루어진 경우 중괄호 {} 생략 불가

    (int a, int b) -> {
      return a > b ? a : b;
    }
    
  • return 문 대신 표현식을 사용할 수 있으며, 이때 반환값은 표현식의 결괏값이 됨. ( 세미콜론(;)은 붙이지 않는다 )

  • (int a, int b) -> a > b ? a: b
    
  • 인자가 없으면 빈 괄호로 표시

    () -> System.out.println("hihi");
    

예제

스레드 생성과 람다 표현식 비교

  • 기존 스레드 생성

    new Thread(new Runnable(){
      public void run(){
        System.out.println("스레드 생성");
      }
    }).start();
    
  • 람다식

    new Thread(()->{
      System.out.println("람다식으로 스레드 생성");
    }).start();
    

함수형 인터페이스

@FunctionalInterface
interface Calc{
  public int min(int x, int y);
}

public calss Lambda{
  public static void main(String[] args){
    Calc minNum = (x, y) -> x < y ? x : y; //추상 메소드 구현
    System.out.println(minNum.min(3,4));
  }
}

메소드 참조

: 람다 표현식이 단 하나의 메소드만을 호출할 때 해당 람다 표현식에서 불필요한 매개변수를 제거하고 사용

문법

클래스이름::메소드이름
또는
참조변수이름::메소드이름
DoubleUnaryOperator oper; //인터페이스

oper = (n) -> Math.abs(n); //람다
System.out.println(oper.applyAsDouble(-5));

oper = Math::abs; //메소드 참조
System.out.println(oper.applyAsDouble(-5))

참고자료

https://coding-factory.tistory.com/

https://m.blog.naver.com/2feelus/220695347170

http://tcpschool.com/java/java_lambda_concept

https://ryan-han.com/post/java/java-lambda/

https://futurecreator.github.io

https://github.com/11STNEWBIE/java-8-study/blob/master/Java8Action/chapter1/1장.md#자바-8에-추가된-새로운-개념

Comments