(Java Stream Programming) 1. Lambda Expression

soosoorim·2024년 2월 20일
0

Lambda Expression

  • 람다(Lambda)란?
    람다 미적분학 학계에서 개발할 시스템에서 유래
    메소드에게 전달할 수 있는 익명 클래스를 함수로 단순화 시킨 것

람다의 특징 (Java 1.8이상)

1. 익명
보통의 메소드와 달리 이름이 없다.
2. 함수
특정 클래스에 종속되지 않아 함수라 부른다.
3. 전달
람다 표현식을 메서드의 인자로 전달하거나 변수로 저장할 수 있다.
4. 간결성
익명 클래스처럼 자질구레한 코드를 구현할 필요가 없다.

익명클래스 (Java 1.8미만)

코드가 지저분해지는 단점

예시)
public static void main(String[] args) {
		
		
		Main main = new Main();
		// fp_java.ch01.anonymousclass.Main@1f32e575
		System.out.println(main);
		
		// fp_java.ch01.anonymousclass.Main$SubMain@2ff4acd0
		// 이름이 있기 때문에 $+이름
		SubMain submain = new SubMain();
		System.out.println(submain);
		
		
		// 인터페이스에 있던 메소드 구현 -> 이름없는 클래스, 익명클래스 구현
		Computable computer = new Computable() {
			@Override
			public int add(int num1, int num2) {
				return num1 + num2;
			}
		};
		
		// fp_java.ch01.anonymousclass.Main$1@27716f4
		// 이름이 없기 때문에 $1
		System.out.println(computer); 
		
		
		Computable computer2 = new Computable() {
			@Override
			public int add(int num1, int num2) {
				return num1 + num2;
			}
		};
		// fp_java.ch01.anonymousclass.Main$2@2a84aee7
		// 이름이 없기 때문에 $2
		System.out.println(computer2); 

람다의 적용

람다의 구성

람다 파라미터
Compartor의 compare 메소드의 파라미터 (두 명의 사원)
파라미터가 1개라면 괄호 생략 가능
파라미터가 없다면 빈 괄호 () 만
화살표 ( -> )
람다의 파라미터 리스트와 바디를 구분함.
람다 바디
두 명의 사원 번호를 구분함. 람다의 반환값에 해당하는 표현식
중괄호가 없으면 반환을 시키지 않을 거란 뜻도 가능
여러줄을 쓸 때 중괄호 필수

Java 8에서 유효한 다섯가지 람다 표현식

  1. String 파라미터 하나를 가지며 int를 반환. 람다표현식에는 return 이 함축되어 있으므로 명시적으로 사용하지 않아도 된다.
  • (String s) -> s.length()
  1. Employees 형식의 파라미터 하나를 가지며 boolean을 반환한다.
  • (Employees emp) -> emp.getSalary() > 5000
  1. int 형식의 파라미터 두개를 가지며 리턴 값이 없다(void 리턴). 람다 표현식을 여러 행의 문장을 포함할 수 있다.
  • (int x, int y) -> {
    System.out.println(“Result : ”);
    System.out.println(x + y);
    }
  1. 파라미터가 없으며 int를 반환한다.
  • () -> 42
  1. Employees 형식의 파라미터 두개를 가지며, int를 반환한다.
  • (Employees emp1, Employees emp2) -> emp1.getSalary() – emp2.getSalary()

{} 중괄호가 있는 람다 표현식에서 리턴이 필요한 경우
return을 명시적으로 작성해야 한다.

람다는 반드시 하나의 추상메소드만 존재해야 한다.

위처럼 이렇게 두가지가 안된다는 뜻
이것을 해결하는 방법은 public void printMessage();을 인터페이스에 메소드로 구현
인터페이스에 메소드 구현 1.8부터 가능

예시)

package fp_java.ch01.lambda;

@FunctionalInterface
public interface Computable {
	
	public int add(int num1, int num2);
	
	/**
	 * 인터페이스의 printMessage 기본 코드를 작성
	 * default 키워드를 가장 앞에 붙이면
	 * 인터페이스도 기능을 구현할 수 있다.
	 * implementable class 에서 overriding 가능하다.
	 * overriding 해주지 않으면 기본코드가 동작된다.
	 */
	default public void printMessage() {
		System.out.println("기본 메세지입니다.");
	}	

}

위에서 만들어주면

// 람다 (정석)
		Computable lambdaComputer = (int num1, int num2) -> num1 + num2;
		int lambdaResult = lambdaComputer.add(10, 20);
		System.out.println(lambdaResult);
		lambdaComputer.printMessage();
		
// 람다 (실무)
		Computable lambdaComputer2 = (num1, num2) -> num1 + num2;
		int lambdaResult2 = lambdaComputer2.add(30, 10);
		System.out.println(lambdaResult2);
		lambdaComputer2.printMessage();

이렇게 lambdaComputer.printMessage(); 간편한 방법으로 다른 클래스에서 사용 가능하다.

함수형 인터페이스

  • 람다는 함수형 인터페이스를 파라미터로 받는 메소드에게만 사용할 수 있다.
  • 함수형 인터페이스는 오직 하나의 추상메소드만 지정되어 있는 인터페이스를 말한다.
  • Comparator 인터페이스의 추상메소드는 int compare(T o1, T 02); 하나.

함수형 인터페이스의 종류

Predicate<T> : 파라미터 하나를 전달받아, boolean을 반환하는 함수형 인터페이스
BiPredicate<L, R> : 파라미터 L과 R을 전달받아 boolean을 반환하는 함수형 인터페이스

Consumer<T> : 파라미터 하나를 전달받아, void를 반환하는 함수형 인터페이스 // void 아무것도 반환 x
BiConsumer<T, U> 파라미터 T와 U를 전달받아 void를 반환하는 함수형 인터페이스 // void 아무것도 반환 x
Function<T, R> : 파라미터 T를 전달받아 R을 반환하는 함수형 인터페이스
BiFunction<T, U, R> : 파라미터 T와 U를 전달받아( funtion에서만 R이 리턴) R 을 반환하는 함수형 인터페이스

예시)

package fp_java.ch01.lambda;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

public class BuiltInFunctionalInterface {
	
	
	public static void main(String[] args) {
		
		// 익명클래스
		Predicate<Integer> pp = new Predicate<Integer>() {
			@Override
			public boolean test(Integer t) {
				return t >= 19;
			}
		};
		boolean isAdult = pp.test(20);
		System.out.println(isAdult);
		
		// 람다
		Predicate<Integer> p = (t) -> t >= 19;
		boolean isAdult2 = p.test(15);
		System.out.println(isAdult2);
		
		
		Consumer<String> c = t -> System.out.println(t); // 파라미터 1개일때는 () 생략가능
		c.accept("반갑습니다");
		
		Function<Boolean, String> f = (t) -> t ? "yes" : "no";
		String result = f.apply(true);
		String result2 = f.apply(false);
		
		System.out.println(result);
		System.out.println(result2);
		
	}

}

메소드 레퍼런스 (Java 1.8 이상)

0개의 댓글

관련 채용 정보