繁体   English   中英

在 java 的两个列表中查找 Common 元素,并使用 java8 将它们添加到列表中的起始位置,第二个列表的剩余元素

[英]Find Common element in two lists in java and add them to starting position in list with remaining element of second list using java8

我有两个包含名称的列表。 第一个列表l1包含选定的名称,第二个列表l2包含所有名称。

例子:

List<String> l1 = {"en", "cu", "eu"};
List<String> l2 = {"ch", "cu", "en", "eu", "pe"};

l1中的所有元素始终存在于l2中。

我想获得将所有通用名称放在开头然后是其余名称的输出,我需要将它们按升序排序。 像这样:

output ->  {cu, en, eu, cu, pe};

我正在尝试做的事情如下所示,但不知道如何将公共元素放在起始位置(第二个列表已经排序)并将其余元素放在公共元素之后

List<String> common = l2.stream().filter(l2::contains).collect(Collectors.toList());

如果我理解正确,您希望通过将第一个列表l1中存在的值放在开头来对第二个列表l2中的元素进行排序,并且这两个部分都应按字母顺序排序。

您需要为此目的定义一个自定义Comparator器。 从 Java 8 开始,创建 Comparator 的推荐方法是使用静态工厂方法,例如Comparator.comparing()

在实现比较器时,首先我们需要检查第一个列表中是否存在特定值,并根据检查结果对元素进行排序(提醒: boolean值的自然排序是false -> true )。 并且由于列表上的contains()是昂贵的(它在引擎盖下迭代列表,因此在O(n)中运行)将数据从第一个列表转储到HashSet并执行检查是性能明智的这个集合。

为了按字母顺序对列表的两个部分进行排序,我们需要通过应用Comparator.thenComparing()并提供Comparator.naturalOrder()作为参数来链接第二个比较器。

以下是它的实现方式:

List<String> l1 = List.of("en", "cu", "eu");
List<String> l2 = List.of("ch", "cu", "en", "eu", "pe");
        
// output ->  {cu,en,eu,cu,pe};
        
Set<String> toCheck = new HashSet<>(l1);
Comparator<String> comparator =
    Comparator.<String,Boolean>comparing(toCheck::contains).reversed()
        .thenComparing(Comparator.naturalOrder());
        
List<String> sorted = l2.stream()
    .sorted(comparator)
    .toList(); // for Java 16 or collect(Collectors.toList())
    
ystem.out.println(sorted);

输出:

[cu, en, eu, ch, pe]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM