【问题标题】:Alternative to using TreeSet in java?在 java 中使用 TreeSet 的替代方案?
【发布时间】:2014-03-03 01:00:50
【问题描述】:

我正在寻找一个 Set 类,它将使用给定的比较器来 removeAll()。

我使用的是 TreeSet,但几个小时后我把头发扯下来试图弄清楚为什么我的 removeAll() 没有删除我发现的任何内容...

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4730113

长话短说 removeAll() 使用 equals() 方法。 (但奇怪的是 remove() 方法没有......)

我确实想要一个 Set 来删除重复项,最好使用比较器但不是必需的,并且我不能覆盖 equals 方法 b/c 我需要它来处理其他逻辑。显然我想避免在所有元素上创建一个调用 remove() 的循环,以免将来让我(或其他人)感到困惑。

这样的动物动物存在吗?

【问题讨论】:

  • 创建自己的并将所有方法委托给树集但全部删除?
  • 也许可以创建你自己的 TreeSet 派生类,它的行为如你所愿,并重写了一些方法?
  • 我希望存在某些东西,所以我不必这样做。我已经查看了 java lib 和 apache commons,但他们似乎没有(我可能会错过它)。 TreeSet 的行为方式对我来说仍然很奇怪。

标签: java set comparator removeall


【解决方案1】:

您是否重写了 TreeSet 包含的对象的 equals 和 hashcode 方法?

【讨论】:

    【解决方案2】:

    你可以使用

    public static <T> void removeAll(TreeSet<T> set, Collection<T> toRemove)
    {
      TreeSet<T> toRemoveTreeSet=new TreeSet<>(set.comparator());
      toRemoveTreeSet.addAll(toRemove);
      set.removeAll(toRemoveTreeSet);
    }
    

    public static <T> void removeAll(TreeSet<T> set, Collection<?> toRemove)
    {
      for(Object o:toRemove) set.remove(o);
    }
    

    【讨论】:

      【解决方案3】:

      这种行为实际上非常合理。 'equals' 确定两个对象是否具有相同的标识,比较确定针对它们的某种形式的大小之间的关系。

      两个对象可以完全不同(等于返回 false)但仍然具有相同的大小(例如考虑复数)。

      您的期望是 removeAll 将根据对象的“大小”(由 compare 定义)确定需要删除的内容,您看到的是删除实际上是根据身份进行的。

      简而言之,使用循环:-)

      【讨论】:

        【解决方案4】:

        TreeSet.removeAll 方法接受 Collection&lt;?&gt; 作为参数。集合中的对象可以是任何类型,不一定是 Comparable 对象。您需要使用不同的方法制作自己的 Set。请注意,错误解决方案是“无法修复”

        【讨论】:

          猜你喜欢
          • 2012-07-26
          • 2013-03-10
          • 2013-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-28
          • 2015-04-29
          相关资源
          最近更新 更多