【问题标题】:Getting incorrect value from Map<String, Map<String, Object>>从 Map<String, Map<String, Object>> 获取不正确的值
【发布时间】:2015-07-29 10:27:02
【问题描述】:

我在尝试从 Map 获取值时遇到了问题。这是详细信息。

我声明了这个结构:

Map<String, Map<String, IrregularWord>> result4 = new TreeMap<>();

作为键,我使用了2_5_13_5_121_4_2 等字符串。当我填写result4 时,我得到了这个结果

然后我尝试从result4 读取所有值并用它们做一些事情:

for (String key : result4.keySet()) {
    Map<String, IrregularWord> words = result4.get(key);
    // other code
}

key == 2_5_1 我有words.size() == 14 而不是9,因为它是真实的result4

更新:此示例的正确值为9

我的问题是为什么我得到了不正确的结果? Map的hash算法可能有问题?

感谢您的帮助。

【问题讨论】:

  • 那么你认为什么是正确的? 9 还是 14?可能是 IntelliJ IDEA 错误?
  • 正确的值是9,但在这种情况下我得到了14
  • 请告诉我们Minimal, Complete, and Verifiable example,以便我们重现您的问题。目前看起来你只是忽略了一些东西。至少提供更多的代码,包括地图填充和地图迭代,没有任何可能导致效果消失的遗漏。
  • @Soana,根据截图,这是第一个键,所以没有之前的迭代。
  • 正如 Tagir 所说,如果您想要明确的答案,则需要包含相关代码。任何人都可以做的就是根据您当前的问题进行推测。

标签: java hashmap java-8 treemap keyset


【解决方案1】:

我不知道为什么,但我自己的Comparator 的所有问题我没有在这里写,这是我的错误。

所以,我真的用过

Map<String, Map<String, IrregularWord>> result4 = new TreeMap<>(new LessonsShortPathComparator());

Comparator:

public class LessonsShortPathComparator implements Comparator<String> {
    public static String LES_SHORT_PATH_REG_EXP = "[0-9]+_[0-9]+_[0-9]+";
    public int compare(String o1, String o2) {
        String[] o1Str = o1.split("_");
        String[] o2Str = o2.split("_");
        if (Integer.parseInt(o1Str[0]) > Integer.parseInt(o2Str[0]))
            return 1;
        if (Integer.parseInt(o1Str[1]) > Integer.parseInt(o2Str[1]))
            return 1;
        if (Integer.parseInt(o1Str[2]) > Integer.parseInt(o2Str[2]))
            return 1;
        return 0;
        } else
            return o1.compareTo(o2);
    }
}

这里有个问题。我只比较更大的价值,但不包括更少。当我这样修复它时:

public class LessonsShortPathComparator implements Comparator<String> {
    public static String LES_SHORT_PATH_REG_EXP = "[0-9]+_[0-9]+_[0-9]+";
    public int compare(String o1, String o2) {
        if (o1.matches(LES_SHORT_PATH_REG_EXP) && o2.matches(LES_SHORT_PATH_REG_EXP)) {
            String[] o1Str = o1.split("_");
            String[] o2Str = o2.split("_");

            for (int i = 0; i < o1Str.length; i++) {
                int i1 = Integer.parseInt(o1Str[i]);
                int i2 = Integer.parseInt(o2Str[i]);
                if (i1 - i2 != 0) {
                    return i1 - i2;
                }
            }
            return 0;
        } else
            return o1.compareTo(o2);
    }
}

现在一切正常。我不明白为什么?也许在我的Comparator 之后指向IrregularWord 的链接变坏了。首先TreeMap 比较键并找到正确的值位置,但反之则不然。

抱歉,描述不完整。我真的不知道Comparator 会影响到这个。

【讨论】:

  • 我想问一下比较器,但有问题你明确指定了result4 = new TreeMap&lt;&gt;();,所以我得出结论你正在使用自然字符串排序。以后请注意将真实代码放入问题中以避免可能的混淆。
  • 当然!也许你能解释一下为什么Comparator 破坏了 TreeMap 或者它是正确的工作?
  • 比较器必须满足其contract:反对称、传递性和稳定性。您的比较器没有满足它(实际上固定的比较器也可能会破坏它,但这是另一回事),因此您的数据结构已损坏。
  • 非常感谢您的解释!这对我来说是一次很好的体验。
猜你喜欢
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 2018-09-22
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 2014-01-29
  • 1970-01-01
相关资源
最近更新 更多