我有一个客户向量:
Vector<Customer> customers = Vector<Customer>();
客户看起来像:
public class Customer {
private String firstName;
private String lastName;
private Customer partner;
}
示例数据:
- 彼得;母鹿;格洛丽亚·文
- 约翰,多伊,空
- 格洛里亚;文;彼得·多伊
- 强尼;标签;零
我想通过将合作伙伴分组在一起来对这个向量进行排序。所以结果应该看起来像这样:
- 彼得;母鹿;格洛丽亚·文
- 格洛里亚;文;彼得·多伊
- 约翰,多伊,空
- 强尼;标签;零
任何想法如何有效地做到这一点?
首先,我尝试通过覆盖比较方法使用自定义排序函数(用于集合)来解决此问题。 问题是我只是在比较同一字段时这样做的。 在这种情况下,我必须比较基本上像这样的内容"this.compareTo(getPartner().getPartner());"但我无法进入跑步。
第二次尝试显然是手动一遍又一遍地循环向量并"手动"对其进行排序,我宁愿避免这种情况,因为我认为这是一个常见问题,并且有人已经提出了更好的解决方案。
谢谢!
注意:类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);
然后实施定制比较器byLastAndFirst
和byPartnerLastAndFirst
并应用于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);
输出(可以改进为不显示空伙伴)
`Mary Blake` & `Adam Swan`
`Adam Swan` & `Mary Blake`
`Peter Doe` & `Gloria Ven`
`Gloria Ven` & `Peter Doe`
`John Doe` & NULL
`Kyle Flint` & NULL