You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现:将列表公共元素前置并整体升序排序

问题描述

我有两个存储名称的列表:

  • 第一个列表l1包含选定名称
  • 第二个列表l2包含全部名称

示例代码:

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

已知l1中的所有元素均存在于l2中。

需要生成符合以下要求的输出列表:

  1. 所有公共名称(即同时存在于l1和l2中的元素)放在列表开头
  2. l2中剩余的元素紧随其后
  3. 公共元素部分和剩余元素部分各自按升序排列

示例输出:

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

我尝试了以下代码,但不知道如何将公共元素放在开头、剩余元素放在后面(l2已排序):

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

方案一:分步处理(逻辑清晰)

先分别处理公共元素和剩余元素,再合并:

// 优化:将l1转为HashSet提升contains效率
Set<String> l1Set = new HashSet<>(l1);

// 1. 排序l1中的元素(即所有公共元素)
List<String> sortedCommon = l1.stream()
        .sorted()
        .collect(Collectors.toList());

// 2. 提取l2中不在l1里的元素并排序
List<String> sortedRemaining = l2.stream()
        .filter(item -> !l1Set.contains(item))
        .sorted()
        .collect(Collectors.toList());

// 3. 合并两个列表
List<String> result = new ArrayList<>();
result.addAll(sortedCommon);
result.addAll(sortedRemaining);

方案二:自定义比较器(代码简洁)

通过自定义排序规则,一次性完成排序和分组:

Set<String> l1Set = new HashSet<>(l1);

List<String> result = l2.stream()
        .sorted((a, b) -> {
            boolean aInL1 = l1Set.contains(a);
            boolean bInL1 = l1Set.contains(b);
            // 优先把在l1中的元素排在前面
            if (aInL1 != bInL1) {
                return aInL1 ? -1 : 1;
            }
            // 同组内按字符串升序排列
            return a.compareTo(b);
        })
        .collect(Collectors.toList());

说明

  • 把l1转为HashSet是为了优化contains方法的性能,从O(n)降到O(1),当列表元素较多时效果明显。
  • 两种方案都能满足需求,可根据代码风格偏好选择。

内容的提问来源于stack exchange,提问作者jitendra varshney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:30:46