【发布时间】:2019-06-23 03:54:45
【问题描述】:
我想编写能够使用多个条件过滤对象列表的代码,但我希望条件的数量可以波动(有时过滤 1 个字段,有时过滤所有 3 个字段)。
在我的情况下,我希望用户可以选择为某个字段选择“任何”,但仍然对其他字段应用过滤器。
在以下情况下,用户可以通过字段x, y & z 过滤列表,但随后他们也可以将其中一个过滤器更改为“任何”,从而在实际过滤列表时不需要该过滤器。 getFilteredList 方法从每个组合框中获取 String 值并使用每个 String 过滤列表,除非 String 是“任何”,那么它将接受来自该字段的任何 String。
我在下面编写了代码,这些代码适用于这种情况,但在将来添加更多过滤器时会变得越来越低效。 (2 个过滤器产生 4 个返回语句,3 个过滤器产生 8 个等等......)。
private static ArrayList<Model> getFilteredList(ArrayList<Model> originalList, String x, String y, String z ){
if(x.equals("any") && y.equals("any") && z.equals("any")) {
return originalList;
}
if(x.equals("any") && y.equals("any") && !z.equals("any")) {
return originalList.stream().filter(item -> item.getZ().equals(z)).collect(Collectors.toCollection(ArrayList::new));
}
if(x.equals("any") && !y.equals("any") && z.equals("any")) {
return originalList.stream().filter(item -> item.getY().equals(y)).collect(Collectors.toCollection(ArrayList::new));
}
if(x.equals("any") && !y.equals("any") && !z.equals("any")) {
return originalList.stream().filter(item -> item.getY().equals(y)&& item.getZ().equals(z)).collect(Collectors.toCollection(ArrayList::new));
}
if(!x.equals("any") && y.equals("any") && z.equals("any")) {
return originalList.stream().filter(item -> item.getX().equals(x)).collect(Collectors.toCollection(ArrayList::new));
}
if(!x.equals("any") && y.equals("any") && !z.equals("any")) {
return originalList.stream().filter(item -> item.getX().equals(x)&& item.getZ().equals(z)).collect(Collectors.toCollection(ArrayList::new));
}
if(!x.equals("any") && !y.equals("any") && z.equals("any")) {
return originalList.stream().filter(item -> item.getX().equals(x)&& item.getY().equals(y)).collect(Collectors.toCollection(ArrayList::new));
}
if(!x.equals("any") && !y.equals("any") && !z.equals("any")) {
return originalList.stream().filter(item -> item.getX().equals(x)&& item.getY().equals(y)&& item.getZ().equals(z)).collect(Collectors.toCollection(ArrayList::new));
}
return originalList;
}
Model 的外观如下:
public class Model {
private String x;
private String y;
private String z;
public String getX() {
return x;
}
public String getY() {
return y;
}
public String getZ() {
return z;
}
}
下面的代码将返回一个列表,其中x 字段等于“red”,y 字段等于“medium”,z 字段可以是任何值。
private static ArrayList<Model> items = new ArrayList<>();
public static void main(String[] args) {
ArrayList<Model> filteredList = getFilteredList(items, "red", "medium", "any");
}
我不确定是否有更简单的方法来执行我的getFilteredList 方法,我已经搜索了很多但找不到任何更简单/更有效的实现。在未来,我希望允许 10 多个过滤器始终可以选择“任何”,但我目前的解决方案太长而且根本不会优雅。如果有人可以提供有关如何优雅地过滤具有不同数量过滤器的列表的任何答案,将不胜感激。
谢谢。
【问题讨论】:
-
至少不是
==,而是equals -
创建您自己的
equalsOrAny()方法,您将不需要您的ifs.. -
@PM77-1 你能详细说明一下,你建议我应该在哪里使用
equalsOrAny()方法? -
您可以一次只应用一个过滤器吗?如果不是“any”,则首先在 X 上过滤整个列表,如果不是“any”,则在 Y 上过滤结果列表,如果不是“any”,则在 Z 上过滤该列表。无需不必要地增加过滤器的组合。
-
@DavidRTribble 是的,他可以链接过滤器。我已经编写了一些测试用例,并且 Kes 对
getFilteredList的实现产生了与我的答案相同的输出。
标签: java arraylist filter java-stream