当前位置:首页 > 开发 > 开源软件 > 正文

Guava Function Predicate 类函数式编程

发表于: 2014-05-26   作者:abc08010051   来源:转载   浏览:
摘要:  最近在学习使用guava, 一个非常优秀的开源项目,是对jdk一个非常有力的补充,我看上guava的是能使代码更简洁,良好的代码风格   首先来介绍一下com.google.common.base包中的常用类   1 Function    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方法

Guava Function Predicate 类函数式编程

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
Java经典类库-Guava中的函数式编程讲解2013-06-28 01:49 by 黄博文, 354 阅读, 8 评论, 收藏, 编辑
先贴代码: DuplicateCenter { main(String[] args) { List names = Arrays.()names=ImmutableSet.(
模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn
模板类使用成员函数模板(member function template)处理隐式(implicit)转换 本文地址: http://blog.
函数式编程不得不提到Predicate 何为Predicate? Predicate是来自于Apache Common Framework,内置
函数式编程不得不提到Predicate 何为Predicate? Predicate是来自于Apache Common Framework,内置
http://www.ruanyifeng.com/blog/2012/04/functional_programming.html 诞生50多年之后,函数式编程
前言 《core python programming 2》说: Python不大可能会成为一种函数式编程语言,但它支持许多有
诞生50多年之后,函数式编程(functional programming)开始获得越来越多的关注。 不仅最古老的函数
诞 生50多年之后,函 数式编程(functional programming)开始获得越来越多的关注。 不 仅最古老的
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号