【问题标题】:Adding Object to HashSet将对象添加到 HashSet
【发布时间】:2018-11-16 04:45:33
【问题描述】:

我正在尝试将Object (Exception) 添加到Set,但是它会添加每个异常,即使有些是重复的。 debug

在我的例子中,重复项是具有相同 Detail 消息的异常。

如果Exception.getDetails() 尚不存在,我如何将Exceptions 正确添加到HashSet

除了HashSet,还有其他方法吗?

性能在这里是一个标准,二次解决方案 (O(n^2)) 不是一个选项。

【问题讨论】:

  • 为你的异常实现正确的 hashCode() 和 equals()
  • 你能告诉我们你为什么这样做吗?
  • 用我的messageFactory在前端正确显示

标签: java performance set equals hashset


【解决方案1】:

你有几个选择:

  • 在您的异常类中覆盖 hashcodeequals
  • 使用TreeSet 和自定义Comparator
  • 使用Map<String, Exception>,其中键是getDetails() 结果(例如HashMap

【讨论】:

    【解决方案2】:

    您需要覆盖 Execptions 的比较方式,以便它以您想要的方式识别重复项。您不能对 HashSet 执行此操作,但可以对 TreeSet 执行此操作,例如

    Set<Exception> exceptions = new TreeSet<>(Comparator.comparing(Object::toString));
    

    这个例子比较了toString,这是大多数情况下的异常类型和消息。

    如果你真的想使用 HashSet,你需要将 Exception 包装在一个实现 hashCode 并等于你想要的方式的类中。

    如果你只关心类型和消息,你可以只存储每个异常的 toString

    final Set<String> exceptions = new HashSet<>();
    
    public void addException(Exception e) {
        exceptions.add(e.toString());
    }
    

    【讨论】:

    • 其实to字符串是不够的,后面我会用它做进一步的处理。但是你的带有 log(n) 的 TreeSet 解决方案就像一个魅力。
    • @0x2E5 在这种情况下,您可能会考虑 assylias 建议使用 Map&lt;String, Exception&gt;,即每次添加 O(1)。
    【解决方案3】:

    您需要重新定义equalshashCode 方法。

    如果detailString,您可以按如下方式重新定义它们

    public boolean equals(Object obj) {
       if (!(obj instanceof YourException)) {
         return false;
       } 
       return getDetail().equals(((YourException) obj).getDetail());
    }
    
    public int hashCode() {
       return getDetail().hashCode();
    }
    

    将此代码视为编程的基础。例如,您必须检查空值。

    一旦重新定义 equals 和 hashCode 在 TreeSet 中插入 YourException 是在 O(log(n)) 中完成的操作,其中 n 是集合的大小,来自 javadoc

    此实现为基本操作(添加、删除和包含)提供有保证的 log(n) 时间成本

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 2016-01-21
      • 1970-01-01
      • 2015-08-16
      相关资源
      最近更新 更多