在Java中删除数组中重复项的最佳方法是什么?

时间:2008-12-10 20:07:09

标签: java filtering duplicates

我有一个需要删除/过滤重复项的对象数组。 我只是重写等于& hachCode对象元素,然后将它们粘贴在一个Set中...但我想我至少应该轮询stackoverflow以查看是否有其他方法,也许是其他一些API的一些聪明的方法?

9 个答案:

答案 0 :(得分:21)

我同意您覆盖hashCode()equals()的方法并使用实现Set的内容。

这样做也使任何其他开发人员都清楚地知道需要非重复的特性。

另一个原因 - 您现在可以选择最符合您需求的实施方案:

您无需更改代码即可在将来更改实施。

答案 1 :(得分:9)

我在网上发现了这个

以下两种方法允许您删除ArrayList中的重复项。 removeDuplicate不维护removeDuplicateWithOrder维护订单的顺序,但是会有一些性能开销。

  1. removeDuplicate方法:

    /** 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);
    }
    

答案 2 :(得分:3)

覆盖equalshashCode并创建一个集合也是我的第一个想法。最好在继承层次结构中使用这些方法的某些重写版本。

认为如果你使用LinkedHashSet,你甚至会保留独特元素的顺序......

答案 3 :(得分:2)

基本上,您需要一个支持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>添加方法添加重复项时(抛出异常或在不同的索引处重新添加项目)将是选项:您可以选择其中一个或者可由该类用户配置)。

答案 4 :(得分:2)

使用列表 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;
   } 

答案 5 :(得分:1)

我想重申Jason在评论中提出的观点:

为什么要把自己置于那个位置?

为什么要将数组用于不应该重复的数据结构?

始终使用SetSortedSet(当元素具有自然顺序时)来保存元素。如果您需要保留广告订单,那么您可以按照指示使用LinkedHashSet

必须对一些数据结构进行后期处理通常暗示您应该选择另一个数据结构。

答案 6 :(得分:1)

当然,最初的帖子引出了一个问题,“你是如何获得该数组(可能包含重复的条目)?”

您是否需要将数组(带有重复项)用于其他目的,或者您是否可以从头开始使用Set?

或者,如果您需要知道每个值的出现次数,可以使用Map<CustomObject, Integer>来跟踪计数。此外,Multimap类的Google Collections定义可能有用。

答案 7 :(得分:0)

Set绝对是您最好的选择。从数组中删除东西(不创建新数组)的唯一方法是将它们清空,然后最后进行大量的空检查。

答案 8 :(得分:0)

从一般编程标准说起,您可以始终双重枚举集合,然后比较源和目标。

如果您的内部枚举总是在源之后开始一个条目,那么它相当有效(伪代码可以遵循)

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]);
        }
    }
}

你可以说是一个休息时间;在破坏之后的陈述但是你只发现了第一个副本,但如果这就是你将拥有的所有东西,那么这将是一个不错的小优化。