【问题标题】:Can I override Hashsets way of determine duplicate?我可以覆盖确定重复的 Hashsets 方式吗?
【发布时间】:2018-07-18 19:23:43
【问题描述】:

我正在使用存储 JSONObjects 的 Hashset。 我知道 hashset 使用 hashCode() 和 equals 方法来确定对象是否重复。

检查后我可以看到相同的 JSONObject 返回 2 个不同的 hascode,即使 equals() 和similar() 返回 true,这基本上意味着 JSONObject 没有正确覆盖 hashcode()。

我知道如果不正确使用像 Gson 或 Jackson 这样的库,我可能会解决这个问题,但我的代码在使用 JSONObject 方面投入了大量精力,并将所有代码重构为使用其中一个库将花费 2 很多时间。

我的问题 - 有没有办法设置 hashSet 方式来决定重复项?

类似

HashSet<JSONObject> hs = new HashSet();
hs.setDuplicateStrategy((o1, o2) => { o1.similar(o2)});

欢迎任何其他解决方案

【问题讨论】:

  • 你能用Set&lt;JSONObject&gt; hs = new TreeSet&lt;&gt;(jsonObjectComparable);吗?
  • 这意味着我必须将 JSONObject 包装在我自己的实现 Comparable 的对象中,对吗?
  • 我没能实现你写的,“jsonObjectComparable”在你的代码中是什么意思?它是一个实现可比较的新对象,那是它的一个实例吗?如果您进一步解释您的解决方案,我将不胜感激
  • 对不起,我的意思是Comparator&lt;JSONObject&gt;,它允许您具体说明这些对象的比较方式以及它们何时相等。
  • 我不知道这是否正是你的意思,但我写了一个答案来展示我设法做的事情和工作,请随时评论任何你认为我的解决方案有问题的地方,我会接受它作为2天内答复

标签: java json hashset


【解决方案1】:

由于您不能扩展 JSONObjectHashSet 不支持替代散列提供程序(如 TreeSet 使用比较器),简单的解决方案是将其包装在一个确实实现 hashCode() 的类中equals() 正确。

或者使用不同的Set 实现(例如TreeSet)。

【讨论】:

    【解决方案2】:

    正如@PeterLawrey 在 cmets 中建议的那样。

    我想出了一种方法来编写 TreeSet 以实际设置其逻辑可比方法

    Set<JSONObject> treeSet = new TreeSet<>((o1, o2) -> {
                                int intRes = 0;
                                if(!o1.similar(o2)){
                                    intRes = Math.random() > 0.5 ? 1 : -1;
                                }
                                return intRes;
                            });
    

    Math.random 部分是为了确保如果对象不相同,我们最终不会得到一个非常不平衡的树,因为所有不相同的对象都将位于树的同一侧

    【讨论】:

    • 拥有一个依赖随机的比较器是一个非常糟糕的主意™。只需选择一致的顺序即可。 TreeSet 的内部树的重新平衡与比较器结果无关,但您可以使用此策略暂时“失去”一半的树。 *TL;DR * 这里的随机位是错误的,它违反了Comparator的合同并违反了TreeSet
    • 但是我没有合乎逻辑的方法来确定哪个更大,因此另一种方法是只返回 1;在任何时候它们都不相等,这样树将所有项目都在同一侧
    • 关于树的那件事根本不是真的。我什至不知道你从哪里得到它,但我敦促你阅读self-balancing trees。并且有一种合乎逻辑的方法来确定哪个更大,只需比较他们的hashCode()s。 (总是返回1 和返回一个随机数一样糟糕。)
    猜你喜欢
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多