第三章(6)复合Lambda表达式

     你可以把多个简单的Lambda复合成复杂的表达式。比如,你可以让两个谓词之间做一个or操作,组合成一个更大的谓词。而且,你还可以让一个函数的结果成为另一个函数的输入。你可能会想,函数式接口中怎么可能有更多的方法呢?(毕竟,这违背了函数式接口的定义啊!)窍门在于,我们即将介绍的方法都是默认方法,也就是说它们不是抽象方法。我们会在第9章详谈。

1.比较器复合

我们之前说到,比较一个列表中苹果的重量,可以像下面这样做:

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Apple a1 = new Apple("国光",33);
        Apple a2 = new Apple("富士",21);
        Apple a3 = new Apple("黄元帅", 12);
        List<Apple> apples = new ArrayList<Apple>();
        apples.add(a1);
        apples.add(a2);
        apples.add(a3);
        apples.sort(Comparator.comparing(Apple::getWeight));
        for(Apple a:apples){
        	System.out.println(a.getWeight());
        }
	}

}

(1)逆序 

然而我们想要逆序,该要如何操作呢?可以像下面这样做:

apples.sort(Comparator.comparing(Apple::getWeight).reversed());

(2)比较器琏

但如果发现有两个苹果一样重怎么办?哪个苹果应该排在前面呢?你可能需要再提供一个Comparator来进一步定义这个比较。比如,在按重量比较两个苹果之后,你可能想要按苹果的其他属性排序。thenComparing方法就是做这个用的。它接受一个函数作为参数(就像comparing方法一样),如果两个对象用第一个Comparator比较之后是一样的,就提供第二个Comparator。你又可以优雅地解决这个问题了:

apples.sort(Comparator.comparing(Apple::getWeight).reversed().thenComparing(Apple::getName));

2.复合谓词

谓词接口包括三个方法:negate、and和or,让你可以重用已有的Predicate来创建更复杂的谓词。

(1)negate非,取反

Predicate<Apple> predicate = apple->"绿光".equals(apple.getName());
List<Apple> apps = Test.getApple(apples, predicate.negate());//取的是名字不是绿光的苹果

 这种复合谓词的起始调用位置无法直接通过lambda表达式调用,只能通过lambda实现的接口示例进行一次起始调用,随后便可以随意玩:

Predicate<Apple> predicate = apple->"绿光".equals(apple.getName());
List<Apple> apps = Test.getApple(apples,predicate.and(apple>20>apple.getWeight()).or(apple->apple.getName().length()>5));

3.函数复合

     最后,你还可以把Function接口所代表的Lambda表达式复合起来。Function接口为此配了andThen和compose两个默认方法,它们都会返回Function的一个实例。andThen方法会返回一个函数,它先对输入应用一个给定函数,再对输出应用另一个函数。比如,假设有一个函数f给数字加1 (x -> x + 1),另一个函数g给数字乘2,你可以将它们组合成一个函数h,先给数字加1,再给结果乘2:

Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.andThen(g);
System.out.println(h.apply(3));//打印出8

 你也可以类似地使用compose方法,先把给定的函数用作compose的参数里面给的那个函数,然后再把函数本身用于结果。比如在上一个例子里用compose的话,它将意味着f(g(x)),而andThen则意味着g(f(x)):

Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.compose(g);
System.out.println(h.apply(3));//输出7

猜你喜欢

转载自blog.csdn.net/qq564425/article/details/81460694