Lambda란?

Lambda란?

프로그래밍 언어에서 사용되는 개념으로 익명 함수(Anonymous functions)를 지칭하는 용어.
현재 사용되고 있는 람다의 근간은 수학과 기초 컴퓨터과학 분야에서의 람다 대수이다. 람다 대수는 간단히 말하자면 수학에서 사용하는 함수를 보다 단순하게 표현하는 방법이다.

Java 함수형 인터페이스

함수형 인터페이스란 1 개의 추상 메소드를 갖는 인터페이스를 말한다.
Java8 부터 인터페이스라도 기본 구현체를 포함한 디폴트 메서드 (default method) 를 포함할 수 있다. 여러 개의 디폴트 메서드가 있더라도 추상 메서드가 오직 하나면 함수형 인터페이스이다. 자바의 람다 표현식은 함수형 인터페이스로만 사용 가능하다.

함수형 인터페이스메서드설명
java.lang.Runnablevoid run()매개변수도 없고, 반환값도 없음
( in > X, out > X)
SupplierT get()매개변수는 없고, 반환값만 있음
( in > X, out > O)
Consumervoid accept(T t)Supplier와 반대로 매개변수만 있고, 반환값이 없음
( in > O, out > X)
Function<T, R>R apply(T t)일반적인 함수. 하나의 매개변수를 받아서 결과를 반환
( in > O, out > O)
Predicateboolean test(T t)조건식을 표현하는데 사용됨. 매개변수는 하나, 반환 타입은 boolean
( in > O, out > boolean)
import java.util.*;
import java.util.function.Consumer;

public class Main{
	public static void main(String[] args){
		Consumer<String> c = s -> {
			for(char ch : s.toCharArray()){
				System.out.println(ch);
			}
		};

		c.accept("test");
	}
}

매개변수가 2개인 함수형 인터페이스

함수형 인터페이스메서드설명
BiConsumer<T, U>void accept(T t, U u)두개의 매개변수만 있고, 반환값이 없음
BiPredicate<T, U>boolean test(T t, U u)조건식을 표햔하는데 사용됨. 매개변수는 둘, 반환값은 boolean
BiFunction<T, U, R>R apply(T t, U u)두 개의 매개변수를 받아서 하나의 결과를 반환
import java.util.*;
import java.util.function.BiConsumer;

public class Main{
	public static void main(String[] args){
		BiConsumer<String,String> c = (s1,s2) -> {
			for(char ch : s1.toCharArray()){
				System.out.println(ch);
			}
			for(char ch : s2.toCharArray()){
				System.out.println(ch);
			}
		};

		c.accept("test","dddd");
	}
}

매개변수 타입과 반환타입이 일치하는 함수형 인터페이스

함수형 인터페이스메서드설명
UnaryOperatorT apply(T t)Function의 자손, Function과 달리 매개변수와 결과의 타입이 같다.
BinaryOperatorT apply(T t, T t)BiFuncrtion의 자손, BiFunction과 달리 매개변수와 결과의 타입이 같다.

컬렉션 프레임워크와 함수형 인터페이스

인터페이스메서드설명
Collectionboolean removeIf(Predicate<E> filter)조건에 맞는 요소를 삭제
Listvoid replaceAll(UnaryOperator<E> operator)모든 요소를 변환하여 대체
Iterablevoid forEach(Consumer<T> action)모든 요소에 작업 action을 수행
MapV compute(K key, BiFunction<K,V,V> f)지정된 키의 값에 작업 f를 수행
V computeIfAbsent(K key, BiFunction<K,V> f)키가 없으면, 작업 f 수행 후 추가
V computeIfPresent(K key, BiFunction<K,V,V> f)지정된 키가 있을 때, 작업 f 수행
V merge(K key, V value, BiFunction<V,V,V> f)모든 요소에 병합작업 f를 수행
void forEach(BiConsumer<K,V> action)모든 요소에 작업 action을 수행
void replaceAll(BiFunction<K,V,V> f)모든 요소에 치환작업 f를 수행
import java.util.*;

public class Main{
	public static void main(String[] args){
		List<Integer> sList = new ArrayList<>();
		for(int i =1 ; i < 100 ; i++){
			sList.add(i);
		}
		sList.removeIf( s -> s>10 );
		sList.forEach( s -> System.out.println(s) );

		sList.replaceAll( s -> s%2==0 ? s+10 : s );
		sList.forEach( s -> System.out.println(s) );
	}
}
import java.util.*;

public class Main{
	public static void main(String[] args){
		Map<Integer,String> m = new HashMap<>();
		for(int i = 1 ; i < 10 ; i++){
			m.put(i,"No."+i);
		}

		m.compute(2, (k,v) -> v+k+" compute");
		m.computeIfAbsent(11, k -> "No."+k);
		m.computeIfPresent(4, (k,v) -> v+k+" computeIfPresent");
		m.merge( 9 ,"999", (v1,v2) -> v1+v2 ); // before No.9 after No.9999
		m.replaceAll( (k,v) -> {
			if(k==2||k==6||k==8) return String.valueOf(k);
			else return v+" re";
		});
		m.forEach( (k,v) -> System.out.println("key : "+k+", value : "+v));
	}
}

메서드 참조
형식 > 클래스이름::메서드이름

// ex))
import java.util.*;
import java.util.function.Function;

public class Main{
	public static void main(String[] args){
		// before
		Function<String,Integer> f = s -> {
			return Integer.parseInt(s);
		};
		System.out.println(f.apply("123"));

		// after
		Function<String,Integer> f2 = Integer::parseInt;
		System.out.println(f2.apply("123"));
	}
}

© 2023 Lee. All rights reserved.