I am getting the unique elements from a arraylist into a hashset but it is being sorted by itself.But i need the data not to be in sorted order.How can it be done?
HashSet getting sorted
The items of a HashSet is not in a particular order at all, as explicitly stated in its javadoc:
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.
Perhaps you meant to say that the items are "rearranged" in a different order than you have added the items and that this is undesireable.
In that case, just use LinkedHashSet instead of HashSet. It maintains the elements in insertion order.
Set<T> unique = new LinkedHashSet<T>(arrayList);
Or, perhaps, if you prefer automatic ordering based on the element's Comparable#compareTo() implementation or would like to supply a custom Comparator, then use a TreeSet instead.
Set<T> uniqueAndSorted = new TreeSet<T>(arrayList);
See also:
The Java Tutorials - Collecitons - Implementations
What do yo mean by 'I want data not in sorted order'? Do you mean to say that you want the same order in which it is present in the list?
If so, you can create a LinkedHashSet and add the entries from the arraylist.
eg:
ArrayList list = new ArrayList();
LinkedHashSet set = new LinkedHashSet();
for (String temp : list) {
set.add(temp);
}
This will ensure the same order in which the elements are present in the arraylist.
Related
If we want to represent a group of individual objects where duplicates are allowed and insertion order is preserved, then we should go for List.
Here, what does insertion order refers to?
Insertion order refers to the order in which you are adding elements to the data structure (i.e., a collection like List, Set, Map, etc..).
For example, a List object maintains the order in which you are adding elements, whereas a Set object doesn't maintain the order of the elements in which they are inserted.
First, take a List object and add elements:
List<String> list = new ArrayList<>();
list.add("1Z");
list.add("2Y");
list.add("3X");
System.out.println(list);
Output (i.e., objects inside List): [1Z, 2Y, 3X] (order same as the insertion)
Now, take a Set object:
Set<String> set = new HashSet<>();
set.add("1Z");
set.add("2Y");
set.add("3X");
System.out.println(set);
Output (i.e., objects inside Set): [3X, 2Y, 1Z] (order disturbed)
The insertion order is the order used to add the elements in the collection.
Iteration order for above implementations:
HashSet - undefined.
HashMap - undefined
LinkedHashSet - insertion order
LinkedHashMap - insertion order of keys (by default), or
'access order'
ArrayList - insertion order.
LinkedList - insertion order.
TreeSet - ascending order, according to Comparable /
Comparator.
There are collection the could preserve the insertion order when you add an element, others cannot. Please refer at this link
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.
I have data of which the sequence is as important as its unique elements. Meaning if something has already been added it should not be added again and the sequence must be remembered.
Set does not remember the sequence in which it was added (either hash or sort), and List is not unique.
What is the best solution to this problem?
Should one have a list and loop through it to test for uniqueness - which I'm trying to avoid?
Or should one have two collections, one a List and one a Set - which I'm also trying to avoid?
Or is there a different solution to this problem altogether.
In the bellow code was your reference
LinkedHashSet<String> al=new LinkedHashSet<String>();
al.add("guru");
al.add("karthik");
al.add("raja");
al.add("karthik");
Iterator<String> itr=al.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
output
guru
karthik
raja
Use LinkedHashSet. It serves as both a List and a Set. It has the uniqueness quality of a set but still remembers the order in which you inserted items to it which allows you to iterate it by order of insertion.
From the Docs:
Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set. (An element e is reinserted into a set s if s.add(e) is invoked when s.contains(e) would return true immediately prior to the invocation.)
You can use SortedSet
or LinkedHashSet
LinkedHashSet is the best possible way out
When I start to add value into Set<Integer> I get sorting elements.
Please refer to this example:
Set<Integer> generated = new HashSet<Integer>();
generated.add(2);
generated.add(1);
generated.add(0);
Here I get sorting Set [0, 1, 2]. I would like to get value as I add to generated object.
A HashSet does not have a predictable order for elements. Use a LinkedHashSet to preserve insertion order of elements in a set:
Hash table and linked list implementation of the Set interface, with predictable iteration order.
Set<Integer> generated = new LinkedHashSet<Integer>();
generated.add(2);
generated.add(1);
generated.add(0);
Firstly it's just a co-incidence that you get sorted value first time. If you run that code multiple time, you'll see the output in some random order. That's because a HashSet doesn't enforce any ordering on elements you add.
Now to get the elements in the order you inserted, you can use LinkedHashSet, that maintains the insertion order.
The HashSet does not guarantee the order of the elements. From the JavaDoc:
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.
So, in order to keep guarantee the order a LinkedHashSet can be used. From the JavaDoc:
Hash table and linked list implementation of the Set interface, with predictable iteration order.
This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order).
Simply instantiate your Set like this:
Set<Integer> generated = new LinkedHashSet<>();
First, regarding the title of your question, Set<Integer> is only the declaration type and its not responsible of any sorting / unsorting behavior, the main reason for using the Set interface is when caring about uniqueness — it doesn't allow duplicates, additional informations from Javadocs:
A Set is a Collection that cannot contain duplicate elements.
Second, it's pure concidence that you got sorted set, use HashSet when you don't care about order when iterating through it, more infos from javadocs:
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. This class permits the null element.
Third, regarding what you are looking for:
I would like to get value as I add to generated object.
then you need to use LinkedHashSet which takes care of the order in which elements were inserted, again from javadocs:
This linked list defines the iteration ordering, which is the order in
which elements were inserted into the set (insertion-order). Note that
insertion order is not affected if an element is re-inserted into the
set
you may use it simply like this:
Set<Integer> generated = new LinkedHashSet<Integer>();
Fourth and Last, as additional information, another important collection that you need to be aware of it, is the TreeSetwhich guarantees that the elements will be sorted in ascending order, according to natural order, javadocs:
The elements are ordered using their natural ordering, or by a
Comparator provided at set creation time, depending on which
constructor is used
I have a Set<String> set that I persist with Neo4j Spring in java. To be able to retrieve elements from that set in the order that elements were added to it. Sets do not retain order. I have tried using a Collection<String>/List<String> instead because Listss have ordering, but Neo4j doesn't like Collection. What else can be used for ordered storage?
EDIT: By order, I mean insertion order.
There is a special implementation of Set, the class TreeSet keeps the elements in the set sorted, either by their natural ordering or by asking a Comparator how they should be ordered. TreeSets reorders the set whenever you add/remove elements.
There is also the LinkedHashSet implementation which keeps the items according to the insertion order.
Collection is an interface that the interfaces Set and List both extend. (And other interfaces as well)
Collection does not guarantee ordering. All they care about is the possibility to add and remove elements. Set does not allow more than one copy of each element to be added. The Set interface itself does not guarantee ordering. The List interface guarantee ordering but also allows multiple copies of the same element.
Summary: For your case, use LinkedHashSet.
List is an ordered collection (also known as a sequence). The user of this interface has precise control over where in the list each element is inserted. The user can access elements by their integer index (position in the list), and search for elements in the list.
List<String> list new ArrayList<String>();
Is there any way to know what was the last new entries that were added to a hashset ? In my program the first cycle adds [Emmy, Carl] and than on my second cycle it adds [Emmy, Dan, Carl] is there anyway I can just use dan and not the rest of them for cycle three ?
java.util.HashSet does not preserve order, but java.util.LinkedHashSet does. Can you use that instead? From the Javadoc:
This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set.
HashSets do not carry information about the order in which you add elements. You need to replace it with a Collection that does (e.g. ArrayList).
Hashset are backed by hash tables and there is no guarantee on the order of retrieval. The order of retrieval will not be the same as the order of insertion. So, no it's not possible to know which item was added last.
Workarounds - may be use two hashsets, compare old with new and get the new entries or have some sort of indicators to distinguish the perticular iteration it was added or use ArrayList or anything that fits in your design.
HashSet<String> oldpeople = new HashSet<String>();P
HashSet<String> newPeople;
for (Set<String> cycle : input)
{
newPeople = new HashSet<String>();
newPeople.addAll(cycle);
newPeople.removeAll(oldPeople);
oldPeople.addAll(cycle);
}
now you have the last new one always contained in newPeople.
Well if I understand your post and the comments correctly (well that's quite hard, try to be bit more precise :) ) what you actually want is: a) not add any items several times to the HashSet and b) see if the set already contains the given item when trying to add it.
a) is trivially true for every set and for b) you can just use the return value of add: If it returns false is already contained in the set.