我有一个pojo列表List<Pojo> pojoList
;并且pojo.getColour();
返回一个枚举实例。
我想这样做:
List<Pojo> newlist = new ArrayList<Pojo>();
for(Pojo pojo:pojoList){
if(pojo.getColour() == Colour.Red){
newList.add(pojo);
}
}
我可以看到自己对其他类型的列表使用类似的函数,而不是重复大量的代码是一种使它成为通用和/或功能的方法?这样我就可以根据不同的规则创建不同类型的子列表了?
答案 0 :(得分:6)
首先,我应该注意,如果您只想要一个包含匹配元素的新ArrayList
,那么您在示例中的方式就可以了。在Java具有lambda表达式之前,你不会比它更简单或更好看。
由于您使用guava对此进行了标记,因此可以使用Guava执行此操作。您基本上是在谓词(== Color.Red
)和函数(pojo.getColour()
)的组合上过滤原始列表。因此,如果您在Function<Pojo, Colour>
上有一个名为COLOUR
的静态最终Pojo
(就像这样):
public static final Function<Pojo, Colour> COLOUR =
new Function<Pojo, Colour>() {
@Override public Colour apply(Pojo input) {
return input.getColour();
}
};
你可以像这样创建这样的组合:
Predicate<Pojo> isRedPojo = Predicates.compose(
Predicates.equalTo(Colour.Red), Pojo.COLOUR);
然后,您可以创建原始列表的过滤视图:
Iterable<Pojo> redPojos = Iterables.filter(pojoList, isRedPojo);
如果您愿意,可以将过滤后的视图复制到ArrayList
:
List<Pojo> copy = Lists.newArrayList(redPojos);
答案 1 :(得分:1)
您必须使您的类型实现检查的通用接口:
public interface Candidate {
public boolean isAddable();
}
然后循环看起来像这样
List<Candidate> newlist = new ArrayList<Candidate>();
for(Candidate pojo:pojoList){
if(pojo.isAddable()){
newList.add(pojo);
}
}
并且Pojo
类必须实现接口:
public class Pojo implments Candidate {
// ...
@Override
public boolean isAddable() {
return isRed();
}
}
答案 2 :(得分:1)
制作通用过滤器界面
public interface Filter<T>{
public boolean match(T item);
}
使用过滤器制作方法
public <T> List<T> getFilteredList(List<T> oldList, List<T> filter){
List<T> newlist = new ArrayList<T>();
for(T item:oldList){
if(filter.match(item)){
newlist.add(item);
}
}
return newlist;
}
把它们放在一起
List<Pojo> myList = ..
List<Pojo> redList = getFilteredList(myList,new Filter<Pojo>(){
public boolean match(Pojo item){ return item.isRed()};
});
List<Pojo> blueList = getFilteredList(myList,new Filter<Pojo>(){
public boolean match(Pojo item){ return item.COLOR== Color.BLUE};
});
答案 3 :(得分:1)
根据您使用它的频率/您使用的多少个不同的过滤器(只有红色,只有绿色等),创建一个过滤器接口是有意义的 - 如果它只是检查isRed那么它可能也是很多代码,你最好用一个简单的静态方法。
这个设计的好处是你可以将它与你想要过滤的任何对象一起使用(参见下面的String示例)。
public static void main(String[] args) {
List<Pojo> originalList = Arrays.asList(new Pojo(true), new Pojo(false), new Pojo(false));
List<Pojo> filteredList = Utils.getFilteredList(originalList, new Filter<Pojo>() {
@Override
public boolean match(Pojo candidate) {
return candidate.isRed();
}
});
System.out.println(originalList.size()); //3
System.out.println(filteredList.size()); //1
//Now with strings
List<String> originalStringList = Arrays.asList("abc", "abd", "def");
List<String> filteredStringList = Utils.getFilteredList(originalStringList, new Filter<String>() {
@Override
public boolean match(String candidate) {
return candidate.contains("a");
}
});
System.out.println(originalStringList.size()); //3
System.out.println(filteredStringList.size()); //2
}
public static class Utils {
public static <T> List<T> getFilteredList(List<T> list, Filter<T> filter) {
List<T> selected = new ArrayList<>();
for (T t : list) {
if (filter.match(t)) {
selected.add(t);
}
}
return selected;
}
}
public static class Pojo {
private boolean isRed;
public Pojo(boolean isRed) {
this.isRed = isRed;
}
public boolean isRed() {
return isRed;
}
}
public interface Filter<T> {
/**
* When passed a candidate object, match returns true if it matches the filter conditions,
* or false if it does not.
* @param candidate the item checked against the filter
* @return true if the item matches the filter criteria
*/
boolean match(T candidate);
}