Is there a no-duplicate List implementation out there?

后端 未结 11 645
悲哀的现实
悲哀的现实 2020-11-29 00:53

I know about SortedSet, but in my case I need something that implements List, and not Set. So is there an implementation out there, in the API or e

相关标签:
11条回答
  • 2020-11-29 01:11

    The documentation for collection interfaces says:

    Set — a collection that cannot contain duplicate elements.
    List — an ordered collection (sometimes called a sequence). Lists can contain duplicate elements.

    So if you don't want duplicates, you probably shouldn't use a list.

    0 讨论(0)
  • 2020-11-29 01:14

    Off the top of my head, lists allow duplicates. You could quickly implement a UniqueArrayList and override all the add / insert functions to check for contains() before you call the inherited methods. For personal use, you could only implement the add method you use, and override the others to throw an exception in case future programmers try to use the list in a different manner.

    0 讨论(0)
  • 2020-11-29 01:16

    in add method, why not using HashSet.add() to check duplicates instead of HashSet.consist(). HashSet.add() will return true if no duplicate and false otherwise.

    0 讨论(0)
  • 2020-11-29 01:18

    Here is what I did and it works.

    Assuming I have an ArrayList to work with the first thing I did was created a new LinkedHashMap.

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

    Then I attempt to add my new element to the LinkedHashSet. The add method does not alter the LinkedHasSet and returns false if the new element is a duplicate. So this becomes a condition I can test before adding to the ArrayList.

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

    This is a simple and elegant way to prevent duplicates from being added to an array list. If you want you can encapsulate it in and override of the add method in a class that extends the ArrayList. Just remember to deal with addAll by looping through the elements and calling the add method.

    0 讨论(0)
  • 2020-11-29 01:21

    I needed something like that, so I went to the commons collections and used the SetUniqueList, but when I ran some performance test, I found that it seems not optimized comparing to the case if I want to use a Set and obtain an Array using the Set.toArray() method.

    The SetUniqueTest took 20:1 time to fill and then traverse 100,000 Strings comparing to the other implementation, which is a big deal difference.

    So, if you worry about the performance, I recommend you to use the Set and Get an Array instead of using the SetUniqueList, unless you really need the logic of the SetUniqueList, then you'll need to check other solutions...

    Testing code main method:

    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
    

    }

    Regards, Mohammed Sleem

    0 讨论(0)
提交回复
热议问题