在工作中,很多时候要使用到集合筛选,而自己又不愿意写循环,在网上找到一种方法 CollectionUtils.select,
下面是个人的理解:
/**
* Selects all elements from input collection which match the given
* predicate into an output collection.
*
* A null
predicate matches no elements.
*
* @param the type of object the {@link Iterable} contains
* @param inputCollection the collection to get the input from, may not be null
* @param predicate the predicate to use, may be null
* @return the elements matching the predicate (new list)
* @throws NullPointerException if the input collection is null
*/
public static Collection select(final Iterable extends O> inputCollection,
final Predicate super O> predicate) {
final Collection answer = inputCollection instanceof Collection> ?
new ArrayList(((Collection>) inputCollection).size()) : new ArrayList();
return select(inputCollection, predicate, answer);
}
先查看这个方法,需要两个参数,Collection inputCollection为输出集合,如果对泛型边界有兴趣,可以查看effective java 第28条 利用有限制通配符来提升API的灵活性,Predicate predicate 是什么意思呢?
public interface Predicate {
/**
* Use the specified parameter to perform a test that returns true or false.
*
* @param object the object to evaluate, should not be changed
* @return true or false
* @throws ClassCastException (runtime) if the input is the wrong class
* @throws IllegalArgumentException (runtime) if the input is invalid
* @throws FunctorException (runtime) if the predicate encounters a problem
*/
public boolean evaluate(T object);
}
这是一个接口,只有一个evaluate方法,从字面意思是比较的意思,返回 true or false ,如何比较,由子类实现
可以写一个PO类:
public class Student {
private Integer number;
private String name;
private Integer score;
public Student() {
super();
}
public Student(Integer number, String name, Integer score) {
super();
this.number = number;
this.name = name;
this.score = score;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
@Override
public String toString() {
return "Student [number=" + number + ", name=" + name + ", score="
+ score + "]";
}
}
在写两个比较实现:
/**
* 如果超过设定的integer 就返回true
*
* @author Administrator
*
*/
public class MoreThanPredicate implements Predicate{
private final Integer score;
public MoreThanPredicate(Integer score){
this.score = score;
}
@Override
public boolean evaluate(Student object) {
return object.getScore() > score;
}
}
/**
* 相同比较器
* @author Administrator
*
*/
public class EqualPredicate implements Predicate{
//学号相同就为相同一个学生
private final Integer number;
//初始化必须赋值
EqualPredicate(Integer number){
this.number = number;
}
@Override
public boolean evaluate(Student object) {
//由于是对象类型,所以不用==号的方式
return object.getNumber().equals(number);
}
}
下面是测试:
/**
* 查找分数大于60的学生
* @param args
*/
public static void main(String[] args) {
Student[] ss = {new Student(0, "123", 99),new Student(1, "789", 59),new Student(3, "110", 80)};
Predicate p = new MoreThanPredicate(60);
Collection c = CollectionUtils.select(Arrays.asList(ss), p);
System.out.println(c);
}
[Student [number=0, name=123, score=99], Student [number=3, name=110, score=80]]
/**
* 查找学号为1的同学
* @param args
*/
public static void main(String[] args) {
Student[] ss = {new Student(0, "123", 99),new Student(1, "789", 59),new Student(3, "110", 80)};
Predicate p = new EqualPredicate(1);
Collection c = CollectionUtils.select(Arrays.asList(ss), p);
System.out.println(c);
}
[Student [number=1, name=789, score=59]]
可以看出,很简洁:
在这个基础之上还可以继续扩展:
public class BeanEqualPredicate implements Predicate {
private final String field;
private final Object param;
BeanEqualPredicate(String field,Object param){
this.field = field;
this.param = param;
}
@Override
public boolean evaluate(T object) {
try {
Object propertyValue = PropertyUtils.getProperty(object, field);
return propertyValue == param || propertyValue.equals(param);
} catch (IllegalAccessException | InvocationTargetException
| NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
/**
* 动态查找
* @param args
*/
public static void main(String[] args) {
Student[] ss = {new Student(0, "123", 99),new Student(1, "789", 59),new Student(3, "110", 80)};
System.out.println(select(Arrays.asList(ss),"number",1));
}
private static Collection select(Collection c,String field,Object param){
BeanEqualPredicate predicate = new BeanEqualPredicate<>(field, param);
return CollectionUtils.select(c, predicate);
}
}
[Student [number=1, name=789, score=59]]
经过这样封装,具有更好的灵活性,当然,如果需要,你可以继续扩展.