람다식

서현서현·2022년 4월 15일
0

JAVA

목록 보기
16/27
post-thumbnail

람다식

  • 익명 함수를 생성하기 위한 식
  • 자바에서는 ‘매개변수를 가진 코드블럭’ ⇒ 런타임시 익명구현객체로 생성된다.
|형식| 인터페이스명 객체변수명 = 람다식;

|람다식의 형식| (매개변수들...) -> {처리할 코드들;...}
  • 람다식으로 변환 할 수 있는 인터페이스는 추상메소드가 1개인 인터페이스만 가능하다.
    이런 인터페이스를 '함수적 인터페이스'라고 한다.
  • 이 함수적 인터페이스를 만들때는 @FunctionalInterface로 지정한다.

이전 스레드 선언방법3번째가 익명클래스를 이용했다. Runnable의 추상메서드는 void run()하나이고 결국 함수적 인터페이스!

public class T01_LambdaTest {
	public static void main(String[] args) {
		// 람다식을 사용하지 않는경우
		Thread th1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i =1; i<=10; i++) {
					System.out.println(i);
				}
				
			}
		});
		th1.start();
		
		//  람다식을 사용하는 경우
		Thread th2 = new Thread(()->{
			for(int i =1; i<=10; i++) {
				System.out.println("람다 - "+i);
			}
			
		});
		th2.start();
	}
}

람다식 작성 방법

기본형식 ) (자료형이름 매개변수명,...) -> {실행문들;...}

1) 매개변수의 '자료형이름'은 생략 할 수 있다

(int a) -> {System.out.println(a);}
		(a) -> {System.out.println(a);}

2) 매개변수가 1개일 경우에는 괄호 '()'를 생략 할 수 있다.
(단, '자료형 이름'을 지정할 경우에는 괄호를 생략 할 수 없다)

a -> {System.out.println(a);}

3) '실행문'이 1개일 경우에는 '{}'를 생략 할 수 있다
(이때 문장의 끝을 나타내는 세미콜론(;)도 생략한다.)

a -> System.out.println(a)

4) 매개변수가 하나도 없으면 괄호’()’를 생략할 수 없다

 () -> System.out.println("안녕");

5) 반환값이 있을 경우에는 return명령을 사용한다.

(a,b) -> { return a+b; }
(a,b) -> return a+b

6) 실행문에 return만 있을경우 return 명령과 ‘{}’를 생략할 수 있다

(a,b) -> a+b

인터페이스

// 함수적 인터페이스 => 추상메소드가 한개뿐인 인터페이스

@FunctionalInterface
public interface LambdaTestInterface1 {
	// 반환값이 없고 매개변수도 없는 추상메소드 선언
	public void test();

}

@FunctionalInterface
interface LambdaTestInterface2 {
	// 반환값이없고 매개변수는 있는 추상메소드 선언
	public void test(int a);
}

@FunctionalInterface
interface LambdaTestInterface3 {
	// 반환값과 매개변수가 모두 있는 추상메소드 선언
	public int test(int a, int b);
}
public class T02_LambdaTest {
	
	
	public static void main(String[] args) {
		
	
	// 람다식을 사용하지 않았을 경우
	LambdaTestInterface1 lam1 = new LambdaTestInterface1() {
		
		@Override
		public void test() {
			System.out.println("안녕하세요");
			System.out.println("익명 구현 객체 방식입니다");
		}
	};
	
	lam1.test(); //메서드 호출
	
	
	LambdaTestInterface1 lam2 = () -> 
		System.out.println("반가워요\n람다식으로 처리하는 방식입니다");
	lam2.test();
	
	System.out.println("----------------------------------------------------");

	
	LambdaTestInterface2 lam3 =
			(int z) -> {
				int result = z+100;
				System.out.println("result = "+result);
			};
			lam3.test(30);
			
	LambdaTestInterface2 lam4 = 
			z -> {
				int result = z+300;
				System.out.println("result = "+result);
			};
	lam4.test(60);
	
	LambdaTestInterface2 lam5 =
			z -> System.out.println("result = "+(z+500));
	lam5.test(90);
	System.out.println("---------------------------------");
	
	LambdaTestInterface3 lam6 =
			(int x, int y)-> {
				int r = x+y;
				return r;
			};
	int k = lam6.test(20, 50);
	System.out.println("k = "+k);
	
	
	LambdaTestInterface3 lam7 =
		(x,y)-> {
			return x+y;
		};
	k = lam7.test(80, 50);
	System.out.println("k= "+k);
	
	LambdaTestInterface3 lam8 =
		(x,y) -> x+y;
	k = lam8.test(100,200);
	System.out.println("k = "+k);
			
			
	LambdaTestInterface3 lam9 = 
		(x,y) -> x > y ? x : y;
	k = lam9.test(100, 200);
	System.out.println("k = "+k);

	
	
	
}

}

final

람다식 내부에서 사용되는 지역변수는 모두 final이어야 한다.
보통은 final을 붙이지 않으면 컴파일러가 자동으로 붙여준다
단, 지역변수의 값을 변경하는 식이 있을 경우에는 자동으로 final을 붙여주지 않는다

즉 익명객체 안에서 지역변수를 참조할때 그 지역변수는 final이어야만 참조가 가능하다!

원래 그냥 int로 선언해도 알아서final로 처리해주지만 만약 도중에 값을 바꾸는 내용이 있을경우 final로 바꿀 수 없으므로 컴파일오류가 뜬다.

public class T03_LambdaTest {
	static int stVar = 9;
	private String name = "aaa";
	
	public void testMethod(final int temp) {
		final int localVar = 50;
		int kor = 100;
		
		temp = 500; //error!
		localVar = 2000; //error!
		kor = 400;
		
		
		// 람다식에서 지역변수 사용하기
		LambdaTestInterface1 lam =
				() -> {
					System.out.println("tmep = "+temp);
					System.out.println("localVar = "+localVar);
					System.out.println("kor = "+kor); //error!
					System.out.println("stVar = "+stVar);
					System.out.println("this.name = "+this.name);
				};
				lam.test();
		
	}
	
	public static void main(String[] args) {
		new T03_LambdaTest().testMethod(200);
	}

}

list에서 람다식 써보기

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class T04_LambdaTest {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("홍길동");
		list.add("이순신");
		list.add("변학도");
		
		//
		for(String str : list) {
			System.out.println(str);
		}
		
		
		//
		list.forEach(new Consumer<String>() {

			@Override
			public void accept(String t) {
				System.out.println(t);
				
			}
		});
		
		
		// 람다식을 이용해 출력을 더 간단하게 표현 ( 알맹이는 위로 변해서 컴파일되는거 )
		list.forEach((t) ->System.out.println(t));
	}

}

0개의 댓글