Java 对象向量和 Sort/Group 第三个值

Java Vector of Object and Sort/Group by third value

我有一个客户向量:

Vector<Customer> customers = Vector<Customer>();

客户看起来像:

public class Customer {

   private String firstName;
   private String lastName;
   private Customer partner;
}

示例数据:

  1. 彼得;母鹿;格洛丽亚文
  2. John, Doe, null
  3. 格洛丽亚;文;彼得·多伊
  4. 强尼;标签;空

我想通过将合作伙伴分组在一起来对这个向量进行排序。所以结果应该是这样的:

  1. 彼得;母鹿;格洛丽亚文
  2. 格洛丽亚;文;彼得·多伊
  3. John, Doe, null
  4. 强尼;标签;空

有什么想法可以有效地做到这一点吗?

首先,我尝试通过覆盖比较方法来使用自定义排序函数(用于集合)来解决此问题。 问题是我只是在比较同一个字段时才这样做的。 在这种情况下,我基本上必须比较类似这样的东西“this.compareTo(getPartner().getPartner());”但我无法进入 运行.

第二次尝试显然是手动一遍又一遍地遍历向量并“手动”对其进行排序,我宁愿避免这种情况,因为我认为这是一个常见问题,并且有人已经提出了更好的解决方案.

谢谢!

注意:class Vector 已过时,可能会被 List 接口的其他实现替换,例如 ArrayList.

nullsLast 比较器的帮助下,将没有合作伙伴的客户放在最后,可以应用更简单的排序。

假设我们有以下测试数据:

Customer a = new Customer("Peter", "Doe");
Customer x = new Customer("Gloria", "Ven", a);
Customer b = new Customer("Adam", "Swan");
Customer z = new Customer("Mary", "Blake", b);
Customer p = new Customer("John", "Doe");
Customer y = new Customer("Kyle", "Flint");

List<Customer> data = Arrays.asList(a, b, p, x, y, z);

// a Vector may be created similarly
// Vector<Customer> data = new Vector<>(Arrays.asList(a, b, p, x, y, z));

Collections.shuffle(data);
System.out.println(data);

然后自定义比较器 byLastAndFirstbyPartnerLastAndFirst 被实现并应用于 partner 领域,然后是自己的客户。

Comparator<Customer> byLastAndFirst = Comparator.comparing(Customer::getLastName)
        .thenComparing(Customer::getFirstName);

Comparator<Customer> byPartnerLastAndFirst = Comparator
    .comparing(Customer::getPartner, Comparator.nullsLast(byLastAndFirst))
    .thenComparing(byLastAndFirst);

data.sort(byPartnerLastAndFirst);
System.out.println(data);

这提供了以下结果:

[`Adam Swan` & `Mary Blake`, `Gloria Ven` & `Peter Doe`, `Mary Blake` & `Adam Swan`, `Peter Doe` & `Gloria Ven`, `John Doe` & NULL, `Kyle Flint` & NULL]

但是,此解决方案中的合作伙伴并未组合在一起。

可以使用 Stream API 实现额外的分组,方法是将客户收集到排序映射中,其中键是客户和合作伙伴的排序列表,合作伙伴可能是 null,并且然后使用 Stream::flatMap 将地图的键映射回客户列表并排除 null 合作伙伴:

Comparator<List<Customer>> sort = Comparator.comparing(list -> list.get(0), byPartnerLastAndFirst);

data.stream()
    .collect(Collectors.groupingBy(
        c -> Arrays.asList(c, c.getPartner())
                .stream()
                .sorted(Comparator.nullsLast(byLastAndFirst))
                .collect(Collectors.toList()),
        () -> new TreeMap<>(sort),
        Collectors.toList()
    ))
    .keySet().stream() // Stream<List<Customer>>
    .flatMap(list -> list.stream().filter(Objects::nonNull))
    .forEach(System.out::println);

输出(可能会改进为不显示 NULL 伙伴)

`Mary Blake` & `Adam Swan`
`Adam Swan` & `Mary Blake`
`Peter Doe` & `Gloria Ven`
`Gloria Ven` & `Peter Doe`
`John Doe` & NULL
`Kyle Flint` & NULL