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

如何让Set类的retainAll方法计算交集时不忽略重复元素

实现包含重复元素的列表交集方案

问题根因

你之前使用HashSet的retainAll方法无法保留重复元素,是因为Set的核心特性就是存储不重复的元素,初始化阶段就已经把list1里的两个"a"合并为1个,自然无法输出符合预期的结果。

实现方案

我们可以通过统计元素出现频率的方式实现,逻辑是先统计其中一个列表各元素的出现次数,再遍历另一个列表,匹配到存在且剩余次数大于0的元素就加入结果集,同时扣减对应频率:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ListIntersectionWithDuplicate {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("a");
        list1.add("k");
        list1.add("s");
        list1.add("f");
        list1.add("a");
        list1.add("j");
        list1.add("e");

        List<String> list2 = new ArrayList<>();
        list2.add("a");
        list2.add("a");
        list2.add("e");
        list2.add("f");
        list2.add("j");

        // 优先统计较短列表的频率,降低性能消耗
        List<String> countList = list1.size() <= list2.size() ? list1 : list2;
        List<String> iterateList = list1.size() <= list2.size() ? list2 : list1;

        Map<String, Integer> frequencyMap = new HashMap<>();
        for (String s : countList) {
            frequencyMap.put(s, frequencyMap.getOrDefault(s, 0) + 1);
        }

        List<String> result = new ArrayList<>();
        for (String s : iterateList) {
            if (frequencyMap.containsKey(s) && frequencyMap.get(s) > 0) {
                result.add(s);
                frequencyMap.put(s, frequencyMap.get(s) - 1);
            }
        }

        // 输出结果:[a, a, e, f, j] 符合预期
        System.out.println(result);
    }
}

方案说明

  • 该方案最终输出的交集重复元素数量,取两个列表中对应元素出现次数的较小值,比如你给出的示例中list1有2个"a"、list2有2个"a",所以交集中保留2个"a",完全匹配需求。
  • 优先统计长度更短的列表的元素频率,可以降低内存占用和统计耗时,性能更优。

内容的提问来源于stack exchange,提问作者In-young Choung

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:39:02