我知道SortedSet
,但是就我而言,我需要一些实现的东西List
,而不是Set
。那么在API或其他地方是否有实现?
实施我自己应该不难,但是我想到了为什么不先问这里的人呢?
我知道SortedSet
,但是就我而言,我需要一些实现的东西List
,而不是Set
。那么在API或其他地方是否有实现?
实施我自己应该不难,但是我想到了为什么不先问这里的人呢?
Answers:
标准库中没有Java集合可以做到这一点。不过,LinkedHashSet<E>
保留顺序类似于List
,因此如果要将集合包装为时List
要使用List
您将获得所需的语义。
另外,Commons Collections(或commons-collections4
对于通用版本)也具有List
您想要的功能:SetUniqueList
/ SetUniqueList<E>
。
这是我所做的,并且有效。
假设我ArrayList
要做的第一件事是创建一个新的LinkedHashMap
。
LinkedHashSet<E> hashSet = new LinkedHashSet<E>()
然后,我尝试将新元素添加到中LinkedHashSet
。add方法不会更改,LinkedHasSet
如果新元素重复则返回false。因此,这成为我可以在添加到之前测试的条件ArrayList
。
if (hashSet.add(E)) arrayList.add(E);
这是防止重复项添加到数组列表的简单而优雅的方法。如果您愿意,可以将其封装在扩展的类中并覆盖add方法ArrayList
。只需记住addAll
通过遍历元素并调用add方法来进行处理。
所以这就是我最终所做的。我希望这可以帮助其他人。
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);
}
}
}
您应该认真考虑dhiller的答案:
new ArrayList(set)
(或a new LinkedList(set)
,无论如何)。我认为您随发布的解决方案NoDuplicatesList
存在一些问题,大部分与contains()
方法有关,再加上您的类无法处理传递给您的addAll()
方法的Collection中是否有重复项的检查。
我需要类似的东西,所以我去了commons集合并使用了SetUniqueList
,但是当我进行一些性能测试时,我发现与要使用aSet
并获得一个Array
using的情况相比,它似乎没有优化。Set.toArray()
方法。
在SetUniqueTest
花了20:1的时间填写,然后遍历100000个弦乐相对于其他实现,这是一个大问题不同。
因此,如果您担心性能,建议您使用Set and Get Array而不是使用SetUniqueList
,除非您确实需要的逻辑,否则您SetUniqueList
需要检查其他解决方案...
测试代码主要方法:
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
}
注意:它不考虑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));
}
}
我只是在自己的小库中创建了自己的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以及一个对象数组。