Guava Predicate
2016-06-18 23:45
148 查看
1. 简介
Predicate<泛型>(断言,断定),是Guava中的一个基础接口,其内部只有一个方法boolean apply(T input),这个方法输入是一个泛型对象,输出是一个布尔值,非常简单,下面来看一下这个小东西能帮助我们做什么。
2. 使用
2.1 更简单的过滤
在日常开发中,可能有这种需求,当集合中的某些元素不符合条件时,想要过滤掉这些元素,这时我们通常有两种做法。方法一:
List<Integer> intList = Lists.newArrayList(1, 2, 3, 5, 6); Iterator<Integer> it = intList.iterator(); while (it.hasNext()) { Integer value = it.next(); if (value == 3 || value == 5) { it.remove(); } } System.out.println(intList);
方法二:
List<Integer> intList = Lists.newArrayList(1, 2, 3, 5, 6); List<Integer> resultList = Lists.newArrayList(); for (Integer value : intList) { if (value != 3 && value != 5) { resultList.add(value); } } System.out.println(resultList);
方法一是在原集合上直接做删除操作,我们知道ArrayList实际上就是数组,而数组是连续的内存空间,当删除元素时,后面的元素都需要向前移动,当这个集合很大的时候,就会涉及到大量的移动。方法二是直接新建一个集合,将符合条件的元素添加至新集合中,这样避免了方法一的问题,但这样的写法有一点啰嗦,可以变成下面这样。
List<Integer> intList = Lists.newArrayList(1, 2, 3, 5, 6); Predicate<Integer> predicate = new Predicate<Integer>() { public boolean apply(Integer value) { return value != 3 && value != 5; } }; List<Integer> resultList = Lists.newArrayList(Iterables.filter(intList, predicate)); System.out.println(resultList);
将过滤规则抽到Predicate中,如果过滤规则发生变化时,只需修改Predicate即可。
2.2 更优雅的判断
举一个判断稍微复杂的例子,MBA的报考条件是:a) 具有国家承认的大学本科毕业学历后,有三年或三年以上工作经历者。
b) 已获硕士、博士学位,并有两年或两年以上工作经历者。
c) 获得国家承认的大专毕业学历后,有五年或五年以上工作经历。
这时需要一个方法去判断一个考生是否准许考试,方法如下:
private boolean canExam(Examinee examinee) { return ("大专".equals(examinee.getEducation()) && examinee.getExperience() >= 5) || ("本科".equals(examinee.getEducation()) && examinee.getExperience() >= 3) || ("研究生".equals(examinee.getEducation()) && examinee.getExperience() >= 2); }
当我们去阅读这段代码的时候,只会感觉到一个字,乱,这时可以使用Predicate去改造。首先,将每个条件分支都抽到一个Predicate中。
private Predicate<Examinee> juniorCollege = new Predicate<Examinee>() { public boolean apply(Examinee examinee) { return "大专".equals(examinee.getEducation()) && examinee.getExperience() >= 5; } }; private Predicate<Examinee> undergraduate = new Predicate<Examinee>() { public boolean apply(Examinee examinee) { return "本科".equals(examinee.getEducation()) && examinee.getExperience() >= 3; } }; private Predicate<Examinee> postgraduate = new Predicate<Examinee>() { public boolean apply(Examinee examinee) { return "研究生".equals(examinee.getEducation()) && examinee.getExperience() >= 2; } };
然后,使用Predicates工具将这三个Predicate用or聚合起来,调用其apply方法。
private boolean canExam(Examinee examinee) { return Predicates.or(juniorCollege, undergraduate, postgraduate).apply(examinee); }
canExam变得非常简洁。
2.3 更动态的配置
根据分数返回对这个分数的评级,要求如下:及格:[60, 70)
良好:[70, 80)
优秀:[80, 100]
可以看到,这是一个分数规则和评级的映射,分数规则是个区间(也可能更复杂),而不是一个具体的值,这时,可以使用Predicate作为key,得到一个评级的配置表。
private Map<Predicate<Double>, String> config = Maps.newHashMap(); { config.put(new Predicate<Double>() { @Override public boolean apply(Double score) { return score >= 60 && score < 70; } }, "及格"); config.put(new Predicate<Double>() { @Override public boolean apply(Double score) { return score >= 70 && score < 80; } }, "良好"); config.put(new Predicate<Double>() { public boolean apply(Double score) { return score >= 80; } }, "优秀"); }
然后写一个方法,遍历这个配置,取到符合条件的值,这段代码是统一的。
private String getLevel(Double score) { for (Map.Entry<Predicate<Double>, String> entry : config.entrySet()) { if (entry.getKey().apply(score)) { return entry.getValue(); } } return "未知"; }
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/51704892,转载请注明。
相关文章推荐
- C#访问修饰符
- java加密——Jasypt开源工具包
- Android 之dragger使用
- Android 之dragger使用
- Android 之dragger使用
- 定制适用于ARM平台的Ubuntu rootfs(根文件系统)
- Mac Os10.11.3 自带Apache的相关命令总结,及遇到的坑
- Linux centos下安装tomcat +JDK环境部署
- Git(2)
- php面向对象及特征
- Ubuntu下好用的软件推荐
- Linux下静态IP地址的设置及TFTP服务的搭建
- [摘录]时间会证明一切
- 如何创建一个类
- Android 开源框架ImageLoader完全解析(一)--- 基本介绍及使用
- AbstractQueuedSynchronizer初探
- mysql1607处理
- 数据库事务隔离级别
- github项目解析(五)-->android日志框架
- spfa模板