카테고리 없음

[Java Stream Programming] 1. Lambda

코딩펭귄 2024. 2. 6. 17:50

         객체             지향     프로그래밍

object(Instance) oriented programming

 

객체 Instance

-> 1. 변수 할당, 2. 객체생성, 3. 객체 파라미터 전달, 4. 객체 내에서 다른 객체를 생성-> 이걸 다 할 수 있어야 '객체'라고 함

 

함수형 프로그래밍

functional programming

-> 객체(Instance)를 각각 함수로 만들 수 있어야 함

-> 람다(Lamda)를 지원함

 

- 자바는, instance, functional 둘다 지원함! (<- 인터페이스 & 익명클래스 때문에 가능)

 

filtering & slicing, mapping, find & matching, collectors 은 반드시 알고 있어야함

 

 

 

람다란?

- 메소드에게 전달할 수 있는 익명클래스를 함수로 단순화 시킨것

람다의 특징

- 익명 : 보통의 메소드와 달리 이름이 없음

- 함수 : 특정클래스에 종속되지않아 함수라 부름

- 전달 : 람다 표현식을 메서드의 인자로 전달하거나, 변수로 저장할 수 있음

- 간결성 : 익명클래스처럼 자질구레한코드를 구현할 필요가 없음

람다의 구성
                                                      람다적용

 

형태)  (람다파라미터) -> 람다바디 ; 

ex) (emp1, emp2) -> emp2.getEmployeeId()-emp1.getEmployeeId();

- 람다파라미터 : 메소드의 파라미터 ( 파라미터의 타입은 생략가능(JVM이 알아서 판단해줌) )

- 화살표(->) : 람다의 파라미터 리스트와 바디의 구분

- 람다바디 : 람다의 반환값에 해당하는 표현식 

 

  파라미터가

> 없을때 : () 비어있는 괄호 써줘야됨

> 1개일때 : 괄호() 생략가능

> 2개이상 : 괄호() 써줘야됨

 

 람다 바디 에서

> 중괄호가 있다면 : (기존코드의)여러줄을 쓸 경우 / 반환안시키겠다

> 중괄호가 없다면 : 코드 1줄 or 반환시키겠다는 뜻

> 중괄호가 있는데 반환시키고 싶다면(리턴이 필요한경우) : 명시적으로 return 사용

( 람다 바디 : 중괄호 안의 내용을 간략하게 표시함)

 

 

 

함수형 인터페이스

함수형 인터페이스

- 람다는 함수형 인터페이스를 파라미터로 받는 메소드에게만 사용할 수 있음

- 단 1개의 추상메소드만 지정되어 있는 인터페이스

- ex) Comparator인터페이스의 추상메소드는 int compare(T o1, To2); 하나

*-> 앞뒤에 습관적으로 띄어쓰기나 return등 작성하지 말것 절대*

함수형 인터페이스의 종류

- R : 반환시킨다는 의미

- BI : 파라미터 2개라는 의미

Predicate<T>          파라미터 하나를 전달받아, boolean을 반환

BiPredicate<L, R>   파라미터 LR을 전달받아 boolean을 반환

Consumer<T>         파라미터 하나를 전달받아, void를 반환

BiConsumer<T, U>  파라미터 TU를 전달받아 void를 반환

Function<T,R>         파라미터T를 전달받아 R을 반환

BiFunction<T,U,R>  파라미터 T와 U를 전달받아 R을 반환

- BiPredicate<L, R>에서의 R : 파라미터

- Function<T, R>에서의 R : 반환값

 

 

Computable 인터페이스를 사용하는 람다 예제

public interface Computable {
	
	public int add(int num1, int num2);
	
	// public void printMessage(); //이렇게되면 추상메소드 2개가 되기때문에 Computable 클래스를 람다로 표현할 수 없게됨
    
	default public void printMessage() {
		System.out.println("기본 메시지입니다.");
	}
}

추상메소드가 반드시 '1개' 만 존재해야 람다로 쓸 수 있으므로 만약 추상메소드가 2개가 된다면 람다로 쓸 수 없음

하지만,

default 키워드를 가장 앞에 붙이면 (;로 끝나면 안되고, 중괄호{}반드시 넣어줘야됨(중괄호 안 내용은 안써도 됨))

-> 인터페이스도 기능을 구현할 수 있음

-> implementable class에서 overriding 가능 (overriding을 해주지 않으면 기본코드가 동작됨)

public class Main {

	//nested class -> private, public, default, protected 모두 가능함
	public static class SubMain{
		
	}
			
	public static void main(String[] args) {
		
		Main main = new Main();
		System.out.println(main); //fp_java.ch01anonymousclass.Main@49097b5d

		
		SubMain subMain = new SubMain();
		System.out.println(subMain); //fp_java.ch01anonymousclass.Main$SubMain@37a71e93 
									//($ 붙음 -> Main 이라는 클래스의 SubMain의 인스턴스이다)

		
		// 익명클래스를 인터페이스로 바로 만들기
		Computable computer = new Computable() {  // (인터페이스는(추상메소드) 바로 인스턴스로 만들 수 없다)
			@Override
			public int add(int num1, int num2) {
				return num1 + num2;
			}
		};
		System.out.println(computer); //fp_java.ch01anonymousclass.Main$1@7106e68e (익명클래스로 만든 객체 : $ 붙음)

		Computable computer2 = new Computable() {  
			@Override
			public int add(int num1, int num2) {
				return num1 + num2;
			}
		};
		System.out.println(computer2); // fp_java.ch01anonymousclass.Main$2@6576fe71 -> $2 : 2번째로 만든 익명클래스

		
		Computable computer3 = new Computable() {  
			@Override
			public int add(int num1, int num2) {
				return num1 + num2;
			}
		};
		System.out.println(computer3); //fp_java.ch01anonymousclass.Main$3@300ffa5d -> $3 : 3번째로 만든 익명클래스
		
//		클래스안의 클래스로 만든 인터페이스라는 의미 = $ 

	}
}