我有一个对象数组,需要删除/过滤重复项。我打算只覆盖对象元素上的 equals 和 hach​​Code,然后将它们粘贴到 Set 中...但我想我至少应该轮询 stackoverflow 看看是否还有其他方法,也许是其他 API 的一些聪明方法?

有帮助吗?

解决方案

我同意你的重写方法 hashCode()equals() 并使用实现的东西 Set.

这样做还可以让任何其他开发人员绝对清楚需要非重复特征。

另一个原因 - 您现在可以选择最能满足您需求的实现:

并且您不必更改代码来更改将来的实现。

其他提示

我在网上找到了这个

这里有两种方法可以让你删除 ArrayList 中的重复项。removeDuplicate 不会维护顺序,而removeDuplicateWithOrder 会维护顺序,但会带来一些性能开销。

  1. 删除重复方法:

    /** List order not maintained **/
    public static void removeDuplicate(ArrayList arlList)
    {
     HashSet h = new HashSet(arlList);
     arlList.clear();
     arlList.addAll(h);
    }
    
  2. 该removeDuplicateWithOrder方法:

    /** List order maintained **/
    public static void removeDuplicateWithOrder(ArrayList arlList)
    {
       Set set = new HashSet();
       List newList = new ArrayList();
       for (Iterator iter = arlList.iterator(); iter.hasNext();) {
          Object element = iter.next();
          if (set.add(element))
             newList.add(element);
       }
       arlList.clear();
       arlList.addAll(newList);
    }
    

重写equalshashCode太创建一组是我的第一个念头。这是很好的做法,在你的继承层次有这些方法的一些重写版本无论如何。

我的认为的,如果你使用一个LinkedHashSet你甚至保存独特的元素的顺序...

基本上,你要支持随机访问的LinkedHashSet<T>接口List<T>实现。因此,这是你所需要的:

  

public class LinkedHashSetList<T> extends LinkedHashSet<T> implements List<T> {

     

// Implementations for List<T> methods here   ...

     

}

List<T>方法的实施将访问和处理的底层LinkedHashSet<T>。关键是有这个类正确的行为当一个人试图通过List<T>添加重复添加方法(在不同的索引抛出异常或重新添加项目将选择:你可以选择一个或由用户进行配置之类的)。

使用一个列表 distinctList 在第一时间以记录元件iterator跌入它,返回distinctList作为列表中删除所有重复

 private List removeDups(List list) {
        Set tempSet = new HashSet();
        List distinctList = new ArrayList();
        for(Iterator  it = list.iterator(); it.hasNext();) {
            Object next = it.next();
            if(tempSet.add(next)) {
                distinctList.add(next);
            } 
        }
        return distinctList;
   } 

我想重申由Jason评价提出的观点:

为什么把自己放置在这一点呢?

为什么使用数组为不应该在所有保持重复的数据结构

在任何时候都使用SetSortedSet(当元件具有自然顺序为好)以保持元件。如果你需要保持插入顺序,那么你可以使用LinkedHashSet,因为它已经指出。

具有到后处理的一些数据结构是经常,你应该已经选择的不同的一个以开始提示。

当然原来的职位引出了一个问题,“你是怎么得到这个数组(可能包含重复的条目)摆在首位?”

您是否需要用于其他目的的阵列(重复),或者可能你只是使用Set从一开始?

另外,如果你需要知道每个值的出现次数,你可以使用一个Map<CustomObject, Integer>跟踪计数。此外,谷歌集合中Multimap之类的定义可能是使用的。

一个Set绝对是你最好的选择。从数组中取出的东西(不创建一个新的)的唯一方法是为空出来,然后结束了很多空检查以后。

这是一个通用的编程标准说起你总是可以双枚举集合,则比较源和目标。

如果你的内心枚举总是从源后一个条目,这是相当有效的(伪代码遵循)

foreach ( array as source )
{
    // keep track where we are in the array
    place++;
    // loop the array starting at the entry AFTER the current one we are comparing to
    for ( i=place+1; i < max(array); i++ )
    {
        if ( source === array[place] )
        {
            destroy(array[i]);
        }
    }
}

您可以说是添加休息一下;语句后销毁,但那么你只发现第一个重复的,但如果这就是你永远不会有,那么这将是一个不错的小优化。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top