Java 如何从两个HashMap检索公共键并将结果放入ArrayList

Java 如何从两个HashMap检索公共键并将结果放入ArrayList,java,list,for-loop,arraylist,hashmap,Java,List,For Loop,Arraylist,Hashmap,我试图从两个hashmap中检索公共“键”,并将结果放入ArrayList中。为此,我提出了以下逻辑 List<String> commonList = new ArrayList<String>(); for(String key : mapA.keySet()) { if(mapB.get(key) !=null ) { if(mapA.get(key).equals(mapB.get(key))) {

我试图从两个hashmap中检索公共“键”,并将结果放入ArrayList中。为此,我提出了以下逻辑

    List<String> commonList = new ArrayList<String>();
    for(String key : mapA.keySet()) {
        if(mapB.get(key) !=null ) {
            if(mapA.get(key).equals(mapB.get(key))) {
                commonList.add(key);
            }
        }
    }
mapA共有219个条目,mapB共有210个条目。当我从这个问题开始运行逻辑时,我得到总共79个条目的输出,而带有宏的MicrosoftExcel给了我210个常用键。 如何检查两个HashMaps:mapA和mapB并检索两个HashMaps中的公共键? 有人能告诉我我在这里犯的错误吗?

您正在检查相等的值,而不是相等的键。如果编写ifmapA.containsKeykey并更改!=空检查containsKey,因为它通常更快

您也可以只使用Set.retainal并传入映射的两个键集

Set<String> keys = new HashSet<>( mapA.keySet() );
keys.retainAll( mapB.keySet() );

问题在于您根据键而不是键本身检查值的相等性

List<String> commonList = new ArrayList<String>();
    for(String key : mapA.keySet()) {
    if (mapB.containsKey(key)) {
        commonList.add(key);
    }
}
您可以使用retainAll方法:


在当前代码中,实际上是比较两个映射中给定键的值。事实上,您真的只想在这里取两个关键点集的交点,所以请执行以下操作:

Set<String> s1 = mapA.keySet();
Set<String> s2 = mapB.keySet();
s1.retainAll(s2);

List<String> result = new ArrayList<>();
result.addAll(s1);

您也可以使用Java8的流来实现这一点

List<String> intersection = mapA.keySet()
                .stream()
                .filter(mapB.keySet()::contains)
                .collect(Collectors.toList());
        System.out.println(intersection.size());

mapB只有209个条目,因为最后两个条目具有相同的键

您的代码还比较了数据,因此79是两个映射中具有相同数据的公共键。这就是你想要的吗

如果您只需要公共密钥,只需将两组os密钥相交即可。您可以使用下面的示例中的方法retainal来实现这一点。此方法在集合中仅保留其他集合中的所有值。结果是209而不是210,因为mapB只有209个唯一键

public class Test {

    public void test() {
        final List<String> commonList = new ArrayList<String>();
        final Map<String, String> mapA = new HashMap<>();
        final Map<String, String> mapB = new HashMap<>();
        fillA(mapA);
        System.out.println("Size A: " + mapA.size());
        fillB(mapB);
        System.out.println("Size B: " + mapB.size());
        for (final String key : mapA.keySet()) {
            if (mapB.get(key) != null) {
                if (mapA.get(key).equals(mapB.get(key))) {
                    commonList.add(key);
                }
            }
        }
        System.out.println("CommonList: " + commonList.size());
        final Set<String> keySetA = mapA.keySet();
        final Set<String> keySetB = mapB.keySet();
        final Set<String> commonKeySet = new HashSet<>(keySetA);
        commonKeySet.retainAll(keySetB);
        System.out.println("CommonKey:" + commonKeySet.size());
    }

    private void fillA(Map<String, String> mapA) {
        // put your A data here
    }

    private void fillB(Map<String, String> mapB) {
        // put your B data here        
    }
}

List commonList=新的ArrayList;对于字符串键:mapA.keySet{ifmapB.containsKeykey&&!commonList.containsKeykey{commonList.addkey;}}}应该可以做到这一点,它是对原始解决方案的编辑。还包括重复项。如果您不在这里使用set。@Sudhiroja我刚刚编辑了我的答案,也许这解决了您看到的问题。如果不是,那么哈希映射的键的重复的概念就没有多大意义,因为你不能这样做。s1.retainals2会破坏原始的映射,因为retainAll会在基础映射上操作。@ThomasTimbul你是对的,我添加了一个选项,通过将密钥集复制到一个新的密钥集来避免这种情况发生。@TimBiegeleisen尝试并测试了这两种方法,但我选择了第二种解决方案,因为它看起来很有效。
Set<String> s1 = mapA.keySet();
Set<String> s2 = mapB.keySet();
s1.retainAll(s2);

List<String> result = new ArrayList<>();
result.addAll(s1);
TreeSet<String> s1 = new TreeSet<String>(mapA.keySet());
Set<String> s2 = mapB.keySet();
s1.retainAll(s2);

List<String> result = new ArrayList<>();
result.addAll(s1);
List<String> intersection = mapA.keySet()
                .stream()
                .filter(mapB.keySet()::contains)
                .collect(Collectors.toList());
        System.out.println(intersection.size());
public class Test {

    public void test() {
        final List<String> commonList = new ArrayList<String>();
        final Map<String, String> mapA = new HashMap<>();
        final Map<String, String> mapB = new HashMap<>();
        fillA(mapA);
        System.out.println("Size A: " + mapA.size());
        fillB(mapB);
        System.out.println("Size B: " + mapB.size());
        for (final String key : mapA.keySet()) {
            if (mapB.get(key) != null) {
                if (mapA.get(key).equals(mapB.get(key))) {
                    commonList.add(key);
                }
            }
        }
        System.out.println("CommonList: " + commonList.size());
        final Set<String> keySetA = mapA.keySet();
        final Set<String> keySetB = mapB.keySet();
        final Set<String> commonKeySet = new HashSet<>(keySetA);
        commonKeySet.retainAll(keySetB);
        System.out.println("CommonKey:" + commonKeySet.size());
    }

    private void fillA(Map<String, String> mapA) {
        // put your A data here
    }

    private void fillB(Map<String, String> mapB) {
        // put your B data here        
    }
}