`

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常用类库 v33.0.0.zip

    4. **函数式编程**:Guava引入了函数接口(Function、Predicate等)和Optional类,这使得Java代码可以更接近函数式编程风格,提高代码的可读性和可维护性。 5. **字符串处理**:Guava的Strings类包含一系列静态方法...

    guava-23.0.zip guava.jar guava

    3. **函数式编程**:Guava支持函数式编程,包括Function、Predicate、Transformer等接口,便于编写简洁的代码。 4. **并发处理**:Guava提供了强大的并发工具,如ListenableFuture、CountDownLatch、CyclicBarrier...

    guava 常用API说明

    Guava提供了一些函数式编程的工具,如Function、Predicate、Transformer等接口,它们可以用来编写更简洁、可读性更强的代码。例如,Function接口用于表示一个接受一个参数并返回一个结果的函数。 4. **并发工具** ...

    guava-18.0(guava-18.0.jar和guava-18.0-sources.jar)

    3. **函数式编程**:Guava引入了Function、Predicate和Transformer等接口,支持函数式编程风格,便于代码的编写和测试。 4. **缓存机制**:Guava提供了本地缓存实现,可以帮助开发者轻松地在应用程序中构建高效的...

    guava(google的java集合包)

    4. **函数式编程**:Guava引入了函数式编程的概念,如Function、Predicate和Transformer接口,使代码更简洁,易于理解和测试。 5. **字符串处理**:Guava提供了Strings类,包含各种静态方法来处理和格式化字符串,...

    guava-18.0资料

    3. **函数式编程**:Guava引入了Function、Predicate等接口,支持函数式编程风格,便于编写无副作用的代码和进行数据转换。 4. **并发支持**:Guava提供了更高级的并发工具,如RateLimiter(限流器)、Service...

    guava14.0.1jar包

    7. **函数式编程**:Guava引入了函数式编程的概念,如Function、Predicate和Supplier接口,使得代码更加简洁,易于测试和维护。 8. **事件监听**:Guava的EventBus是一种发布-订阅事件总线,用于组件之间的松耦合...

    guava源码src

    5. **函数式编程**:Guava引入了Function、Predicate等函数式接口,以及Optional类,使得Java也可以进行函数式编程,增强了代码的简洁性和可读性。 6. **预检查与断言**:Preconditions类提供了静态方法,用于在...

    guava-API文档

    6. 函数式编程:Guava引入了Function、Predicate、Transformer等接口,这些接口是函数式编程的关键元素,可以用于构建高度可组合和可重用的代码。 7. 哈希与比较:Guava提供了Hashing类,可以方便地创建哈希函数。...

    guava代码展示

    3. **函数式编程**:Guava引入了函数接口,如Function、Predicate等,这些接口支持函数式编程风格,使得代码更加简洁、可读性强。例如,可以使用Predicate来创建过滤器,Function进行转换操作。 4. **并发工具**:...

    guava-jdk5

    3. **函数式编程**:Guava引入了函数式编程的概念,如Function、Predicate等接口,它们是实现高阶函数的基础。开发者可以利用这些接口来编写更简洁、可读性更强的代码。 4. **并发编程支持**:Guava提供了丰富的...

    Guava 工程项目包 有实例

    - **函数式编程**:Guava 引入了 Function 和 Predicate 等接口,促进了函数式编程风格在 Java 中的应用。 - **并发**:Guava 提供了更高级别的并发工具,如 ListenableFuture、Service 等,简化了异步编程和系统...

    guava-26.0-jre.zip

    3. **函数式编程**:Guava支持函数式编程风格,包括Function、Predicate、Transformer等接口,使得代码更简洁,更易于测试和维护。 4. **并发工具**:Guava提供了丰富的并发工具类,如 ListeningExecutorService、...

    guava-18.jar

    7. **函数式编程**:Guava引入了Function、Predicate和Function接口,支持函数式编程风格,便于编写无副作用的代码和进行复杂操作的组合。 8. **检查异常**:Guava通过Preconditions类提供了一组静态方法,用于在...

    Google-guava 19.0

    函数式编程** Guava引入了Function、Predicate、Supplier等函数式接口,支持lambda表达式的使用,使得代码更加简洁、可读性更强。Compose、andThen方法则方便了函数的组合。 **7. 正则表达式** Guava的Regex类提供...

    guava23.0,用于安卓软件开发

    5. **函数式编程**:Guava引入了Function、Predicate等接口,支持函数式编程风格,这在处理数据流和转换时特别有用。 6. **I/O操作**:Guava提供了Files、ByteStreams、CharStreams等类,简化了文件读写和流操作,...

    com.google.common.jar的替换包guava-r07.jar

    4. **函数式编程**:Guava引入了Function、Predicate、Transformer等接口,支持函数式编程风格,使得代码更加简洁和可读。 5. **I/O操作**:Guava的Files类和Charsets类提供了许多文件操作和字符编码的便利方法,...

    google-guava-18.0

    Guava引入了函数接口(Function、Predicate、Transformer等)和Optional类,支持函数式编程风格。这使得代码更简洁,更易于测试和维护。 4. **并发支持**: Guava提供了原子类的扩展,如AtomicIntegerMap,以及更...

    guava-18.0.rar

    9. **函数式编程**:Guava提供了函数接口,如Function、Predicate、Transformer等,为Java提供了更多的函数式编程能力。 10. **Guava的文档和源码**:这个压缩包中的"guava-18.0-javadoc.jar"是Guava的Java文档,...

    guava多个版本jar包

    增加了新的函数式编程工具,如Function和Predicate,以及更丰富的Optional API。在I/O方面,增加了对文件系统操作的简化接口,如Files和Paths。Guava 23还优化了缓存,支持弱键和软引用键,以更好地管理内存资源。...

Global site tag (gtag.js) - Google Analytics