将对象列表相对于给定输入值的列表进行排序

问题描述 投票:0回答:1

我有一个值对象,其结构类似于:

class MyValueObject {
    String travellerName;
    List<String> countryTags;

    // Getters and setters
}

在此,我维护了旅行者的清单以及他们访问过的国家/地区。例如

理查德->印度,波兰,澳大利亚

约翰->美国,澳大利亚,马尔代夫

Emma-> US

现在我要添加一个筛选器功能,它将提供访问过所选国家/地区的所有旅行者的列表。

将提供国家列表作为输入。

List<String> countryFilter;

此过滤器具有多选选项。

过滤后的结果应同时包含AND和OR结果。

即,如果输入是美国和澳大利亚,则结果将是:

约翰->美国,澳大利亚,马尔代夫

理查德->印度,波兰,澳大利亚

Emma-> US

结果的排序方式应为AND匹配显示在OR匹配上方。

问题:

我应该如何对比赛进行排序?

我要写一个比较器吗?如果是,那么一些示例将非常有帮助。

请提出建议。

谢谢。

java comparator
1个回答
0
投票

而不是排序,而是重复两次,一次针对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;
        }
}


0
投票

尝试一下:

构建对象。

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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.