Function
@FunctionalInterface public interface Function<T, R> { /** * Applies this function to the given argument. *@paramt the function argument *@return the function result */ R apply(T t); ... }
한 타입을 다른 타입으로 매핑한다.
같은 타입이면서 같은 값을 반환하는 함수를 Identity 함수라고 한다. t→t
package demo.tv.kevin.episode_02.example; import java.util.function.Function; public class FunctionExample { public static void main(String[] args) { Function<String, String> identityFunc1 = new Function<String, String>() { @Override public String apply(String s) { return s; } }; Function<String, String> identityFunc2 = s -> s; //identity function Function<String, String> identityFunc3 = Function.identity(); Function<String, Integer> toInt1 = s -> Integer.parseInt(s); Function<String, Integer> toInt2 = Integer::parseInt; String hello = identityFunc1.apply("hello"); System.out.println("hello = " + hello); } }
Consumer
, The Spartan, Give them nothing but Take from them Everything
@FunctionalInterface public interface Consumer<T> { /** * Performs this operation on the given argument. * * @param t the input argument */ void accept(T t); ... }
전달 받은 인자를 사용하기만 하고 리턴은 없음!
package demo.tv.kevin.episode_02.example; import java.util.function.Consumer; import java.util.function.Function; public class ConsumerExample { public static void main(String[] args) { final Consumer<String> printer1 = System.out::println; final Function<String,Void> printer2 = s -> { System.out.println(s); return null; }; printer1.accept("hello"); printer2.apply("hello"); } }
Predicate
, The Judge
@FunctionalInterface public interface Predicate<T> { /** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); ... }
Function인데 리턴 타입이 primitive boolean 으로 고정된 Function
package demo.tv.kevin.episode_02.example; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; public class PredicateExample { public static void main(String[] args) { Predicate<String> isAlphabetical1 = s -> s.matches("[a-zA-Z]+"); Predicate<String> isAlphabetical2 = PredicateExample::alphabetTest; System.out.println(isAlphabetical1.test("가나다")); System.out.println(isAlphabetical1.test("abc")); Predicate<Integer> isPositive = i -> i > 0; System.out.println(isPositive.test(-1)); System.out.println(isPositive.test(1)); List<Integer> numbers = Arrays.asList(-5,-4,-3,-2,-1,1,2,3,4); long count = numbers.stream().filter(isPositive).count(); System.out.println("count = " + count); List<Integer> positiveNums = filter(numbers, isPositive); List<Integer> lessThan3 = filter(numbers, i -> i < 3); System.out.println("positiveNums = " + positiveNums); System.out.println("lessThan3 = " + lessThan3); } private static boolean alphabetTest(String s) { return s.matches("[a-zA-Z]+"); } private static <T> List<T> filter(List<T> list, Predicate<T> filter){ List<T> result = new ArrayList<>(); for(T input : list){ if(filter.test(input)){ result.add(input); } } return result; } }
Supplier
, The Master of Lazy
@FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); }
T 타입의 인스턴스를 제공
package demo.tv.kevin.episode_02.example; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; /** * Supplier - The Master of Lazy */ public class SupplierExample { public static void main(String[] args) { Supplier<String> helloSupplier = () -> "hello"; System.out.println(helloSupplier.get()+" world"); long start = System.currentTimeMillis(); // printIfValidIndex(0, getVeryExpensiveValue()); // printIfValidIndex(-1, getVeryExpensiveValue()); // printIfValidIndex(-2, getVeryExpensiveValue()); printIfValidIndexSupplier(0, ()->getVeryExpensiveValue()); printIfValidIndexSupplier(-1, ()->getVeryExpensiveValue()); printIfValidIndexSupplier(-2, ()->getVeryExpensiveValue()); long end = System.currentTimeMillis(); System.out.println("spend time : " + (end - start) + "ms"); } static void printIfValidIndex(int number, String value){ if (number >= 0){ System.out.println("The value is " + value +"."); } else{ System.out.println("Invalid"); } } static void printIfValidIndexSupplier(int number, Supplier<String> valueSupplier){ if (number >= 0){ System.out.println("The value is " + valueSupplier.get() +"."); } else{ System.out.println("Invalid"); } } static String getVeryExpensiveValue(){ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } return "Kevin"; } }
서플라이어를 제공하는것 만으로 Lazy Evaluation이 가능해진다.
기존 9초 → 3초