簡體   English   中英

如何使用 partitioningBy,然后使用 Java Streams 分別對結果列表進行排序

[英]How to use partitioningBy and then sort resulting lists separately using Java Streams

我有一個如下對象:

public class Resource {
  int level;
  String identifier;
  boolean isEducational;

  public Resource(String level, String identifier, boolean isEducational) {
            this.level = level;
            this.identifier = identifier;
            this.isEducational = isEducational;
        }

 // getter and setters 
}

以及這些資源的列表,例如:

List<Resource> resources = Arrays.asList(new Resource(4, "a", true ),
                                                new Resource(4, "b", false),
                                                new Resource(3, "c", true ),
                                                new Resource(3, "d", false ),
                                                new Resource(2, "e", true ),
                                                new Resource(2, "f" , false));

我想按它們的level屬性對這個列表進行排序,但是這種排序應該對isEducational資源和isEducational資源分別進行。

因此,排序后,結果列表應按以下順序排列:

[Resource e, Resource c, Resource a, Resource f, Resource d, Resource b]

// basically, isEducational sorted first, followed by non-educational resources

所以我嘗試了以下操作:

List<Resource> resources1 = resources.stream()
                .collect(partitioningBy(r -> r.isEducational()))
                .values()
                .stream()
                .map(list -> {
                    return list
                            .stream()
                            .sorted(comparing(r -> r.getLevel()))
                            .collect(toList());
                })
                .flatMap(Collection::stream)
                .collect(toList());


resources1.stream().forEach(System.out::println);

並將輸出打印為:

Resource{level='2', identifier='f', isEducational='false'}
Resource{level='3', identifier='d', isEducational='false'}
Resource{level='4', identifier='b', isEducational='false'}
Resource{level='2', identifier='e', isEducational='true'}
Resource{level='3', identifier='c', isEducational='true'}
Resource{level='4', identifier='a', isEducational='true'}

這與我想要的相反,即首先印刷非教育,其次是教育資源

有沒有更好的方法來實現這一目標? 我不想再次迭代列表來重新排列它。 謝謝。

根本不需要使用partitioningBy 您只需要兩個比較器首先通過isEducational進行比較,然后通過level進行比較,您可以使用Comparator.thenComparing進行鏈接

resources.stream()
         .sorted(Comparator.comparing(Resource::isEducational).reversed().thenComparing(Resource::getLevel))
         .forEach(System.out::println);

您可以為比較器引入變量以使您的代碼更具可讀性,或者如果您想以靈活的方式重用它們:

Comparator<Resource> byIsEdu = Comparator.comparing(Resource::isEducational).reversed();
Comparator<Resource> byLevel = Comparator.comparing(Resource::getLevel);

resources.stream()
         .sorted(byIsEdu.thenComparing(byLevel))
         .forEach(System.out::println);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM