我有一个值列表:
{(“ 1”,“ 3”),(“ 1”,“ 5”),(“ 3”,“ 13”)(“ 5”,“ 4”),(“ 1”,“ 7 “),(” 8“,” 9“),(” 9“,” 1“),(” 1“,” 23“),(” 5“,” 7“)}
和一个必须应用于每个元素“ 1:3,3:13,5:-”的过滤器。 我需要获取另一个列表,该列表具有与过滤器匹配的值。在这种情况下,结果应为:
值:1 3 值:3 13 值:5 4 值:5 7
在过滤器中,该值 5:- 表示它与第一个元素匹配,并且不考虑第二个值,因此任何以5开头的元素都是好吧。
import java.util.*;
import java.util.Set;
import java.util.stream.Collectors;
class Filter {
private String valueFilter1;
private String valueFilter2;
public Filter(String valueFilter1, String valueFilter2) {
this.valueFilter1 = valueFilter1;
this.valueFilter2 = valueFilter2;
}
public Filter(String fil) {
String[] filResult = fil.split(":");
this.valueFilter1 = filResult[0];
this.valueFilter2 = filResult[1];
}
public String getValueFilter1() {
return valueFilter1;
}
public String getValueFilter2() { return valueFilter2; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Filter that = (Filter) o;
return Objects.equals(valueFilter1, that.valueFilter1) &&
Objects.equals(valueFilter2, that.valueFilter2);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((valueFilter1 == null) ? 0 : valueFilter1.hashCode());
result = prime * result + ((valueFilter2 == null) ? 0 : valueFilter2.hashCode());
return result;
}
}
public class FilterUtils {
private static void filterMessages(List<Filter> eventsParam, String type) {
Set<Filter> filter1 = new HashSet<>();
Set<String> filter2 = new HashSet<>();
Arrays.stream(type.split(","))
.forEach(f -> {
if (f.contains("-"))
filter2.add(f.split(":")[0]);
else
filter1.add(new Filter(f));
});
// This following logic is in another method called processMessage().
// So I'm trying to return both filters as in processMessage I have something like this:
// .stream()
// .filter(e -> filterMessages(eventsParam).contains(new Filter(e.getValueFilter1(), e.getValueFilter2()))
// .collect(Collectors.toList());
// the real method filterMessages only receives List<Filter> eventsParam as argument
// I was thinking of returning a map of Set like this Map<String, Set<Object>> or Map<String, Set<T>> but it didn't work
// map.put("filter1", filter1);
// map.put("filter2", filter2);
// Not sure how to make it work
List<Filter> result = eventsParam
.stream()
.filter(e -> filter1.contains(new Filter(e.getValueFilter1(), e.getValueFilter2())) |
filter2.contains(e.getValueFilter1()))
.collect(Collectors.toList());
for (Filter r: result) {
System.out.println("Values: " + r.getValueFilter1() + " " + r.getValueFilter2());
}
}
public static void main(String[] args) {
List events = new ArrayList<Filter>();
events.add(new Filter("1", "3"));
events.add(new Filter("1", "5"));
events.add(new Filter("3", "13"));
events.add(new Filter("5", "4"));
events.add(new Filter("1", "7"));
events.add(new Filter("8", "9"));
events.add(new Filter("9", "1"));
events.add(new Filter("1", "23"));
events.add(new Filter("5", "7"));
filterMessages(events, "1:3,3:13,5:-");
}
}
到目前为止,我拥有的代码可以正常工作,但是我认为这是一种有点复杂的方法,并且不允许我将其调整为适合我目前拥有的现有代码。任何想法?或面对这个问题的更好方法?谢谢
答案 0 :(得分:0)
我建议您在代码审查网站https://codereview.stackexchange.com/上问这个问题。
简而言之:
1)不需要构造函数Filter(String valueFilter1, String valueFilter2)
。
2)尽管代码可以工作,但equals()
的这种定义在其他情况下仍可能导致错误:
Filter a = new Filter("1", "2");
Filter b = new Filter("-", "2");
Filter c = new Filter("5", "2");
System.out.println(a.equals(b)); // true
System.out.println(b.equals(c)); // true
System.out.println(a.equals(c)); // false
根据常识,如果a = b和b = c,则它必须是a = c。但您的情况并非如此。在实际的应用程序中,这可能会导致难以发现的错误。