Ch14-7~8. function 패키지
0. 목차
Chapter14. 람다와 스트림
Ch14 - 7. java.util.function 패키지
Ch14 - 8. java.util.function 패키지 예제
Ch14 - 7. java.util.function 패키지
▶ java.util.function 패키지란?
▷ 자주 사용되는 다양한 함수형 인터페이스를 제공
▷ 우리는 가져와서 사용 : 편리함
▶ java.util.function 패키지 : 매개변수 1개
▷ 함수형 인터페이스 : java.lang.Runnable
▷ 메서드 : void run()
- 매개변수 無, 반환값 無
▷ 함수형 인터페이스 : Supplier<T>
▷ 메서드 : T get() → T
- 매개변수 無, 반환값 有
▷ 함수형 인터페이스 : Consumer<T>
▷ 메서드 : -T→ void accept{T t}
- Supplier와 반대
- 매개변수 有, 반환값 無
▷ 함수형 인터페이스 : Function<T, R>
▷ 메서드 : -T→ R apply{T t} → R
- 일반적인 함수
- 하나의 매개변수를 받아 결과를 반환
▷ 함수형 인터페이스 : Predicate<T>
▷ 메서드 : -T→ boolean test{T t} → boolean
- 조건식 표현에 사용
- 매개변수는 하나, 반환 타입은 boolean
Predicate<String> isEmptyStr = s -> s.length() == 0; // s(String)를 받아서 길이가 '0'이면 true를 반환 Stirng s = ""; if (isEmptyStr.test(s)) // 위의 람다식 이름이 test, 그래서 이 코드는 if (s.length() == 0) System.out.println("This is an empty String.");
▶ java.util.function 패키지 : 매개변수 1개 퀴즈
▶ 알맞은 함수형 인터페이스(java.util.function 패키지)는?
▷ 퀴즈1
f = () -> (int)(Math.random() * 100) + 1;
- 매개변수 無, 반환값 int
Supplier<Integer>
▷ 퀴즈2
f = i -> System.out.println(i + ", ");
- 매개변수 int, 반환값 無
Consumer<Integer>
▷ 퀴즈3
f = i -> i % 2 == 0;
- 조건식
- 매개변수 int, 반환값 boolean
Predicate<Integer>
▷ 퀴즈4
f = i -> i / 10 * 10;
- 매개변수 int, 반환값 int
Function<Integer, Integer>
▶ java.util.function 패키지 : 매개변수 2개
▷ 함수형 인터페이스 : BiConsumer<T, U>
▷ 메서드 : -T, U→ void accept(T t, U u)
- 매개변수 2개 有, 반환값 無
▷ 함수형 인터페이스 : BiPredicate<T, U>
▷ 메서드 : -T, U→ boolean test(T t, U u) → boolean
- 조건식 표현에 사용
- 매개변수 2개 有, 반환값 boolean
▷ 함수형 인터페이스 : BiFunction<T, U, R>
▷ 메서드 : -T, U→ R apply(T t, U u) → R
- 매개변수 2개를 받아 하나의 결과를 반환
▶ java.util.function 패키지 : 매개변수 3개
▷ 매개변수 3개 이상 부터는 직접 만들어 사용
@FunctionalInterface
interface TriFunction<T, U, V, R> { // 매개변수 3개, R은 반환 타입
R apply(T t, U u, V v);
}
▶ java.util.function 패키지 : 매개변수 타입 == 반환 타입
▷ 함수형 인터페이스 : UnaryOperator<T>
▷ 메서드 : -T→ T apply(T t) → T
- Function의 자손
-
Function과 달리 매개변수와 결과의 타입이 같음
- UnaryOperator Code
@FunctionalInterface public interface UnaryOperator<T> extends Function<T> { // Function을 상속 static <T> UnaryOperator<T> identity() { // identity : 항등 함수 return t -> t; // t를 넣으면 t 그대로 반환 } }
▷ 함수형 인터페이스 : BinaryOperator<T>
▷ 메서드 : -T, T→ T apply(T t, T t) → T
- BiFunction의 자손
- BiFunction과 달리 매개변수와 결과의 타입이 같음
Ch14 - 8. java.util.function 패키지 예제
▶ 람다식 생성
▷ 1 ~ 100 난수 추출 람다식
▷ Supplier<Integer>
Supplier<Integer> s = ()-> (int)(Math.random() * 100) + 1;
▷ i, i, i 이런 식으로 나열하는 람다식
▷ Consumer<Integer>
Consumer<Integer> c = i -> System.out.print(i + ", ");
▷ 짝수 검사 람다식
▷ Predicate<Integer>
Predicate<Integer> p = i -> i % 2 == 0;
▷ 1의 자리 삭제 람다식
▷ Function<Integer, Integer>
Function<Integer, Integer> f = i -> i / 10 * 10; // i의 일의 자리 삭제
▶ main 메서드
▷ 짝수 난수의 일의 자리 0으로 바꾸어 출력
public static void main(String[] args) {
// 람다식 ...
List<Integer> list = new ArrayList<>(); // list 생성
makeRandomList(s, list); // list를 1 ~ 100 중 난수로 채움
System.out.println(list); // list 출력
printEvenNum(p, c, list); // list의 난수 중 짝수 검사 → 짝수만 출력
List<Integer> newList = doSomething(f, list); // list의 짝수 일의 자리 삭제
System.out.println(newList); // 최종 list 출력
}
▶ doSomething 메서드
▷ 짝수 난수를 받아 1의 자리 삭제하는 메서드
// i의 일의 자리 삭제 : Function<Integer, Integer> f = i -> i / 10 * 10;
static <T> List<T> doSomething(Function<T, T> f, List<T> list) {
List<T> newList = new ArrayList<T>(list.size());
for(T i : list) {
newList.add(f.apply(i)); // 일의 자리 삭제 후 newList에 저장
}
return newList;
}
▶ printEvenNum 메서드
▷ 난수가 짝수인지 검사 후,
▷ [i, i, i] 이런 식으로 배열하여 출력하는 메서드
// 짝수 검사 : Predicate<Integer> p = i -> i % 2 == 0;
// 배열 : Consumer<Integer> c = i -> System.out.print(i + ", ");
static <T> void printEvenNum(Predicate<T> p, Consumer<T> c, List<T> list) {
System.out.print("[");
for(T i : list) {
if(p.test(i)) // 짝수 검사
c.accept(i); // 배열
}
System.out.println("]");
}
▶ makeRandomList 메서드
▷ 난수를 얻는 메서드
static <T> void makeRandomList(Supplier<T> s, List<T> list) {
for(int i=0;i<10;i++) {
list.add(s.get());
}
}
▷ 전체
import java.util.function.*;
import java.util.*;
class Ex14_2 {
public static void main(String[] args) {
Supplier<Integer> s = ()-> (int)(Math.random()*100)+1;
Consumer<Integer> c = i -> System.out.print(i+", ");
Predicate<Integer> p = i -> i%2==0;
Function<Integer, Integer> f = i -> i/10*10;
List<Integer> list = new ArrayList<>();
makeRandomList(s, list);
System.out.println(list);
printEvenNum(p, c, list);
List<Integer> newList = doSomething(f, list);
System.out.println(newList);
}
static <T> List<T> doSomething(Function<T, T> f, List<T> list) {
List<T> newList = new ArrayList<T>(list.size());
for(T i : list) {
newList.add(f.apply(i));
}
return newList;
}
static <T> void printEvenNum(Predicate<T> p, Consumer<T> c, List<T> list) {
System.out.print("[");
for(T i : list) {
if(p.test(i))
c.accept(i);
}
System.out.println("]");
}
static <T> void makeRandomList(Supplier<T> s, List<T> list) {
for(int i=0;i<10;i++) {
list.add(s.get());
}
}
}
// console
[16, 43, 70, 91, 74, 77, 58, 83, 13, 21] // 난수 받자마자
[16, 70, 74, 58, ] // 난수가 짝수인지 검사
[10, 40, 70, 90, 70, 70, 50, 80, 10, 20] // 일의 자리 0으로 바꿈