我有一个值对象,其结构类似于:
class MyValueObject {
String travellerName;
List<String> countryTags;
// Getters and setters
}
在此,我维护了旅行者的清单以及他们访问过的国家/地区。例如
理查德->印度,波兰,澳大利亚
约翰->美国,澳大利亚,马尔代夫
Emma-> US
现在我要添加一个筛选器功能,它将提供访问过所选国家/地区的所有旅行者的列表。
将提供国家列表作为输入。
List<String> countryFilter;
此过滤器具有多选选项。
过滤后的结果应同时包含AND和OR结果。
即,如果输入是美国和澳大利亚,则结果将是:
约翰->美国,澳大利亚,马尔代夫
理查德->印度,波兰,澳大利亚
Emma-> US
结果的排序方式应为AND匹配显示在OR匹配上方。
问题:
我应该如何对比赛进行排序?
我要写一个比较器吗?如果是,那么一些示例将非常有帮助。
请提出建议。
谢谢。
而不是排序,而是重复两次,一次针对AND匹配,一次针对OR匹配:
// Say you have a list of MyValueObject type called travelers
ArrayList<MyValueObject> copyTravelers = new ArrayList<>(travelers);
List<MyValueObject> filtered = new ArrayList<>();
// AND
for (MyValueObject t : copyTravelers) {
MyValueObject traveler = t;
for (String country : countryFilter)
if (!traveler.countryTags.contains(country)) {
traveler = null;
break;
}
if (traveler != null) {
filtered.add(traveler);
copyTravelers.remove(traveler);
}
}
// OR
for (MyValueObject t : copyTravelers) {
for (String country : countryFilter)
if (traveler.countryTags.contains(country)) {
filtered.add(t);
copyTravelers.remove(t);
break;
}
}
尝试一下:
构建对象。
List<Traveler> travelers = new ArrayList<>();
Traveler t1 = new Traveler();
t1.traveler = "Richard";
t1.countries = List.of("India", "Poland", "Australia");
travelers.add(t1);
t1 = new Traveler();
t1.traveler = "John";
t1.countries = List.of("US", "Australia", "Maldives");
travelers.add(t1);
t1 = new Traveler();
t1.traveler = "Emma";
t1.countries = List.of("US");
travelers.add(t1);
过滤器
List<String> countryFilter = List.of("US", "Maldives");
测试谓词。这些是问题的核心。
any
返回true,如果旅行国包含至少一个国家/地区all
返回true,如果旅行者的国家/地区包含所有国家/地区。Predicate<Traveler> any = t -> countryFilter.stream()
.anyMatch(cc -> t.countries.contains(cc));
Predicate<Traveler> all = t -> countryFilter.stream()
.allMatch(cc -> t.countries.contains(cc));
现在应用过滤器。它只是传输旅行者对象并应用过滤器。然后打印结果。
System.out.println("Filtering on: " + countryFilter);
System.out.println("\nVisited some of the countries");
travelers.stream().filter(any)
.forEach(t -> System.out.println(t.traveler));
System.out.println("\nVisited all of the countries");
travelers.stream().filter(all)
.forEach(t -> System.out.println(t.traveler));
打印
Filtering on: [US, Maldives]
Visited some of the countries
John
Emma
Visited all of the countries
John
班级支持班
class Traveler {
String traveler;
List<String> countries;
public String toString() {
return traveler + " => " + countries.toString();
}
}