Java Set Retain Order

Java Set retain order?

The Set interface does not provide any ordering guarantees.

Its sub-interface SortedSet represents a set that is sorted according to some criterion. In Java 6, there are two standard containers that implement SortedSet. They are TreeSet and ConcurrentSkipListSet.

In addition to the SortedSet interface, there is also the LinkedHashSet class. It remembers the order in which the elements were inserted into the set, and returns its elements in that order.

How to keep order in Java 9 Set.of

The immutable Sets created by Set.of make no guarantee about the iteration order of their elements. You could use a specific implementation that does, such as a LinkedHashSet:

Set<Integer> mySet = new LinkedHashSet<>(List.of(new Integer[]{1, 2, 3, 4}));

How can I preserve insertion order in a HashSet?

Stating the HashSet documentation

It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.

If you want to use a Set that remains natural order, use a SortedSet instead.

A Set that further provides a total ordering on its elements. The elements are ordered using their natural ordering, or by a Comparator typically provided at sorted set creation time.

Edit:
A Set does by definiton not say anything about the order of its elements. For exmaple, two Sets are equals if both contain the same elements and have the same size. The iteration order of a Set is dependent on the implementations and may change between versions, so you should not make any assumptions on it. It may depend on the value of #hashCode, but it may as well depend on the insertion order or something else in the future. However, we should not care, because if you do you should use a List or a SortedSet instead.

java collection to retain order and should be unique

Only LinkedHashSet guarantees predictable order

From jdoc:

Hash table and linked list implementation of the Set interface, with
predictable iteration order

Order of elements in a set in java

You will propably get the same ordering in the lists l and l1. But since most Sets are unordered, you have no guarantee that there will be the same order.

Technically you could write an implementation of the Set interface which changes its order everytime any method is called. This would still fulfil the interface.

Since in the constructor new ArrayList(Collection) the toArray method of the collection is called, we can have a look at the Javadoc of Set#toArray():

Returns an array containing all of the elements in this set. If this set makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order.

While the Javadoc of Set#iterator() says there is no general guarantee:

Returns an iterator over the elements in this set. The elements are returned in no particular order (unless this set is an instance of some class that provides a guarantee).

Given this, I would strongly advise you not to rely on the ordering of the lists.

Is there an insertion order preserving Set that also implements List?

TreeSet is sorted by element order; LinkedHashSet retains insertion order. Hopefully one of those is what you were after.

You've specified that you want to be able to insert at an arbitrary location, I suspect you'll have to write your own - just create a class containing a HashSet<T> and an ArrayList<T>; when adding an item, check whether or not it's in the set before adding it to the list.

Alternatively Apache's commons-collections4 offers ListOrderedSet and SetUniqueList, which behave similarly and should meet the given requirements.

Set String doesn't maintain order the same as the order the elements were added in

Use a LinkedHashSet if you want to order the elements of the set. For more details, see this link.

Java Stream Map List to Set and preserve Order

HashSet does not preserve the insertion order but List does. You can try with LinkedHashSet instead.

Edit:
An other alternative is to use a TreeSet. It's a set so the duplicated values are deleted. And the elements are sorted when they are inserted. The sort is made using the method compareTo (provided by the Comparable interface).
For example :

// Answer class
public class Answer {

private final User user;

public Answer(final User user) {
this.user = user;
}

public User getUser() {
return user;
}
}

// User class
public class User implements Comparable<User> {

private final int points;

public User(final int points) {
this.points = points;
}

public int getPoints() {
return points;
}

@Override
public int compareTo(User other) {
// Sort user by their points (ascending order)
return points - other.points;
}

@Override
public String toString() {
return "User{" + "points=" + points + '}';
}
}

Then in your main code :

// Main
List<Answer> answers = Arrays.asList(
new Answer(new User(0)),
new Answer(new User(20)),
new Answer(new User(1)),
new Answer(new User(20)),
new Answer(new User(10))
);

answers
.stream()
.map(Answer::getUser)
.collect(Collectors.toCollection(TreeSet::new))
.forEach(System.out::println);

Output :

User{points=0}
User{points=1}
User{points=10}
User{points=20}

What does it mean by Insertion Order is preserved in Collections ?

Insertion Order means the order in which we are inserting the data.

public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("alpha");
list.add("beta");
list.add("gamma");

for (String string : list) {
System.out.println(string);
}
}

Output :
alpha
beta
gamma

Insertion order is maintained.

If you want the original insertion order there are the LinkedXXX
classes, which maintain an additional linked list in insertion order.
Most of the time you don't care, so you use a HashXXX, or if you want a natural order, so you use TreeXXX.



Related Topics



Leave a reply



Submit