Guava Predicate
Posted 高爽 Coder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Guava Predicate相关的知识,希望对你有一定的参考价值。
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,转载请注明。
以上是关于Guava Predicate的主要内容,如果未能解决你的问题,请参考以下文章