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

kdfy810k  于 2022-12-25  发布在  Java
关注(0)|答案(1)|浏览(135)

我有两个包含名字的列表,第一个列表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());
cbeh67ev

cbeh67ev1#

如果我没理解错的话,您希望将第一个列表l1中的值放在开头,对第二个列表l2中的元素进行排序,并且这两部分都应该按字母顺序排序。
你需要定义一个自定义的Comparator来达到这个目的。从Java8开始,推荐的创建比较器的方法是使用静态工厂方法,比如Comparator.comparing()
在实现比较器时,首先我们需要检查第一个列表中是否存在特定值,并根据检查结果对元素进行排序(提醒:并且由于列表上的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]

相关问题