Guava库学习:函数编程(三)使用Supplier和Suppliers进行对象的包装构建

    链接地址: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真的很棒。

你可能感兴趣的:(guava,对象包装,Supplier,Suppliers)