`

Guava Function Predicate 类函数式编程

阅读更多

 最近在学习使用guava, 一个非常优秀的开源项目,是对jdk一个非常有力的补充,我看上guava的是能使代码更简洁,良好的代码风格

 

首先来介绍一下com.google.common.base包中的常用类

 

1 Function

   guava提供了类函数式的编程,其中的代码就是提供了Function, Predicate接口,及工具类Functions, Predicates

Function 主要用来不同类型的对象之间的转换,下面是一个demo

首先定义一个JavaBean

class User {
    private String username;

    private String sex;

    public User (String username, String sex) {
        this.username = username;
        this.sex = sex;
    }

    void setUsername(String username) {
        this.username = username;
    }

    void setSex(String sex) {
        this.sex = sex;
    }

    String getUsername() {

        return username;
    }

    String getSex() {
        return sex;
    }
}

 然后写测试方法:

    public static void main (String[] args) {
        User u1 = new User("malone", "man");
        User u2 = new User("lanlan", "woman");
        List<User> list = Lists.newArrayList(u1, u2);
        Collection<String> result = Collections2.transform(list, new Function<User, String> () {
            @Override
            public String apply(User user) {
                if (Objects.equals(user, null)) {
                    return "";
                }
                return user.toString();
            }
        });
    }

 使用guava提供的工具类调用transform方法,可实现User到String的集合转换,实际上转换时,调用的是apply方法,工具类Lists,Maps均可接收Function参数,来实现对象转换;如果需要多次转换,可以使用Functions把多个Function整合到一起

 

可以使用Function作为参数的工具类有:Collections2,Lists, Maps, Iterators

 

2 Predicate

   此接口的实现主要是用来过滤集合中不需要的对象,下面是一个demo

Collection<User> resultUser = Collections2.filter(list, new Predicate<User>() {
            @Override
            public boolean apply(User user) {
                if (Objects.equals(user, null)) {
                    return false;
                }
                if (Objects.equals(user.getSex(), "woman")) {
                    return false;
                }
                return true;
            }
        });

 想要过滤掉的对象,只要在apply中判断对应的逻辑,想过滤掉的对象返回false,即不存在结果集中

 

3 Functions
    toStringFunction() :返回 Function<Object, String> ,该 Function apply(Object o) 方法调用了参数 o toString() 方法。 apply(Object o) 的参数 o 如果为 null ,会抛出异常。
    identity() :返回 Function<E, E> ,该 Function apply(Object o) 方法直接返回参数 o

    forMap(Map<K, V> map) :返回 Function<K, V> ,该 Function apply(K key) 方法在 map 中查找键值为参数 key value ,并返回 value ,如果 key 不在 map 中会抛出异常。

 

    forMap(Map<K, ? extends V> map @Nullable V defaultValue) :与上面的方法类似,但是如果 apply() 方法的参数 key 不在 map 中,会返回 defaultValue

 

    compose(Function<B, C> g, Function<A, ? extends B> f) :返回 Function<A, C> ,该 Function 定义的方法是方法 g 和方法 f 的组合,对于输入参数,先对其调用方法 f ,然后对结果调用方法 g

 

    forPredicate(Predicate<T> predicate) :返回 Function<T, Boolean> ,将一个 Predicate 转换为 Function ,该 Function 返回值与 Predicate 相同。

 

    constant(@Nullable E value) :返回 Function<Object, E> ,该 Function 返回常量 value

    下面是一个demo

 

    public static void main (String[] args) {
        User u1 = new User("malone", "man");
        User u2 = new User("lanlan", "woman");
        List<User> list = Lists.newArrayList(u1, u2);
        Function<User, String> f1 = new Function<User, String> () {
            @Override
            public String apply(User user) {
                if (Objects.equals(user, null)) {
                    return "";
                }
                return user.getUsername();
            }
        };
        //多个工具类均可使用类函数式编程
        Collection<String> result = Collections2.transform(list, f1);
        List<String> strList = Lists.transform(list, f1);
        Iterators.transform(list.iterator(), f1);
        Function<String, String> f2 = new Function<String, String> () {
            @Override
            public String apply(String input) {
                if (Objects.equals(input, "malone")) {
                    return "malone's function";
                } else {
                    return "lanlan's function";
                }
            }
        };
        //连接多个Function
        Function<User, String> f3 = Functions.compose(f2, f1);
        List<String> mylist = Lists.transform(list, f3);
        System.out.println(mylist.get(0));

        Map<String, String> map = Maps.newHashMap();
        map.put("1", "2");
        //Functions可以转换一下map,使用语义更直白的代码,并提供默认值支持
        Function<String, String> lookup = Functions.forMap(map, "default value");
        System.out.println(lookup.apply("hi"));

    }

 

 

4 Predicates 常用方法

   and(), or() 下面是一个demo

 

    public static void main (String[] args) {
        User u1 = new User("malone", "man");
        User u2 = new User("lanlan", "woman");
        User u3 = new User("mama", "woman");
        List<User> userList = Lists.newArrayList(u1, u2, u3);
        Predicate<User> p1 = new Predicate<User> () {
            @Override
            public boolean apply(User user) {
                if (user == null) {
                    return false;
                }
                if (Objects.equals(user.getUsername(), "malone")) {
                    return false;
                }
                return false;
            }
        };
        Predicate<User> p2 = new Predicate<User> () {
            @Override
            public boolean apply(User user) {
                if (user == null) {
                    return false;
                }
                if (Objects.equals(user.getUsername(), "lanlan")) {
                    return false;
                }
                return false;
            }
        };
        //同时判断是否满足两个Predicate
        Predicate<User> unionPredicate = Predicates.and(p1, p2);
        List<User> newUserList = Lists.newArrayList(Iterators.filter(userList.iterator(), unionPredicate));
        System.out.println(newUserList.size());
        //判断是否满足两个Predicate的任何一个
        Predicate<User> unionPredicate1 = Predicates.or(p1, p2);
        List<User> newUserList1 = Lists.newArrayList(Iterators.filter(userList.iterator(), unionPredicate1));
        System.out.println(newUserList1.size());
    }

    and方法的作用是要满足所有and参数的Predicate逻辑才会返回true

    or方法的作用是要满足and参数的Predicate任意一个逻辑才会返回true

 

5 Converter

   前面说到的Function用在集合中的对象互相转换上,那么单个对象的转换函数式支持呢,就是使用Converter

   首先在增加一个dto的定义UserDto:

 

class UserDto {
    private String name;
    private String userSex;

    public UserDto() {}

    public UserDto(String name, String userSex) {
        this.name = name;
        this.userSex = userSex;
    }

    void setName(String name) {
        this.name = name;
    }

    void setUserSex(String userSex) {
        this.userSex = userSex;
    }

    String getName() {

        return name;
    }

    String getUserSex() {
        return userSex;
    }
}
 自定义Converter继承Converter类,需要实现doForward(正向转换), doBackward(反向转换)

 

 

    public static void main (String[] args) {

        User user = new User("malone", "man");
        //自定义一个Converter
        Converter<User, UserDto> convertA = new Converter<User, UserDto>() {
            @Override
            protected UserDto doForward(User user) {
                UserDto dto = new UserDto();
                if (Objects.equals(user, null)) {
                    return dto;
                }
                dto.setName(user.getUsername());
                dto.setUserSex(user.getSex());
                return dto;
            }

            @Override
            protected User doBackward(UserDto userDto) {
                User user = new User();
                if (Objects.equals(userDto, null)) {
                    return user;
                }
                user.setSex(userDto.getUserSex());
                user.setUsername(userDto.getName());
                return user;
            }
        };
        //自定义一个Converter
        Converter<UserDto, String> convertB = new Converter<UserDto, String> () {
            @Override
            protected String doForward(UserDto userDto) {
                if (Objects.equals(userDto, null)) {
                    return "null";
                }
                return userDto.getName() + "|" + userDto.getUserSex();
            }

            @Override
            protected UserDto doBackward(String s) {
                if (Objects.equals(s, null)) {
                    return new UserDto("", "");
                }
                List<String> list = Splitter.on("|").splitToList(s);
                return new UserDto(list.get(0), list.get(1));
            }
        };
        //把两个Converter连接成一个转换链条
        Converter<User, String> converC = convertA.andThen(convertB);

        String userStr = converC.convert(user);
        System.out.println(userStr);
        //使用Converse方法实现反转换
        User newUser = converC.reverse().convert(userStr);
        System.out.println(newUser.getUsername() + "|" + newUser.getSex());
    }
   调用andThen方法可以连接多个Converter弄一个转换链条,这个方法的名字起得真奇葩

 

   converse方法Converter<A,B>变成Converter<B,A>
   Converter<A,B> 实现了Function接口,可以在使用Function的地方使用,不过Converter已经废弃了apply方法,不过从源码可以知道,apply的实现是调用了Convert方法
分享到:
评论

相关推荐

    83丨开源实战三(下):借GoogleGuava学习三大编程范式中的函数式编程1

    引入Lambda表达式的作用是简化代码编写;函数接口的作用是让我们可以把函数包裹成函数接口,来实现把函数当做参数一样来使用(Java 不像 C 一样支持函数指针

    Stream API函数式编程和Guava操作

    Stream API常用操作,初步理解stream操作方法,对java8有初步认知。

    google Guava集合工具类(超实用)

    Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这些高质量的 API 可以使你...

    Guava 16.0 API (CHM格式)

    Functional idioms(函数式): 简洁, Guava实现了Java的函数式编程,可以显著简化代码。  五. Concurrency(并发):强大,简单的抽象,让我们更容易实现简单正确的并发性代码。  1. ListenableFuture(可监听的...

    guava_programming.zip

    汪文君Google Guava 代码。Guava之函数式接口、Guava EventBus源码剖析以及优缺点总结

    guava源文档

    guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档guava源文档...

    不加密Google Guava视频教程.txt

    ├─Google Guava 第06讲-Guava之函数式接口(非常类似Java8,熟悉的可以不看).wmv ├─Google Guava 第07讲-Guava之StopWatch和JDK之ServiceLoader讲解.wmv ├─Google Guava 第08讲-Guava之Files讲解(废话比较多)...

    eclipse-guava-插件

    eclipse的guava插件,使用guava toStringHelper造成toString函数。同样适用于hashcode equals 等

    guava-17.0-API文档-中文版.zip

    赠送jar包:guava-17.0.jar; 赠送原API文档:guava-17.0-javadoc.jar; 赠送源代码:guava-17.0-sources.jar; 赠送Maven依赖信息文件:guava-17.0.pom; 包含翻译后的API文档:guava-17.0-javadoc-API文档-中文...

    guava-31.1-jre.jar

    guava

    guava-23.0-API文档-中文版.zip

    赠送jar包:guava-23.0.jar; 赠送原API文档:guava-23.0-javadoc.jar; 赠送源代码:guava-23.0-sources.jar; 赠送Maven依赖信息文件:guava-23.0.pom; 包含翻译后的API文档:guava-23.0-javadoc-API文档-中文...

    guava-23.0.zip guava.jar guava

    guava-23.0.zip guava.jar guava

    guava-18.0-API文档-中文版.zip

    赠送jar包:guava-18.0.jar; 赠送原API文档:guava-18.0-javadoc.jar; 赠送源代码:guava-18.0-sources.jar; 包含翻译后的API文档:guava-18.0-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:...

    guava-20.0-API文档-中文版.zip

    赠送jar包:guava-20.0.jar; 赠送原API文档:guava-20.0-javadoc.jar; 赠送源代码:guava-20.0-sources.jar; 赠送Maven依赖信息文件:guava-20.0.pom; 包含翻译后的API文档:guava-20.0-javadoc-API文档-中文...

    Google Guava 30.1.1常用类介绍及实践代码

    Google Guava 30.1.1常用类介绍及实践代码

    guava-30.0-jre-API文档-中文版.zip

    赠送jar包:guava-30.0-jre.jar; 赠送原API文档:guava-30.0-jre-javadoc.jar; 赠送源代码:guava-30.0-jre-sources.jar; 赠送Maven依赖信息文件:guava-30.0-jre.pom; 包含翻译后的API文档:guava-30.0-jre-...

    guava-27.0.1-jre-API文档-中文版.zip

    赠送jar包:guava-27.0.1-jre.jar; 赠送原API文档:guava-27.0.1-jre-javadoc.jar; 赠送源代码:guava-27.0.1-jre-sources.jar; 赠送Maven依赖信息文件:guava-27.0.1-jre.pom; 包含翻译后的API文档:guava-...

    guava-23.6-android

    guava-23.6-android guava 版本23.6的 jar 包

    guava-18.0.rar

    guava-18.0 jar包,Guava的工具类,对java集合等一些列的封装,源码、文档、jar包一起

    guava-16.0.1-API文档-中文版.zip

    赠送jar包:guava-16.0.1.jar; 赠送原API文档:guava-16.0.1-javadoc.jar; 赠送源代码:guava-16.0.1-sources.jar; 赠送Maven依赖信息文件:guava-16.0.1.pom; 包含翻译后的API文档:guava-16.0.1-javadoc-API...

Global site tag (gtag.js) - Google Analytics