我有一个名为Data的类;我有一个包含一些数据的列表,以及一个使用数据类的属性过滤该列表的函数
if a,b,c filter words are not empty => data object must have these 3
if a,b are not empty => data object must have these 2
if a,c are not empty => data object must have these 2
if b,c are not empty => data object must have these 2
if a is not empty => data object must have this
if b is not empty => data object must have this
if c is not empty => data object must have this
如您所见,我编写了一个可以完成其工作的代码,但我不喜欢我的算法,因此您可以建议我使用更智能的算法,因为如果类的字段计数增加,我需要编写新的ifs。 (我正在使用Java,但我不会添加Java标记,也许有一个不错的伪代码,但Javas函数也被接受了)
public class Data {
private String a;
private String b;
private String c;
private String getA() {
return a;
}
private String getB() {
return b;
}
private String getC() {
return c;
}
private List<Data> filterData(List<Data> datas, String a, String b, String c) {
List<Data> result = new ArrayList<>();
for (Data data : datas) {
if (a != null && data.getA().equals(a) && b != null && data.getB().equals(b) && c != null && data.getC().equals(c)) {
result.add(data);
} else if (a != null && data.getA().equals(a) && b != null && data.getB().equals(b)) {
result.add(data);
} else if (a != null && data.getA().equals(a) && c != null && data.getC().equals(c)) {
result.add(data);
} else if (b != null && data.getB().equals(b) && c != null && data.getC().equals(c)) {
result.add(data);
} else if (a != null && data.getA().equals(a)) {
result.add(data);
} else if (b != null && data.getB().equals(b)) {
result.add(data);
} else if (c != null && data.getC().equals(c)) {
result.add(data);
} else {
return null;
}
}
return result;
}
}
假设您拥有汽车列表,并且汽车类别具有颜色(a),型号年份(b),燃料类型(c)假定它们不是字符串枚举,或者您不需要比较其范围内的型号年份
答案 0 :(得分:1)
这是一种更通用的方法:将要过滤的字符串添加到数组,然后以相同顺序添加数据中的值。然后,我们可以利用它们具有相同索引的事实,以更通用的方式对它们进行比较。
List<String> filterBy = new List<String>{a, b, c};
for (Data data : datas) {
Boolean shouldAdd = true;
List<String> values = new List<String>{data.getA(), data.getB(), data.getC()};
for (Integer i = 0; i < filterBy.size(); i++) {
if (filterBy[i] != null && filterBy[i].equals(values[i]) == false) {
shouldAdd = false;
break;
}
}
if (shouldAdd) {
result.add(data);
}
}
答案 1 :(得分:1)
如果您改变了病情,则可以大大减少if
检查的次数。目前,您的状况(拆分了7次if
检查)大致如下:
(a & b & c) | (b & c) | (a & c) | (a & b) | a | b | c
a
,b
和c
中的每个对应于x != null && data.getX().equals(x)
如果将那些组件更改为a & b & c
,即元素为null或匹配,则可以简化为x == null || data.getX().equals(x)
。您也可以将此方法单独使用,以使代码更清晰。另外,您可以将循环和if
检查为Stream.filter
private boolean matches(Object x, Object y) {
return x == null || x.equals(y);
}
private List<Data> filterData(List<Data> datas, String a, String b, String c) {
return datas.stream()
.filter(d -> matches(a, d.getA()))
.filter(d -> matches(b, d.getB()))
.filter(d -> matches(c, d.getC()))
.collect(Collectors.toList());
}
注意:1)我将data.getX().equals(x)
更改为x.equals(data.getX())
,因为您已经知道x
是!= null
,但是getX()
可能为空。另外,如果所有过滤器均为if
,则您最后的null
检查将null
添加到列表中,而不是data
。我以为这是个错误。
答案 2 :(得分:0)
我相信这就是您想要的组合。尽管您的描述不明确,但是您现有的代码与此不匹配。 (正如@juvian所说,您目前写的最后3个条件涵盖了前4个条件。)
private List<Data> filterData(List<Data> datas, String a, String b, String c) {
List<Data> result = new ArrayList<>();
for (Data data : datas) {
if (! data.getA().equals(a == null ? data.getA() : a)) {
// Filtered out
}
else if (! data.getB().equals(b == null ? data.getB() : b)) {
// Filtered out
}
else if (! data.getC().equals(c == null ? data.getC() : c)) {
// Filtered out
}
else {
result.add(data);
}
}
return result;
}