链接地址:http://www.xx566.com/detail/132.html
在上一篇Guava库学习:函数编程(二)使用Predicate和Predicates进行对象过滤中, 我们学习Predicate和Predicates,用于进行对象的过滤,通过Function和Predicate接口,我们可以在Java中达到函数 式编程的效果,在Guava的函数编程中,还有另一个重要的:Supplier和Suppliers,使用Supplier我们可以对传入的对象进行包装 构建后再输出,接下来,我们就来了解一下Supplier和Suppliers。
翻开Supplier接口的源码,及其简单,只有一个方法T get(),只用来返回T类型的一个实例,返回的对象可能是一个新的实例,也可能不是,取决于具体的实现。Supplier接口灵活的提供了一种懒加载机 制,只有在get方法被调用的时候才去构造实例。另外,由于Supplier是一个接口,相比较静态工厂方法创建对象,Supplier也更加容易。
首先我们来看下面一个例子,代码如下:
static class Girl { int age; String face; Girl(int age, String face) { this.age = age; this.face = face; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getFace() { return face; } public void setFace(String face) { this.face = face; } } @Test public void testSupplier() { Supplier<Predicate<String>> supplier = new Supplier<Predicate<String>>() { @Override public Predicate<String> get() { Map<String, Girl> map = new HashMap<String, Girl>() { { put("love the age", new Girl(18, "not so nice")); put("love the face", new Girl(16, "so nice")); } }; Function<String, Girl> function = Functions.forMap(map); Predicate<Girl> predicate = new Predicate<Girl>() { @Override public boolean apply(Girl input) { return input.getAge() >= 18; } }; Predicate<String> result = Predicates.compose(predicate, function); return result; } }; System.out.println(supplier.get().apply("love the age"));//true System.out.println(supplier.get().apply("love the face"));//false }
在这个例子中,我们使用了Functions.forMap来创建一个Function实例,用来转换Map集合中的Girl对象,之后,使用一个 Predicate实例来过滤年纪未满18岁的Girl对象,接下来,我们使用Function和Predicate作为参数传递到 Predicates.compose方法,进行组合,返回一个Predicate实例,我们可以通过Supplier.get方法货物到 Predicate,通过apply方法查看过滤结果。
与Function和Supplier类似,Guava内部也对Supplier做了实现,提供了Suppliers工具类,Suppliers提供了许多方法来获取Supplier实例,翻看源码,我们看到以下方法,如下:
compose( Function<? super F, T> function, Supplier<F> supplier):返回一个新的,由传入的Function和Supplier组成的Supplier实例。
memoize(Supplier<T> delegate):返回第一个调用缓存实例的Supplier,检索在随后的调用并返回该值。
memoizeWithExpiration( Supplier<T> delegate, long duration, TimeUnit unit):返回一个缓存的Supplier实例由传入的Supplier提供,设置缓存失效的时间。
ofInstance(@Nullable T instance):,返回一个Supplier总是接收instance
synchronizedSupplier(Supplier<T> delegate):返回一个Supplier,保证在调用get方法时加锁同步,是线程安全的。
supplierFunction():返回一个Function,接收一个Supplier返回其调用get方法后的结果。
方法很多,具体的作用也不是很清楚,接下来,我们通过代码来重点学习一下memoize和memoizeWithExpiration方法,代码如下:
@Test public void testSuppliers() { Supplier<Predicate<String>> supplier = new Supplier<Predicate<String>>() { @Override public Predicate<String> get() { Map<String, Girl> map = new HashMap<String, Girl>() { { put("love the age", new Girl(18, "not so nice")); put("love the face", new Girl(16, "so nice")); } }; Function<String, Girl> function = Functions.forMap(map); Predicate<Girl> predicate = new Predicate<Girl>() { @Override public boolean apply(Girl input) { return input.getAge() >= 18; } }; Predicate<String> result = Predicates.compose(predicate, function); return result; } }; //Supplier.memoize方法,返回传入参数Supplier的包装类, //当get()方法第一次被调用,Supplier的包裹被创建, //包装类缓存了Supplier实例,并将其返回给调用者 Supplier<Predicate<String>> wrapped = Suppliers.memoize(supplier); System.out.println(wrapped.get().apply("love the age"));//true //Supplier.memoizeWithExpiration方法,设定时间的数值(10l)和单位(TimeUnit.SECONDS) // 返回传入参数Supplier的包装类,当get方法被调用,在指定的时间内, // memoizeWithExpiration作用与memoize相同,包装类缓存Supplier实例给定的时间 Supplier<Predicate<String>> wrapped2 = Suppliers .memoizeWithExpiration(supplier, 10l, TimeUnit.SECONDS); }
总结:到此,Guava的函数式编程已经介绍完毕,我们一次学习了Function、Predicate和Supplier,其实这几个接口的作用,还不 算太清楚,懵懵懂懂,希望在随后的学习中,能够看到Guava对其的应用,或许能够完全的理解,目前只能借助源码的注释和网上些许的资料进行体味了,总 之,Guava真的很棒。