Java의 주요 함수형 인터페이스는 java.util.function 패키지에 정의되어 있으며,
람다 표현식과 함께 사용하여 간결하고 가독성 높은 코드를 작성할 수 있습니다.
주요 함수형 인터페이스들
1. Predicate<T>
Predicate<T>는 입력을 받아 boolean 값을 반환하는 함수형 인터페이스입니다. 주로 조건을 테스트하는 데 사용됩니다.
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args) {
Predicate<String> isEmpty = s -> s.isEmpty();
System.out.println(isEmpty.test("")); // 출력: true
System.out.println(isEmpty.test("Hello")); // 출력: false
// 다른 예시: 숫자가 짝수인지 확인
Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4)); // 출력: true
System.out.println(isEven.test(5)); // 출력: false
}
}
Predicate는 and, or, negate 메서드를 사용하여 조합할 수 있습니다.
Predicate<String> isNotEmpty = s -> !s.isEmpty();
Predicate<String> containsA = s -> s.contains("A");
Predicate<String> complexPredicate = isNotEmpty.and(containsA);
System.out.println(complexPredicate.test("Apple")); // 출력: true
System.out.println(complexPredicate.test("")); // 출력: false
System.out.println(complexPredicate.test("Banana")); // 출력: false
2. Function<T, R>
Function<T, R>는 입력을 받아 다른 타입의 출력을 반환하는 함수형 인터페이스입니다. 주로 변환 작업에 사용됩니다.
import java.util.function.Function;
public class FunctionExample {
public static void main(String[] args) {
Function<Integer, String> intToString = i -> "Number: " + i;
System.out.println(intToString.apply(5)); // 출력: Number: 5
// 다른 예시: 문자열의 길이 계산
Function<String, Integer> stringLength = s -> s.length();
System.out.println(stringLength.apply("Hello")); // 출력: 5
}
}
Function은 andThen, compose 메서드를 사용하여 조합할 수 있습니다.
Function<Integer, Integer> multiplyByTwo = x -> x * 2;
Function<Integer, Integer> addThree = x -> x + 3;
Function<Integer, Integer> combinedFunction = multiplyByTwo.andThen(addThree);
System.out.println(combinedFunction.apply(5)); // 출력: 13
3. Consumer<T>
Consumer<T>는 입력을 받아 소비하는 함수형 인터페이스로, 반환값이 없습니다. 주로 입력을 출력하거나 다른 작업을 수행하는 데 사용됩니다.
import java.util.function.Consumer;
public class ConsumerExample {
public static void main(String[] args) {
Consumer<String> print = s -> System.out.println(s);
print.accept("Hello, World!"); // 출력: Hello, World!
// 다른 예시: 숫자를 출력
Consumer<Integer> printNumber = n -> System.out.println("Number: " + n);
printNumber.accept(10); // 출력: Number: 10
}
}
Consumer는 andThen 메서드를 사용하여 조합할 수 있습니다.
Consumer<String> printUpperCase = s -> System.out.println(s.toUpperCase());
Consumer<String> printLowerCase = s -> System.out.println(s.toLowerCase());
Consumer<String> combinedConsumer = printUpperCase.andThen(printLowerCase);
combinedConsumer.accept("Java"); // 출력: JAVA, java
4. Supplier<T>
Supplier<T>는 입력을 받지 않고 출력을 반환하는 함수형 인터페이스입니다. 주로 값을 생성하거나 제공하는 데 사용됩니다.
import java.util.function.Supplier;
public class SupplierExample {
public static void main(String[] args) {
Supplier<String> supplyString = () -> "Hello, Supplier!";
System.out.println(supplyString.get()); // 출력: Hello, Supplier!
// 다른 예시: 현재 시간 제공
Supplier<Long> currentTime = () -> System.currentTimeMillis();
System.out.println(currentTime.get()); // 출력: 현재 시간 밀리초
}
}
5. BinaryOperator<T>
BinaryOperator<T>는 동일한 타입의 두 인수를 받아 동일한 타입의 출력을 반환하는 함수형 인터페이스입니다. BiFunction<T, U, R>의 특수한 경우로, 인수와 반환 타입이 동일한 경우입니다.
import java.util.function.BinaryOperator;
public class BinaryOperatorExample {
public static void main(String[] args) {
BinaryOperator<Integer> sum = (a, b) -> a + b;
System.out.println(sum.apply(2, 3)); // 출력: 5
// 다른 예시: 문자열 합치기
BinaryOperator<String> concatenate = (s1, s2) -> s1 + s2;
System.out.println(concatenate.apply("Hello", " World")); // 출력: Hello World
}
}
6. UnaryOperator<T>
UnaryOperator<T>는 단일 인수를 받아 동일한 타입의 출력을 반환하는 함수형 인터페이스입니다. Function<T, R>의 특수한 경우로, 입력과 반환 타입이 동일한 경우입니다.
import java.util.function.UnaryOperator;
public class UnaryOperatorExample {
public static void main(String[] args) {
UnaryOperator<Integer> square = x -> x * x;
System.out.println(square.apply(4)); // 출력: 16
// 다른 예시: 문자열 대문자로 변환
UnaryOperator<String> toUpperCase = s -> s.toUpperCase();
System.out.println(toUpperCase.apply("hello")); // 출력: HELLO
}
}
7. BiFunction<T, U, R>
BiFunction<T, U, R>는 두 개의 인수를 받아 다른 타입의 출력을 반환하는 함수형 인터페이스입니다.
import java.util.function.BiFunction;
public class BiFunctionExample {
public static void main(String[] args) {
BiFunction<Integer, Integer, String> sumToString = (a, b) -> "Sum: " + (a + b);
System.out.println(sumToString.apply(2, 3)); // 출력: Sum: 5
// 다른 예시: 두 문자열을 합치고 길이 반환
BiFunction<String, String, Integer> combineLength = (s1, s2) -> (s1 + s2).length();
System.out.println(combineLength.apply("Hello", " World")); // 출력: 11
}
}
결론
Java의 주요 함수형 인터페이스는 코드의 재사용성과 가독성을 크게 향상시킬 수 있습니다. Predicate, Function, Consumer, Supplier, BinaryOperator, UnaryOperator, BiFunction 등의 함수형 인터페이스를 적절히 활용하면 더 간결하고 명확한 코드를 작성할 수 있습니다. 이 인터페이스들은 람다 표현식과 함께 사용되며, Java 8에서 도입된 스트림 API와도 잘 어울립니다. 이를 통해 Java의 강력한 함수형 프로그래밍 기능을 최대한 활용할 수 있습니다.
'개발 > java' 카테고리의 다른 글
java.lang.nullpointerexception 오류 예방 (0) | 2023.03.28 |
---|---|
Java Generics (0) | 2022.02.25 |
Stream 예제 (0) | 2022.02.06 |
JSch를 사용한 JAVA SFTP 업로드 다운로드 예제 (개인키, 패스워스) (3) | 2021.08.18 |
현재 날짜 출력, 시간 원하는 형태로 출력, 날짜 포맷 (0) | 2021.01.18 |
댓글