반응형
인터페이스에 함수가 하나라면 @FunctionalInterface을 붙여 람다식으로 활용가능
@FunctionalInterface
interface RunSomething {
void doIt();
}
RunSomething runSomething = new RunSomething() {
@Override
public void doIt() {
System.out.println("Hello, I'm DolphaGo");
}
};
RunSomething runSomething = () -> System.out.println("Hello, I'm DolphaGo")
기본 함수형 인터페이스
Function<Integer,Integer> plus10= (i) -> i+10; // -> UnaryOperator<Integer> plus10 = (i) ->(i+10);
Function<Integer,Integer> multiply2 = (i) -> i*2;
Function<Integer, Integer> func = plus10.andThen(multiply2);
System.out.println(func.apply(2)); // -> 생성된 람다 함수에 2를 넣어 실행(순서대로)
-
리턴값 X
Consumer<Integer> print=(i)-> System.out.println(i); print.accept(10);
-
인자 X
Supplier<Integer> get10 = () -> 10; System.out.println(get10.get());
-
boolean
Predicate<String> startWithDolphaGo = (s) -> s.startsWith("DolphaGo"); System.out.println(startWithDolphaGo.test("DolphaGo's Blog"));
가능한 모든 속성으로 필터링(일반적방법)
private static List<Apple>filterApples(List<Apple> apples, Color color, int weight, boolean flag) {
List<Apple> result=new ArrayList<>();
for(Apple apple:apples){
if((flag && apple.getColor().equals(color)) || (!flag && apple.getWeight()>=weight) ) {
result.add(apple);
}
}
return result;
}
List<Apple> greenApples=filterApples(apples,Color.GREEN,0,true);
List<Apple> largeApples=filterApples(apples,null,150,false);
람다사용, 리스트형식 추상화(함수형)
private static <T> List<T> filter(List<T> list, Predicate<T> p) {
List<T> result = new ArrayList<>();
for (T e : list) {
if (p.test(e))
result.add(e);
}
return result;
}
List<Apple> apples = List.of(new Apple(100, Color.GREEN), new Apple(150, Color.RED));
List<Banana> bananas = List.of(new Banana(100, Color.GREEN), new Banana(150, Color.GREEN));
List<Integer> numbers= List.of(3,6,1,2,3,2,1,6,7,2,3,4,6,4,3,2,34,123);
List<Apple> filteredApples = filter(apples, (Apple apple) -> Color.RED.equals(apple.getColor()));
List<Banana> filteredBananas= filter(bananas,(Banana banana) -> banana.getWeight()>150);
List<Integer> filteredNumbers = filter(numbers, (Integer i) -> i.intValue() % 2 == 0);
특징
형식추론 - 컴파일러는 람다의 시그니처도 추론할 수 있습니다. 결과적으로 컴파일러는 람다 표현식의 파라미터 형식에 접근할 수 있으므로 람다 문법에서 이를 생략할 수 있습니다. (인자의 자료형 생략)
지역 변수 사용 - final로 선언된 지역변수를 body({}안)에서 사용가능
메서드 참조 - 정의를 재활용
list.sort((o1,o2) -> Integer.compare(o1,o2) );
list.sort(Integer::compare);
생성자 참조
Supplier<Apple> supplier = Apple::new;
Apple apple = supplier.get();
Function<Integer, Apple> function = Apple::new;
Apple apple = function.apply(100);
public class AppleComparator implements Comparator<Apple> {
@Override
public int compare(Apple o1, Apple o2) {
return Integer.compare(o1.getWeight(),o2.getWeight());
}
}
apples.sort(new AppleComparator()); //Apple을 weight별로 비교해서 apples를 sort하라
apples.sort(new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return Integer.compare(o1.getWeight(), o2.getWeight());
}
}); //익명 클래스 활용
apples.sort((o1, o2) -> Integer.compare(o1.getWeight(), o2.getWeight()) ); //람다식 사용
apples.sort(Comparator.comparing(Apple::getWeight)); //메서드 참조
유용한 람다 메서드
-
비교에 사용할 키 추출
Comparator<Apple> c = Comparator.comparing(Apple::getWeight)
-
역정렬
apples.sort(comparing(Apple::getWeight).reversed() .thenComparing(Apple::getColor)); //2번째 정렬 포인트 추가
-
Predicate 조합
Predicate<Apple> redApple = apple -> apple.getColor().equals(Color.RED); Predicate<Apple> redAndHeavyAppleOrGreen = redApple.and(apple -> apple.getWeight() > 150) .or(apple -> apple.getColor().equals(Color.GREEN)); Predicate<Apple> negate =redApple.negate();//조건 반전 List<Apple> collect = apples.stream().filter(negate).collect(Collectors.toList());
-
Function 조합
Function<Integer, Integer> f = x -> x + 1; Function<Integer, Integer> g = x -> 2 * x; Function<Integer,Integer> h1= f.andThen(g); //f->g Function<Integer,Integer> h2= g.compose(f); //g->f
728x90
반응형
댓글