简体   繁体   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

I have two lists containing names.我有两个包含名称的列表。 The first list l1 has selected names, and the second list l2 has all the names.第一个列表l1包含选定的名称,第二个列表l2包含所有名称。

Example:例子:

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

All the elements in l1 always exist in l2 . l1中的所有元素始终存在于l2中。

I want to obtain the output where all the common names are placed at the beginning followed by the remaining names, and I need them to be sorted in the ascending order.我想获得将所有通用名称放在开头然后是其余名称的输出,我需要将它们按升序排序。 Like this:像这样:

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

What I was trying to do I've shown below, but don't getting the idea that how to place common elements at the starting position (2nd list is already sorted) and place the remaining elements after the common elements我正在尝试做的事情如下所示,但不知道如何将公共元素放在起始位置(第二个列表已经排序)并将其余元素放在公共元素之后

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

If I understood correctly, you want to sort the elements from the second list l2 by placing the values that are present in the first list l1 at the beginning, and both part should be sorted in the alphabetical order.如果我理解正确,您希望通过将第一个列表l1中存在的值放在开头来对第二个列表l2中的元素进行排序,并且这两个部分都应按字母顺序排序。

You need to define a custom Comparator for that purpose.您需要为此目的定义一个自定义Comparator器。 Since Java 8 the recommended way to create a Comparator is to use static factory methods like Comparator.comparing() .从 Java 8 开始,创建 Comparator 的推荐方法是使用静态工厂方法,例如Comparator.comparing()

While implementing the Comparator, firstly we need to check if a particular value is present in the first list and order the elements by the result of this check (reminder: natural ordering of boolean values is false -> true ).在实现比较器时,首先我们需要检查第一个列表中是否存在特定值,并根据检查结果对元素进行排序(提醒: boolean值的自然排序是false -> true )。 And since contains() on a list is costful (it does iteration over the list under the hood and therefore runs in O(n) ) it would be performance-wise to dump the data from the first list into a HashSet and perform checks against this Set.并且由于列表上的contains()是昂贵的(它在引擎盖下迭代列表,因此在O(n)中运行)将数据从第一个列表转储到HashSet并执行检查是性能明智的这个集合。

The in order to sort both parts of the list alphabetically, we need can chain the second comparator by applying Comparator.thenComparing() and providing Comparator.naturalOrder() as the argument.为了按字母顺序对列表的两个部分进行排序,我们需要通过应用Comparator.thenComparing()并提供Comparator.naturalOrder()作为参数来链接第二个比较器。

Here's how it might be implemented:以下是它的实现方式:

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);

Output:输出:

[cu, en, eu, ch, pe]

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

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