那里有没有重复的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的答案:

  1. 不用担心将对象添加到不重复的列表中,而是将它们添加到Set(任何实现)中,这将自然地过滤掉重复项。
  2. 当你需要调用需要一个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,以及一个对象数组。