Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

일상기록

java.util.function패키지 본문

Java

java.util.function패키지

너 구 나 2023. 4. 18. 21:04

java.util.function패키지

대부분의 메소드는 타입이 비슷하다. 매개변수가 없거나 한 개 또는 두 개, 반환 값은 없거나 한 개, 게다가 제네릭 메소드로 정의하면 매개변수나 반환 타입이 달라도 문제가 되지 않는다. 그래서 java.util.function패키지에 일반적으로 자주 쓰이는 형식의 메소드를 함수형 인터페이스로 미의 정의해 놓았다. 매번 새로운 함수형 인터페이스를 정의하지 말고, 가능하면 이 패키지의 인터페이스를 활용하는게 좋다.

 그래야 함수형 인터페이스에 정의된 메소드 이름도 통일되고, 재사용성이나 유지보수 측면에서도 좋다. 자주 쓰이는 가장 기본적인 함수형 인터페이스는 다음과 같다.

java.util.function패키지의 주요 함수형 인터페이스

매개변수와 반환값의 유무에 따라 4개의 함수형 인터페이스가 정의되어 있고, Function의 변형으로 Predicate가 있는데, 반환값이 boolean이라는 것만 제외하면 Function과 동일하다. Predicate는 조건식을 함수로 표현하는데 사용된다.

조건식의 표현에 사용되는 Predicate

Predicate는 Function의 변형으로, 반환타입이 boolean이라는 것만 다르다. Predicate는 조건식을 람다식으로 표현하는데 사용된다.

Predicate<String> isEmptyStr = s -> s.length() == 0;
String s = "";

if(isEmptyStr.test(s))	// if(s.length() == 0)
	System.out.println("This is an empty String.");

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

매개변수의 개수가 2개인 함수형 인터페이스는 이름 앞에 접두사 'Bi'가 붙는다.

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

Supplier는 매개변수는 없고 반환값만 존재하는데, 메소드는 두 개의 값을 반환할 수 없으므로 BiSupplier가 없는 것이다.

두 개 이상의 매개변수를 갖는 함수형 인터페이스가 필요하다면 직접 만들어서 써야한다. 만일 3개의 매개변수를 갖는 함수형 인터페이스를 선언한다면 다음과 같은 것이다.

@FunctionalInterface
interface TriFunction<T, U, V, R> {
	R apply(T t, U u, V v);
}

UnaryOperator와 BinaryOperator

Function의 또 다른 변형으로 UnaryOperator와 BinaryOperator가 있는데, 매개변수의 타입과 반환타입의 타입이 모두 일치한다는 점만 제외하고 Function과 같다.

UnaryOperator와 BinaryOperator 상위클래스는 각각 Function과 BiFunction이다.

UnaryOperator와 BinaryOperator

컬렉션 프레임웍과 함수형 인터페이스

컬렉션 프레임웍의 인터페이스에 다수의 디폴트 메소드가 추가되었는데, 그 중의 일부는 함수형 인터페이스를 사용한다.

컬렉션 프레임웍의 함수형 인터페이스를 사용하는 메소드

Map인터페이스에 있는 'compute'로 시작하는 메소드들은 맵의 value를 변환하는 일을 하고 merge()는 Map을 병합하는 일을 한다.

기본형을 사용하는 함수형 인터페이스

지금까지 소개한 함수형 인터페이스는 매개변수와 반환값의 타입이 모두 제네릭 타입이었는데, 기본형 타입의 값을 처리할 때도 래퍼(wrapper)클래스를 사용해왔다. 그러나 기본형 대신 래퍼클래스를 사용하는 것은 당연히 비효율적이다. 그래서 보다 효율적으로 처리할 수 있도록 기본형을 사용하는 함수형 인터페이스들이 제공된다.

기본형을 사용하는 함수형 인터페이스

아래 코드에서 IntUnaryOperator대신 Function을 사용하면 에러가 발생한다.

Function f = (a) -> 2 * a;	// 에러 a의 타입을 알 수 없으므로 연산불가

매개변수 a와 반환 값의 타입을 추정할 수 없기 때문이다. 그래서 아래와 같이 타입을 지정해 주어야한다.

// OK 매개변수 타입과 반환타입이 Integer
Function<Integer, Integer> f = (a) -> 2 * a;

다시 한번 Function대신 IntFunction을 사용할 수도 있지만, IntUnaryOperator가 Function이나 IntFunction보다 오토박싱&언박싱의 횟수가 줄어들어 더 성능이 좋다.

// OK 매개변수 타입은 int, 반환타입은 Integer
IntFunction<Integer> f = (a) -> 2 * a;

IntFunction, ToIntFunction, IntToLongFunction은 있어도 IntToIntFunction은 없는데 그 이유는 IntUnaryOperator가 그 역활을 하기 때문이다. 매개변수 타입과 반환타입이 일치할 때는 앞에 설명처럼 Function대신 UnaryOperator를 사용하자.

 

람다식 연습코드

github

 

'Java' 카테고리의 다른 글

Java - 메소드 참조  (0) 2023.04.19
Java - Function의 합성, Predicate의 결합  (0) 2023.04.19
Java - 람다식(Lambda expression)  (1) 2023.04.18
Java - 열거형(Enums)  (0) 2023.04.18
Java - 제네릭 타입의 제거  (0) 2023.04.18