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()的执行结果.

Function, Predicate的更多相关文章

  1. guava function and predicate 函数式编程

    @Test public void function(){ List<String> list = Lists.newArrayList("1","2&quo ...

  2. java8 array、list操作 汇【2】)- (Function,Consumer,Predicate,Supplier)应用

    static class UserT { String name; public UserT(String zm) { this.name=zm; } public String getName() ...

  3. 函数式接口的使用 (Function、Predicate、Supplier、Consumer)

    参考:https://blog.csdn.net/jmj18756235518/article/details/81490966 函数式接口 定义:有且只有一个抽象方法的接口 Function< ...

  4. Java8-四个函数式接口(Consumer,Supplier,Predicate,Function)

    Java8---函数式接口 Consumer---消费者(accept方法,Lambda与方法引用返回都是Consumer) Supplier---供给型(get方法,返回数据,与Optional可以 ...

  5. Predicate接口和Consumer接口

    Predicate和Consumer接口是集合操作中常用到的俩个接口: 1.Predicate public interface Predicate<T>{ boolean test(T ...

  6. Java 8 基础教程 - Predicate

    在Java 8中,Predicate是一个函数式接口,可以被应用于lambda表达式和方法引用.其抽象方法非常简单: /** * Evaluates this predicate on the giv ...

  7. Java 8 新特性:4-断言(Predicate)接口

    (原) 这个接口主要用于判断,先看看它的实现,说明,再给个例子. /* * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All ri ...

  8. Java8 Predicate

    code: package com.qhong; import java.util.ArrayList; import java.util.Arrays; import java.util.List; ...

  9. STL - Predicate - Binary Predicate(双参判断式)

    Binary Predicate(双参判断式)的用途是:比较两个参数的特定属性 我们先建一个领域模型类: Person.h #ifndef _Domain_Models_Person_H_ #defi ...

随机推荐

  1. PostgreSQL Replication之第十二章 与Postgres-XC一起工作(6)

    12.6 添加节点 Postgres-XC允许您在那个过程中的任何一个时间点添加新的服务器到计划中.所有您需要做的是按照我们之前演示的设置一个节点,并在 控制器上调用CREATE NODE.然后,该系 ...

  2. Lintcode: Minimum Adjustment Cost

    Given an integer array, adjust each integers so that the difference of every adjcent integers are no ...

  3. 转:Selenium之CSS Selector定位详解

    CSS selector定位 CSS(Cascading Style Sheets)是一种语言,它被用来描述 HTML 和 XML 文档的样式.  百度输入框: <input name=&quo ...

  4. codevs 1506 传话

    http://codevs.cn/problem/1506/ 1506 传话  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver 题解       题目描述 D ...

  5. several生命周期

    several生命周期 1. 实例化: 容器调用servlet创建servlet对象 2. 初始化: <init-param> <param-name> company < ...

  6. JSP 中 forward 和 redirect 的区别_2014.12.31

    重定向,只能访问工程下(WebRoot文件夹)的页面,不能访问到内部(WEB_INF文件夹)的页面 1.从地址栏显示来说:forward浏览器显示路径不变,redirect浏览器显示路径改变forwa ...

  7. dtree的使用和扩展

    相信用过dtree的童靴的不在少数,网络上流传的JS树有很多,例如雪花树MzTreeView,EXT.Struts2出来之后,也有自己的树控件,但是这么多风姿卓约的倩影中,我独爱,独爱dtree那一棵 ...

  8. 夺命雷公狗---node.js---5net模块玩telnet通信(中)

    我们理论知识太多还不如实战,我们来写一个可以通过telnet腾讯的小玩意玩玩: var net = require('net'); var ChatServer = net.createServer( ...

  9. 各种类型的Writable(Text、ByteWritable、NullWritable、ObjectWritable、GenericWritable、ArrayWritable、MapWritable、SortedMapWritable)转

    java原生类型 除char类型以外,所有的原生类型都有对应的Writable类,并且通过get和set方法可以他们的值. IntWritable和LongWritable还有对应的变长VIntWri ...

  10. 视频处理控件TVideoGrabber中如何混合多个视频源(1)

    其实一个或是几个作为普通的视频源使用的TVideoGrabber组件,可以进行混合来作为一个TVideoGrabber组件使用,这些普通的组件可以是视频捕捉设备或是视频剪辑等.同时这个混合的组件独立于 ...