[그린컴퓨터] Server/JAVA(자바 JDK)

람다식 { 함수형 프로그래밍, 람다식, 연습문제 }

Ben의 프로그램 2023. 7. 3. 11:22
728x90

  • 자바는 8 버전부터 객체지향 언어임에도 불구하고 함수형 프로그래밍 기법 사용이 가능해졌다. 

  • 함수형 프로그래밍은 함수를 중심으로 프로그래밍하는 기법인데, 코드 가독성과 유지보수 확보를 위해 사용한다.

  • 자바에서 메소드는 무조건 클래스 안에 존재해야 하는데(객체 지향 언어이기 때문), 함수형 프로그래밍에서는 가능해졌다. 메소드를 객체 생성 없이 사용할 수 있다는 것을 의미한다.  

  • 함수형 프로그래밍에서는 람다식과 함수형 인터페이스를 사용하여 함수를 표현하게 된다. 

  • 함수형 인터페이스는 단 하나의 추상 메소드를 가지는 인터페이스이다. 

  • 함수형 인터페이스는 @FunctionalInterface 라는 Annotation 이 사용된 것을 볼 수 있다. Annotation 은 특정 제약사항을 걸어줄 때 사용하는데, 함수형 인터페이스 Annotation 은 단 하나의 추상 메소드를 가지게 만든다.

  • 람다식은 함수 이름, 반환타입, 매개변수 타입을 생략한다. 

  • 바디 코드가 짧은 경우(한 줄일 경우) { } 중괄호 & return 키워드를 생략할 수 있다. 
package lambda;

@FunctionalInterface
interface MyNumber {
	int add(int num1, int num2);
}

public class Ex1 {

	public static void main(String[] args) {
		MyNumber number = (x, y) -> x+y;
		System.out.println(number.add(10, 20));
	}

}
  • 람다식은 식처럼 보이는데 사실은 메서드 선언에 가깝다는 것을 생각해야 한다.
package lambda;

@FunctionalInterface
interface MyNumber2 {
	int add(int num1, int num2);
}

public class Ex2 {
	public static void main(String[] args) {
		//MyNumber number = (x, y) -> x + y;
		MyNumber2 number2 = new MyNumber2() {
			@Override 
			public int add(int x, int y) {
				return x+y;
			}
		};
		// 람다식을 사용하지 않으니까 코드가 훨씬 길어진 것을 볼 수 있다.
		
		System.out.println(number2.add(10, 20));
	}
}
  • 실제로 람다식이 처리되는 과정을 코드로 풀어쓴 것을 볼 수 있다. 람다식은 실제로 익명 클래스 형식으로 처리가 된다. 
package lambda;

@FunctionalInterface
interface StringConcat {
	public void makeString(String s1, String s2);
}

public class Ex3 {
	public static void main(String[] args) {
		String s1 = "Hello";
		String s2 = "World";
		
        //람다식 함수 사용
		StringConcat concat1 = (str1, str2) -> System.out.println(str1 + "," + str2);
		
        // 익명 클래스 사용
		StringConcat concat2 = new StringConcat() {
			@Override 
			public void makeString(String str1, String str2) {
				System.out.println(str1 + "," + str2);
			}
		};
		
		concat1.makeString(s1, s2);
		concat2.makeString(s1, s2);
	}
}
  • 람다식 함수와 익명 클래스 사용은 같은 것이다. 
package lambda;

import java.util.*;

public class Ex4 {
	public static void main(String[] args) {
		List<String> list = Arrays.asList("aaa", "ccc", "bbb");
		
		// 익명클래스 넣기
		Collections.sort(list, new Comparator<String>() {
			@Override
			public int compare(String s1, String s2) {
				return s2.compareTo(s1);
			}
		});
		System.out.println("리스트 역정렬 : " + list);
		
		// 람다식 함수 넣기
		Collections.sort(list, (s1, s2) -> s1.compareTo(s2)); 
		System.out.println("리스트 순정렬 : " + list);
	}
}
  • 다양한 코드에서 람다식 함수 사용이 더 간단한 것을 확인할 수 있다. 

연습문제

람다식과 함수형 인터페이스를 사용하여 두 숫자 중 더 큰 값을 반환하는 함수를 만드세요.
ex. max(10, 20) -> 20
package lambda;

@FunctionalInterface 
interface largerNumber {
	public int max(int i1, int i2);
}

public class Q1 {
	public static void main(String[] args) {
		// 분기문 활용 & 람다식 활용
		largerNumber l1 = (i1, i2) -> {
			if (i1 < i2) {
				return i2;
			} else if (i1 == i2) {
				return -999;
			} else {
				return i1;
			}
		};
		
		// 삼항 연산자 활용 & 익명 클래스로 인터페이스 구현
		largerNumber l2 = new largerNumber() {
			@Override
			public int max(int i1, int i2) {
				return i1>i2? i1:i2;
			}
		};
		
		// 삼항 연산자 활용 & 람다식 활용
		largerNumber l3 = (x, y) -> x>y? x:y;
		
		System.out.println(l1.max(10, 20));
		System.out.println(l2.max(10, 20));
		System.out.println(l3.max(10, 20));
	}
}

연습문제2

배열의 합을 구하는 함수를 함수인터페이스와 람다식을 활용해서 만들어보세요.
package lambda;

@FunctionalInterface
interface Calculator {
	int add(int arr[]);
}

public class Q2 {
	public static void main(String[] args) {
		int arr[] = {1, 2, 3, 4};
		
		Calculator calculator = (intArr) -> {
			int sum = 0;
			for(int i=0; i<arr.length; i++) {
				sum = sum + arr[i];
			}
			return sum;
		};
		
		System.out.println(calculator.add(arr));
	}
}