那里有没有重复的List实现?
我知道SortedSet
,但在我的情况下,我需要的东西,实现List
,而不是Set
。 那么在API或其他地方是否有实现?
实施自己应该不难,但我想到了为什么不先问这里的人呢?
标准库中没有Java集合来执行此操作。 LinkedHashSet<E>
保留了与List
类似的sorting,所以如果你想将List
作为List
来使用,你将得到你想要的语义。
或者, Commons Collections (或commons-collections4
,对于通用版本)有一个List
,它可以完成你想要的工作: SetUniqueList
/ SetUniqueList<E>
。
所以这是我最终做的。 我希望这可以帮助别人。
class NoDuplicatesList<E> extends LinkedList<E> { @Override public boolean add(E e) { if (this.contains(e)) { return false; } else { return super.add(e); } } @Override public boolean addAll(Collection<? extends E> collection) { Collection<E> copy = new LinkedList<E>(collection); copy.removeAll(this); return super.addAll(copy); } @Override public boolean addAll(int index, Collection<? extends E> collection) { Collection<E> copy = new LinkedList<E>(collection); copy.removeAll(this); return super.addAll(index, copy); } @Override public void add(int index, E element) { if (this.contains(element)) { return; } else { super.add(index, element); } } }
这是我做的,它的工作原理。
假设我有一个ArrayList
与我做的第一件事是创build一个新的LinkedHashMap
。
LinkedHashSet<E> hashSet = new LinkedHashSet<E>()
然后我尝试将我的新元素添加到LinkedHashSet
。 add方法不会改变LinkedHasSet
,如果新元素是重复的,则返回false。 所以这成为一个条件,我可以在添加到ArrayList
之前testing。
if (hashSet.add(E)) arrayList.add(E);
这是一个简单而优雅的方法来防止将重复项添加到数组列表中。 如果你想要的话,你可以把它封装进来,并且在扩展ArrayList
的类中覆盖add方法。 只要记住通过遍历元素并调用add方法来处理addAll
。
你应该认真考虑dhiller的答案:
- 不用担心将对象添加到不重复的列表中,而是将它们添加到Set(任何实现)中,这将自然地过滤掉重复项。
- 当你需要调用需要一个List的方法时,把它包装在一个
new ArrayList(set)
(或者一个new LinkedList(set)
)中。
我认为你使用NoDuplicatesList
发布的解决scheme有一些问题,主要是使用contains()
方法,另外你的类不处理传递给你的addAll()
方法的集合中的重复项。
为什么不用一个列表封装一个集合,sorting如下:
new ArrayList( new HashSet() )
这使得另一个实现的人是一个真正的集合的主人;-)
我需要类似的东西,所以我去公用集合,并使用SetUniqueList,但是当我跑了一些性能testing,我发现它似乎没有优化比较,如果我想要使用一个集和获得一个数组使用Set.toArray()方法,SetUniqueTest花了20:1的时间来填充,然后遍历100,000个string比较另一个实现,这是一个很大的差异,所以如果你担心性能,我build议你使用Set和得到一个数组,而不是使用SetUniqueList,除非你真的需要SetUniqueList的逻辑,那么你需要检查其他解决scheme…
testing代码主要方法:
public static void main(String [] args){
SetUniqueList pq = SetUniqueList.decorate(new ArrayList()); Set s = new TreeSet(); long t1 = 0L; long t2 = 0L; String t; t1 = System.nanoTime(); for (int i = 0; i < 200000; i++) { pq.add("a" + Math.random()); } while (!pq.isEmpty()) { t = (String) pq.remove(0); } t1 = System.nanoTime() - t1; t2 = System.nanoTime(); for (int i = 0; i < 200000; i++) { s.add("a" + Math.random()); } s.clear(); String[] d = (String[]) s.toArray(new String[0]); s.clear(); for (int i = 0; i < d.length; i++) { t = d[i]; } t2 = System.nanoTime() - t2; System.out.println((double)t1/1000/1000/1000); //seconds System.out.println((double)t2/1000/1000/1000); //seconds System.out.println(((double) t1) / t2); //comparing results
}
问候穆罕默德Sleem http://abusleem.net/blog
注意:它不考虑subList实现。
import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; public class UniqueList<T> extends ArrayList<T> { private static final long serialVersionUID = 1L; /** Unique elements SET */ private final Set<T> set=new HashSet(); /** Used by addAll methods */ private Collection<T> addUnique(Collection<? extends T> col) { Collection<T> unique=new ArrayList(); for(T e: col){ if (set.add(e)) unique.add(e); } return unique; } @Override public boolean add(T e) { return set.add(e) ? super.add(e) : false; } @Override public boolean addAll(Collection<? extends T> col) { return super.addAll(addUnique(col)); } @Override public void add(int index, T e) { if (set.add(e)) super.add(index, e); } @Override public boolean addAll(int index, Collection<? extends T> col) { return super.addAll(index, addUnique(col)); } }
在add
方法中,为什么不使用HashSet.add()
来检查重复项而不是HashSet.consist()
。 HashSet.add()
将返回true
,否则返回false
。
在我的头顶,列表允许重复。 在调用inheritance的方法之前,可以快速实现UniqueArrayList
并覆盖所有的add
/ insert
函数以检查contains()
。 对于个人使用,您只能实现您使用的add
方法,并重写其他方法来抛出exception,以防将来的程序员尝试以不同的方式使用列表。
收集界面的文档说:
设置 – 不能包含重复元素的集合。
列表 – 一个有序的集合(有时称为序列)。 列表可以包含重复的元素。
所以,如果你不想重复,你可能不应该使用一个列表。
我只是在我自己的小型库中创build了自己的UniqueList,如下所示:
package com.bprog.collections;//my own little set of useful utilities and classes import java.util.HashSet; import java.util.ArrayList; import java.util.List; /** * * @author Jonathan */ public class UniqueList { private HashSet masterSet = new HashSet(); private ArrayList growableUniques; private Object[] returnable; public UniqueList() { growableUniques = new ArrayList(); } public UniqueList(int size) { growableUniques = new ArrayList(size); } public void add(Object thing) { if (!masterSet.contains(thing)) { masterSet.add(thing); growableUniques.add(thing); } } /** * Casts to an ArrayList of unique values * @return */ public List getList(){ return growableUniques; } public Object get(int index) { return growableUniques.get(index); } public Object[] toObjectArray() { int size = growableUniques.size(); returnable = new Object[size]; for (int i = 0; i < size; i++) { returnable[i] = growableUniques.get(i); } return returnable; } }
我有一个TestCollections类,如下所示:
package com.bprog.collections; import com.bprog.out.Out; /** * * @author Jonathan */ public class TestCollections { public static void main(String[] args){ UniqueList ul = new UniqueList(); ul.add("Test"); ul.add("Test"); ul.add("Not a copy"); ul.add("Test"); //should only contain two things Object[] content = ul.toObjectArray(); Out.pl("Array Content",content); } }
工作正常。 它所做的就是添加到一个集合,如果它没有它已经有一个可返回的Arraylist,以及一个对象数组。