Function, Predicate的使用
Function用于把一种类型的对象转化为另一种类型的对象.
Predicate用于判断某个对象是否符合一定条件.
一.Function和Functions
在java开发中, 我们经常需要对一些对象进行处理, 然后返回我们想要的结果, 比如说:对日期进行格式化, 获取字符串等等.在guava中, 我们可以通过实现Function接口来实现类似的需求, 如下:
import com.google.common.base.Function; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by xinfengyao on 16-2-22. */ public class FunctionTest { public static void main(String[] args) { Function<Date, String> function = new Function<Date, String>() { @Override public String apply(Date date) { return new SimpleDateFormat("yyyy-MM-dd").format(date); } }; System.out.println(function.apply(new Date())); } }
打印结果为:
2016-02-22
我们看到, 调用Function接口中的apply()方法, 将我们想要处理的对象作为输入参数, 返回结果就是处理后我们想要的. Function接口中, 其实有两个方法, 我们一般只关心apply()方法.
package com.google.common.base; import com.google.common.annotations.GwtCompatible; import javax.annotation.Nullable; @GwtCompatible public interface Function<F, T> { @Nullable T apply(@Nullable F var1); boolean equals(@Nullable Object var1); }
多数情况下, 我们需要自己实现Function接口, 以满足不同的需求. 不过Guava提供了工具类Functions, 其中包含了一些常用的Function实现. Functions中最重要的两个方法是forMap()和compose(). 通过实例代码, 学习这两个方法:
import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.collect.Maps; import java.util.Map; /** * Created by xinfengyao on 16-2-22. */ public class FunctionsTest { public static void main(String[] args) { Map<String, Integer> map = Maps.newHashMap(); map.put("aaa", 1); map.put("bbb", 2); Function<String, Integer> function = Functions.forMap(map); /** * 调用apply()方法, 可以通过key获取对应的value * 当传给apply()中的key在map中不存在时, 就会抛出异常IllegalArgumentException */ System.out.println(function.apply("aaa")); /** * 我们可以通过forMap()另一个重载方法避免抛出异常, 当key不存在时, 设置一个默认值 */ function = Functions.forMap(map, 0); System.out.println(function.apply("ccc")); /** * 有时候我们需要通过多个Function进行组合, 这时我们就需要用到compose()方法 */ Function<Integer, Integer> function2 = new Function<Integer, Integer>() { @Override public Integer apply(Integer input) { return input * input; } }; /** * 将上面map中的值进行平方运算, 注意compose()方法中的输入参数的顺序不能颠倒: * Function<A, C> compose(Function<B, C> g, Function<A, ? extends B> f) */ Function<String, Integer> result = Functions.compose(function2, function); System.out.println(result.apply("bbb")); } }
运行结果:
1 0 4
通过运行结果, 我们能够看到compose()方法的内部执行过程: 假定Fuctions.compose()方法返回的Function为function1, compose()的第一个参数为function2, 第二个参数为function3, 那么调用function1.apply()方法时, 输入参数会传给function3的apply()方法, function3.apply()方法的返回结果作为function2.apply()方法的入参, function2.apply()方法的返回结果就是function1.apply()方法的执行结果.
二.Predicate和Predicates
如果说Function主要用于对象的转换, 那么Predicate则主要用作对象的过滤和筛选. Predicate和Function一样, 也有两个方法, 我们主要关心apply()方法.
package com.google.common.base; import com.google.common.annotations.GwtCompatible; import javax.annotation.Nullable; @GwtCompatible public interface Predicate<T> { boolean apply(@Nullable T var1); boolean equals(@Nullable Object var1); }
通过下面这个例子学习Predicate的使用:
/** * Created by xinfengyao on 16-2-22. */ public class Person { private String name; private int age; private int height; // 省略getter和setter方法, 构造方法 }
import com.google.common.base.Predicate; /** * Created by xinfengyao on 16-2-22. */ public class PredicateTest { public static void main(String[] args) { Predicate<Person> predicate = new Predicate<Person>() { @Override public boolean apply(Person person) { return person.getAge() > 18; } }; Person person = new Person("tom", 23, 175); System.out.println(predicate.apply(person)); } }
打印结果:
true
与Function类似, Predicate也有对应的工具类Predicates. 下面来学习几个比较重要的方法: Predicates.not(), Predicates.or(), Predicates.and(), Predicates.compose()
import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Maps; import java.util.Map; /** * Created by xinfengyao on 16-2-22. */ public class PredicatesTest { public static void main(String[] args) { Predicate<Person> predicate1 = new Predicate<Person>() { @Override public boolean apply(Person person) { return person.getAge() > 18; } }; Predicate<Person> predicate2 = new Predicate<Person>() { @Override public boolean apply(Person person) { return person.getHeight() > 175; } }; Person person = new Person("Jack", 25, 170); Predicate<Person> predicate3 = Predicates.and(predicate1, predicate2); System.out.println(predicate3.apply(person)); Predicate<Person> predicate4 = Predicates.not(predicate1); System.out.println(predicate4.apply(person)); Predicate<Person> predicate5 = Predicates.or(predicate1, predicate2); System.out.println(predicate5.apply(person)); Map<String, Person> personMap = Maps.newHashMap(); personMap.put("marry", new Person("marry", 21, 165)); personMap.put("bob", new Person("bob", 25, 180)); Predicate<String> predicate6 = Predicates.compose(predicate2, Functions.forMap(personMap)); System.out.println(predicate6.apply("marry")); } }
运行结果:
false false true false
Predicates.compose()方法运行过程: 假定Predicates.compose()返回predicate1, compose()的第一个参数为predicate2, 第二个参数为function1; 则当调用predicate1.apply()方法时, 输入参数传递给function1, function1的返回结果作为predicate2的输入参数, predicate2的返回结果就是predicate1.apply()的执行结果.