상세 컨텐츠

본문 제목

자바 람다식 ( java lambda expression ) 정리하기 part01

Language/JAVA

by Computer_x86_64 2021. 8. 19. 11:15

본문

자바의 람다식이 있습니다.

 

JDK 1.5 에는 Generics가 자바에 등장했고 

JDK 1.8 에 오늘의 주제 Java Lamba expression이 등장 했다.

 

우리가 알아야할 개념 요약!

1. 람다는 함수형 언어에서 유래된것이다.

2. 자바는 객체지향언어라 람다도 익명객체이다.

3. 함수형언어를 바탕으로 사용할수 있다.

4. 함수는 클래스에 자유롭다.

5. 메서드는 클래스에 종속적이다.

 

모든 그것을 이해하기 위해 정의부터 파악해보자!

 

" 원래 수리 논리의 일종 람다계산에서 사용되는 식이지만 LISP에 들어가 있어 널리 알려지게 된 것이다. 

   λxyㆍplus(x, y) 는  x 와 y를 변수로 하여 x + y해라"

  

'음... 이게 뭐야 이상한 기호 나오고 아 몰라....'

저도    λ  기호 몰라도 람다식은 이해했습니다.

 

java는 객체지향성격을 갖고 있는걸 다들 잘 알고 있으니 설명 패스

람다는 원래 LISP 프로그래밍 언어로 이것도 모르셔도 됩니다. (저도 몰라요...) 

 

자 보시죠

λxy   ?? = x y를 변수로 하여 

              plus(x, y) 특정 함수에 넣으면 두 변수가  x + y 결과를 얻는구나!"

 

주로 함수형 언어에서 많이 사용된다고합니다. 

 

자바는 객체지향 언어인데 ? 함수형 언어? 머리가 복잡해지실수 있다.

 

중요한건 자바는 무조건 객체다. 

 

- 그래서 람다는 익명객체이다. 

- 매소드를 변수처럼 사용할수있다.

- 함수는 클래스의 독립적이고, 메서드는 클래스에 종속적이다.

 

예시에 보자.

(문제) 싱싱한 사과와 불량사과를 모두 더하는 메서드가 필요합니다.

(해결책) 그럼 첫번째 사용법.  아래와 같이 메서드를 클래스에 정의해 해결합니다.

//사과라는 객체에 싱싱한 사과를 카운트하고, 불량인 사과를 카운트한다.
public class apple{
	int flashCount;
	int DefectCount;
	
    //싱싱한 사과와 불량인 사과를 모두 합산한다.
	int count(int f, int d) {
		this.flashCount = f;
		this.DefectCount = d;
		return f+d;
	}
    	public static void main(String[] agrs) {
		apple a = new apple();
		
		int totalCount = a.count(34, 3);
		System.out.println(totalCount);  //37
		
	}

}

위에는 메소드 방식입니다.

 

그렇다면 배워야할 람다식은?

 

함수형 인터페이스를 정의해야합니다.

@FunctionalInterface는 람다를 위에 정의해주며 추상 메서드는 1개밖에 만들지 못합니다.

한번 메서드를 하나더 만들어보시면 아래와 같은 컴파일 에러가 발생합니다.

Invalid '@FunctionalInterface' annotation; LambdaTest1 is not a functional interface

@FunctionalInterface
interface LambdaTest1{
	public int add(int a, int b);
}

 

 

(해결책) 두번째 인터페이스를 통해 메소드를 구현합니다.

인터페이스는 객체를 인스턴스로 생성할수 없지만 아래와 같이 익명 클래스처럼 생성과 동시에 메소드를 저의합니다.

	public static void main(String[] agrs) {
	//	LambdaTest1 lam1 = new LambdaTest1();  //인스턴스로 만들수없다.  Cannot instantiate the type LambdaTest1
		LambdaTest1 lam1 = new LambdaTest1() {
			public int add(int a, int b) {
				return a + b;
			}
		};
		int Lambda1 = lam1.add(3,4);
		System.out.println(Lambda1);
    }
 }

(해결책) 세번째 람다를 익명객체로 만들어 사용합니다.

[인터페이스명] [변수명] ([파라미터변수명]) -> { [실행문] [반환] }

@FunctionalInterface 
interface LambdaTest2 {
	public int add(int c, int d);
}

class grape {
	int flashCount;
	int defectCount;
}
public class apple {
	int flashCount;
	int DefectCount;
	
	int count(int f, int d) {
		this.flashCount = f;
		this.DefectCount = d;
		return f+d;
	}
	
	public static void main(String[] agrs) {
		
		LambdaTest2 lam2 = (c, d) -> { return c + d; };
		
		int lambda2 = lam2.add(2,3);
		System.out.println(lambda2);

	}

}

 

람다의 문법적 요소로

-함수명 제거

-파라미터값의 타입 생략

-파라미터값이 두개 이거나 없는경우 ( ) 사용. (한개인경우 생략)

-리턴 타입이 없으면 { } 생략가능

 

 

위에 문법적인 요소로 제거와 생략다른 단어를 사용했습니다.

제거는 사용하면 에러가 발생하는것이고 

생략은 경우에 따라 사용하기도 해야할 경우입니다..

 

 

이와같이 포도라는 클래스도 이런 값을 구하고 싶다면 

해당 람다식은 종속성이 없기에 사용할수 있습니다.

 

아니면 각각의 클래스마다 메서드를 다 정의해줘야합니다.

관련글 더보기

댓글 영역