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

Java中检查列表是否包含另一列表全部元素(含重复元素校验)

带元素频次检查的列表包含判断方案

嘿,这个问题我之前也碰到过!普通的List.containsAll()方法只会验证每个元素是否存在于目标列表中,完全不考虑元素的出现次数——所以像你说的{a,a,d,e}和{a,d,e}这种情况,它会错误地返回true,但咱们要的是false,因为目标列表里的a数量不够覆盖源列表的。

下面给你两种可行的实现方式:

方法一:用HashMap手动统计频次(纯JDK,无需第三方库)

这是最通用的方式,完全依赖JDK自带的类就能实现:

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

public class ContainmentChecker {
    public static boolean isContainedWithFrequency(List<Character> source, List<Character> target) {
        // 统计源列表中每个字符的出现次数
        Map<Character, Integer> sourceCounts = new HashMap<>();
        for (char c : source) {
            sourceCounts.put(c, sourceCounts.getOrDefault(c, 0) + 1);
        }

        // 统计目标列表中每个字符的出现次数
        Map<Character, Integer> targetCounts = new HashMap<>();
        for (char c : target) {
            targetCounts.put(c, targetCounts.getOrDefault(c, 0) + 1);
        }

        // 逐一验证:源列表的每个字符,目标列表的数量都要足够
        for (Map.Entry<Character, Integer> entry : sourceCounts.entrySet()) {
            char charToCheck = entry.getKey();
            int requiredCount = entry.getValue();
            
            // 如果目标里没有这个字符,或者数量不够,直接返回false
            if (!targetCounts.containsKey(charToCheck) || targetCounts.get(charToCheck) < requiredCount) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        List<Character> listA = List.of('a', 'a', 'd', 'e');
        List<Character> listB = List.of('a', 'd', 'e');
        System.out.println(isContainedWithFrequency(listA, listB)); // 输出false,符合你的预期
    }
}

方法二:用Guava的Multiset(简洁高效,适合已引入Guava的项目)

如果你的项目已经在使用Guava库,那Multiset就是为这种带计数的集合场景设计的,代码会简洁很多:

import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import java.util.List;

public class MultisetContainmentChecker {
    public static boolean isContainedWithFrequency(List<Character> source, List<Character> target) {
        Multiset<Character> sourceMultiset = HashMultiset.create(source);
        Multiset<Character> targetMultiset = HashMultiset.create(target);

        // 遍历源集合的每个元素,检查目标集合的计数是否足够
        for (Multiset.Entry<Character> entry : sourceMultiset.entrySet()) {
            if (targetMultiset.count(entry.getElement()) < entry.getCount()) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        List<Character> listA = List.of('a', 'a', 'd', 'e');
        List<Character> listB = List.of('a', 'd', 'e');
        System.out.println(isContainedWithFrequency(listA, listB)); // 输出false
    }
}

额外说明

  • 这两种方法的核心逻辑都是对比元素的出现频次,确保源列表的每个元素的次数都不超过目标列表的对应次数。
  • 如果你的列表里可能出现null字符,记得在统计的时候加个空指针判断(比如if (c == null) { ... }),不过你的例子里都是普通字符,应该不需要。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:35:14