【问题标题】:Java ArrayList remove duplicates on a custom conditionJava ArrayList 在自定义条件下删除重复项
【发布时间】:2013-07-14 06:28:45
【问题描述】:

我有一个类项目的数组列表

Class foo {
    String name;
    String time;
}

我想获取具有唯一名称的 foo 对象列表。如果列表中的两个对象具有相同的名称,我只想保留时间最少的一个(字典很好)。该列表由底层库返回,因此我在插入时无法执行任何操作。我知道这很容易使用 O(n) 时间和空间中的地图(最坏情况)。有没有更有效的解决方案?

【问题讨论】:

    标签: java sorting arraylist set comparator


    【解决方案1】:

    有什么问题:

    // myList is the List returned by the library
    List<foo> new List = new ArrayList<foo>(new LinkedHashSet<foo>(myList));
    

    覆盖 equals()hashCode()in foo

    这个列表是由底层库返回的,所以我在插入时不能做任何事情。我知道这很容易使用 O(n) 时间和空间中的地图(最坏的情况)。有没有更有效的解决方案?

    我相信不,那是最优化的解决方案。看看这个SO answer

    【讨论】:

      【解决方案2】:

      为什么您不简单地使用 java.util.Set 并且不要忘记覆盖 foo 类的 equalshashCode 方法。

      【讨论】:

      • 正如我提到的,类 foo 是在底层库中定义的,所以我不能修改它。有没有办法可以为集合使用自定义比较器?
      【解决方案3】:

      即使有办法修改类以获得正确的散列码,但问题是,它应该是哪个散列码。通常,哈希码和相等性使用对象的所有属性,因此这样的标准实现在这里没有帮助,因为您希望拥有关于实例的单个属性的唯一对象。

      没有标准的哈希映射允许您提供自定义哈希和相等函数,但您可以为 排序 映射执行此操作。这不会像散列一样给你 O(1),但它可以给你 O(log(n)) 的查找仍然比 O(n) 更好。

      它是这样工作的:

      List<foo> list = // however you get it
      Set<foo> set=new TreeSet<>(FooComparator.INSTANCE);
      // now the set has no duplicates regarding foo.name
      
      …
      
      final class FooComparator implements Comparator<foo>
      {
        static final FooComparator INSTANCE = new FooComparator();
        public int compare(foo o1, foo o2)
        {
          return o1.name.compareTo(o2.name);
        }
      }
      class foo {
        String name;
        String time;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-22
        • 2015-07-10
        • 2014-04-22
        • 2011-01-26
        • 2012-08-25
        • 1970-01-01
        • 2013-02-24
        • 2015-12-22
        相关资源
        最近更新 更多