Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which data structure to use for keeping a list unique with insertion order intact

I need to add objects to a list (with List semantics) while keeping all objects in the list unique. I figured LinkedHashSet would do, but the "re-insert" clause breaks this:

LinkedHashSet<String>list = new LinkedHashSet<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
list.add("a");
System.out.println (list);

Output from the above is: [a, b, c], not [b, c, a] as I would like it.

Is there any such data-structure in Java which handles this case?

like image 965
Martin Wickman Avatar asked Jan 23 '13 09:01

Martin Wickman


People also ask

How do you preserve the insertion order in a list?

If we want to maintain the insertion order of the elements, we are supposed to use LinkedHashSet. LinkedHashSet maintains the order in which the elements are inserted.

Which implementation of a set data type also maintains the order of its elements?

TreeSet is one of the most important implementations of the SortedSet interface in Java that uses a Tree for storage. The ordering of the elements is maintained by a set using their natural ordering whether or not an explicit comparator is provided.

In which data structure elements are processed in order of their insertion?

A stack is an ordered list in which all insertions and deletions are made at one end, called the top. A queue is an ordered list in which all insertions take place at one end, the rear, while all deletions take place at the other end, the front.

Does array maintain insertion order in Java?

Both ArrayList and LinkedList are implementation of List interface. They both maintain the elements insertion order which means while displaying ArrayList and LinkedList elements the result set would be having the same order in which the elements got inserted into the List.


3 Answers

try

    Set<String> set = Collections.newSetFromMap(new LinkedHashMap<String, Boolean>(16, 0.75f, true));
    set.add("a");
    set.add("b");
    set.add("c");
    set.add("a");
    set.add("a");
    System.out.println(set);

output

[b, c, a]
like image 184
Evgeniy Dorofeev Avatar answered Oct 05 '22 04:10

Evgeniy Dorofeev


I don't think there is an out of the box data structure that does what you want as it seems a little odd. I would suggest you create a wrapper around LinkedHashSet that pops the element when you try to re-inserts it and than inserts it again.

like image 39
Ivaylo Strandjev Avatar answered Oct 05 '22 03:10

Ivaylo Strandjev


Actually there is an out of the box data structure provided by the JDK libraries. If you look at this LinkedHashMap constructor:

/**
 * Constructs an empty <tt>LinkedHashMap</tt> instance with the
 * specified initial capacity, load factor and ordering mode.
 *
 * @param  initialCapacity the initial capacity
 * @param  loadFactor      the load factor
 * @param  accessOrder     the ordering mode - <tt>true</tt> for
 *         access-order, <tt>false</tt> for insertion-order
 * @throws IllegalArgumentException if the initial capacity is negative
 *         or the load factor is nonpositive
 */
public LinkedHashMap(int initialCapacity,
                     float loadFactor,
                     boolean accessOrder) {
    super(initialCapacity, loadFactor);
    this.accessOrder = accessOrder;
}

there is an extra parameter accessOrder. Based on this, a newly added object will be moved to the end of the list (accessOrder - true) or remain at the old location (accessOrder - false).

In order to create a Set with these characteristics, you would need to use this factory method from java.util.Collections: newSetFromMap(LinkedHashMap(initialCapacity, loadFactor, accessOrder))

Keep in mind that the accessOrder property is responsible for all interactions with given element - if you'd call get on HashMap it will do reordering as well (that shouldn't affect you anyway because the Set interface does not expose a get method on a wrapped HashMap, just saying).

like image 40
Petro Semeniuk Avatar answered Oct 05 '22 04:10

Petro Semeniuk