在 Java 中删除数组中重复项的最佳方法是什么?
-
21-08-2019 - |
题
我有一个对象数组,需要删除/过滤重复项。我打算只覆盖对象元素上的 equals 和 hachCode,然后将它们粘贴到 Set 中...但我想我至少应该轮询 stackoverflow 看看是否还有其他方法,也许是其他 API 的一些聪明方法?
其他提示
我在网上找到了这个
这里有两种方法可以让你删除 ArrayList 中的重复项。removeDuplicate 不会维护顺序,而removeDuplicateWithOrder 会维护顺序,但会带来一些性能开销。
删除重复方法:
/** List order not maintained **/ public static void removeDuplicate(ArrayList arlList) { HashSet h = new HashSet(arlList); arlList.clear(); arlList.addAll(h); }
该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); }
重写equals
和hashCode
太创建一组是我的第一个念头。这是很好的做法,在你的继承层次有这些方法的一些重写版本无论如何。
我的认为的,如果你使用一个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评价提出的观点:
为什么把自己放置在这一点呢?
为什么使用数组为不应该在所有保持重复的数据结构
在任何时候都使用Set
或SortedSet
(当元件具有自然顺序为好)以保持元件。如果你需要保持插入顺序,那么你可以使用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]);
}
}
}
您可以说是添加休息一下;语句后销毁,但那么你只发现第一个重复的,但如果这就是你永远不会有,那么这将是一个不错的小优化。