代码之家  ›  专栏  ›  技术社区  ›  Yuval

是否存在无重复列表的实现?

  •  77
  • Yuval  · 技术社区  · 16 年前

    我知道 SortedSet ,但就我而言,我需要一些能够实现 List Set . 那么,在API或其他地方是否有实现?

    实现我自己应该不难,但我想为什么不先问问这里的人呢?

    11 回复  |  直到 7 年前
        1
  •  97
  •   naXa stands with Ukraine    7 年前

    标准库中没有Java集合可以执行此操作。 LinkedHashSet<E> 保持排序类似于 List ,不过,如果你用 列表 当你想把它作为一个 列表

    或者 Commons Collections (或 commons-collections4 列表 这正是您想要的: SetUniqueList / SetUniqueList<E> .

        2
  •  15
  •   JasonMArcher TWE    10 年前

    假设我有一个 ArrayList 我做的第一件事就是创建一个新的 LinkedHashMap .

    LinkedHashSet<E> hashSet = new LinkedHashSet<E>()
    

    然后我尝试将新元素添加到 LinkedHashSet LinkedHasSet 如果新元素是重复的,则返回false。因此,在添加到 ArrayList

    if (hashSet.add(E)) arrayList.add(E);
    

    这是一种简单而优雅的方法,可以防止将重复项添加到数组列表中。如果需要,可以将其封装在扩展 . 记住要处理好 addAll

        3
  •  11
  •   Yuval    13 年前

    这就是我最终所做的。我希望这对其他人有帮助。

    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);
            }
        }
    }   
    
        4
  •  6
  •   Daniel Hiller    7 年前

    为什么不用列表封装一个集合,排序如下:

    new ArrayList( new LinkedHashSet() )
    

        5
  •  4
  •   matt b    16 年前

    你应该认真考虑迪勒的回答:

    1. 当需要调用需要列表的方法时,请将其包装在 new ArrayList(set) (或 new LinkedList(set) ,随便了)。

    我认为你发布的解决方案 NoDuplicatesList contains() 方法,并且您的类不处理传递给您的 addAll() 方法

        6
  •  3
  •   Grandtour p27    4 年前

    公地收藏 SetUniqueList ,但当我运行一些性能测试时,我发现与使用 Set 并获得 Array 使用 Set.toArray() 方法

    SetUniqueTest 填充然后穿过 100000串 与其他实现相比,这是一个很大的区别。

    因此,如果您担心性能,我建议您使用 设置并获取一个数组 而不是使用 集合唯一列表 ,除非你真的需要 集合唯一列表

    测试代码主方法 :

    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
    

    当做 Mohammed Sleem

        7
  •  1
  •   marcolopes    8 年前

    注意:不需要任何时间 子列表 考虑到执行情况。

    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));
        }
    
    }
    
        8
  •  0
  •   naXa stands with Ukraine    7 年前

    documentation for collection interfaces 说:

    设置不能包含重复元素的集合。
    列出有序集合(有时称为序列)。列表可以包含重复的元素。

    因此,如果您不想要重复的,您可能不应该使用列表。

        9
  •  -1
  •   naXa stands with Ukraine    7 年前

    add 方法,为什么不使用 HashSet.add() HashSet.consist() . HashSet.add() 会回来的 true 如果没有副本和 false 否则

        10
  •  -1
  •   naXa stands with Ukraine    7 年前

    在我脑海中,列表允许重复。您可以快速实现 UniqueArrayList 并覆盖所有 add / insert 要检查的函数 contains() 在调用继承的方法之前。对于个人使用,您只能实现 添加 方法,并重写其他方法以引发异常,以防将来的程序员尝试以不同的方式使用该列表。

        11
  •  -3
  •   Jonathan    13 年前

    我只是在我自己的小图书馆里制作了我自己的单子,就像这样:

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

    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以及一个对象数组。