如何通过检查 Java 中内部列表中的值来对列表进行排序?

How to sort a List by checking a value inside inner list in Java?

我有一个 class 如下所示,

public class Inventory {

   private String name;
   private List<Sample> samples;
}

public class Sample {

   private int count;
   private String date;
}

List<Inventory> inventories;

我已经按日期对 samples 进行了排序。没关系。但是我需要根据示例 class 中的 date 字段对 inventories 列表进行排序。 samples 已经排序。所以我需要库存按样品日期 DESC 排序。例如,

在那个inventories列表中,如果它有3个数据,

Inventory 1
name = 1
samples has dates of = List of (2021-07-02, 2021-07-03)

Inventory 2
name = 2
samples has dates of = List of (2021-07-02, 2021-09-03, 2021-10-03)

Inventory 3
name = 3
samples has dates of = List of (2021-08-02, 2021-09-03)

所以它应该按日期 DESC 排序,在那个 inventories 列表中,它应该有以下方式的数据,

Inventory 1
Inventory 3
Inventory 2

您想根据嵌套 collection 中的值对 collection 进行排序。 我们是怎么做到的?

您需要实现自定义比较器才能执行此操作...

static class InventoryComparator implements Comparator<Inventory> {
     public int compare(Inventory i1, Inventory i2) {
         // compare them here like this 
         // a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
         // this can be done by checking the nested lists
     }
}

然后你可以像这样对你的collection排序...

Collections.sort(inventoryList, new InventoryComparator());

这可以通过 Comparable 界面实现。

我假设 Sample 对象按日期排序,Inventory 对象通过比较最后一个(Sample 与最新日期)Samplesamples,但您可以在 Sample 重写的 compareTo() 方法中实现您自己的自定义比较逻辑。

  public class Inventory implements Comparable<Inventory> {

    private String name;
    private List<Sample> samples;

    public List<Sample> getSamples() {
      return samples;
    }

    public Inventory(String name, List<Sample> samples) {
      this.name = name;
      this.samples = samples;
    }

    @Override
    public int compareTo(Inventory inventory) {
      Optional<Sample> thisOldestSample = this.getSamples().stream().sorted().reduce((s1, s2) -> s2);
      Optional<Sample> thatOldestSample = inventory.getSamples().stream().sorted().reduce((s1, s2) -> s2);

      if (thisOldestSample.isPresent() && thatOldestSample.isPresent()) {
        return thisOldestSample.get().compareTo(thatOldestSample.get());
      } else {
        return 0;
      }
    }
  }

  public class Sample implements Comparable<Sample> {

    private int count;
    private String date;

    public String getDate() {
      return date;
    }

    public Sample(int count, String date) {
      this.count = count;
      this.date = date;
    }

    @Override
    public int compareTo(Sample sample) {
      return LocalDate.parse(sample.getDate()).isBefore(LocalDate.parse(this.getDate())) ? 1 : -1;
    }
  }

  @Test
  void shouldSortInventoriesBasedOnSampleDate() {
    Inventory one = new Inventory("1", List.of(new Sample(0, "2021-07-02"), new Sample(1, "2021-07-03")));
    Inventory two = new Inventory("2", List.of(new Sample(0, "2021-07-02"), new Sample(1, "2021-09-03"), new Sample(2, "2021-10-03")));
    Inventory three = new Inventory("3", List.of(new Sample(0, "2021-08-02"), new Sample(1, "2021-09-03")));

    List<Inventory> unsorted  = List.of(one, two, three);
    List<Inventory> sorted = unsorted.stream().sorted().collect(Collectors.toList());

    assertEquals(one, sorted.get(0));
    assertEquals(three, sorted.get(1));
    assertEquals(two, sorted.get(2));
  }