I have some of values in my java program. I just stored those values in HashSet. I have stored it by for loop. The values iterating by loop has been ordered differently after the set formed. How can restrict this order change of HashSet as I get from the loop. Can anyone help me please?
If you want the set to maintain the insertion order, you can use a LinkedHashSet:
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).
Alternatively, if you want your set to be ordered, you can use a TreeSet.
A HashSet is unordered, as the javadocs specify:
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.
You might want to consider using a LinkedHashSet, which maintains the order of insertions.
An alternative is using one of the NavigableSet implementations, such as the TreeSet which guarantee order according to the natural order or Comparator, if given.
use LinkedHashSet predictable iteration order
Related
Please explain how different collection are used under different scenario.
By this I mean to say how can I differentiate when to use a List, a Set or a Map interface.
Please provide some links to examples that can provide a clear explanation.
Also
if insertion order is preserved then we should go for List.
if insertion order is not preserved then we should go for Set.
What does "insertion order is preserved" means?
Insertion order
Insertion order is preserving the order in which you have inserted the data.
For example you have inserted data {1,2,3,4,5}
Set returns something like {2,3,1,4,5}
while list returns {1,2,3,4,5} .//It preserves the order of insertion
When to use List, Set and Map in Java
1) If you need to access elements frequently by using index, then List is a way to go. Its implementation e.g. ArrayList provides faster access if you know index.
2) If you want to store elements and want them to maintain an order on which they are inserted into collection then go for List again, as List is an ordered collection and maintain insertion order.
3) If you want to create collection of unique elements and don't want any duplicate then choose any Set implementation e.g. HashSet, LinkedHashSet or TreeSet. All Set implementation follow there general contract e.g. uniqueness but also add addition feature e.g. TreeSet is a SortedSet and elements stored on TreeSet can be sorted by using Comparator or Comparable in Java. LinkedHashSet also maintains insertion order.
4) If you store data in form of key and value then Map is the way to go. You can choose from Hashtable, HashMap, TreeMap based upon your subsequent need.
You will find some more useful info at http://java67.blogspot.com/2013/01/difference-between-set-list-and-map-in-java.html
I've sorted an arraylist of int in ascending order, but when I copy it in a set, the elements are not sorted anymore.
I'm using this :
HashSet<Integer> set = new HashSet<Integer>(sortedArray);
why is like that?
LinkedHashSet will keep the order. TreeSet will sort based either on an external Comparator or natural ordering through Comparable.
A general point of a Set is that order is irrelevant. Hashing is intended to put the elements in as random an order as possible. LinkedHashSet maintains a linked-list between references to the elements, so can maintain an order.
BitSet (which is not a Set) may, or may not, provide a more efficient data structure.
HashSet's don't sort or maintain order, and the API will tell you this:
it does not guarantee that the order will remain constant over time.
Consider using another type of Set such as a TreeSet.
If you just care about uniqueness, use the HashSet. If you're after sorting, then consider the TreeSet.
you need to use TreeSet and implement a Comparator object or Comparable interface for your data. you can read about Object ordering here
hash set is designed for quick access to unique data, not for maintaining a particular order.
Does such a thing exist anywhere? Basically I see java has LinkedHashSet but no type of navigatable hash set?
By its very nature, a hash-based data structure is not ordered. You can write wrappers which supplement it with an additional data structure (this is more or less what LinkedHashMap does). But while it makes some sense to keep a hash set and a list, in order to keep a good ordering, you would need a tree or similar data structure. But the tree can work as a set by itself, so you would essentially be duplicating the information (more than in the case of set plus list, which differ more than two different set implemnentations). So the best solution is to just use TreeSet or another SortedSet if you need order.
It's not a HashSet, but as a descendant of Set you have the TreeSet
This class implements the Set interface, backed by a TreeMap instance. This class guarantees that the sorted set will be in ascending element order
You can traverse the elements using the iterator
public Iterator iterator()
Returns an iterator over the elements in this set. The elements are returned in ascending order
You can use a TreeSet but all the operations in it are lg(n)
You can use a LinkedHashSet, which keeps a linked list on top of hashset, but it only maintains insertion ordering (first inserted will be first element in iterator), you cannot have natural or custom ordering
You could also use TreeSet+HashSet approach but two reference for each element will be kept and while add and remove would still be lg(n) the contains will become expected o(n)
choose wisely :)
I guess there's TreeMap which is...related but definitely not the same :)
In Java 5, If i have a Set, and i add two objects to the Set. When I retrieve the objects, will it give me back in the same order as I added?
I am not able to find the answer to this. Does it depend on which Set implementation I use?
Yes, it depends on which implementation you use. For example, LinkedHashSet will preserve insertion order:
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.)
... but HashSet won't:
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.
Straight from the documentation:
The elements are returned in no particular order (unless this set is
an instance of some class that provides a guarantee).
Depends on Set implementation. LinkedHashSet does exactly that.
Yes it does depend on the implementation you choose. HashSet will not guarantee order but LinedHashSet will.
JavaDocs is your best friend. It's implementation specific. For example:
java.util.Set:
Iterator<E> iterator();
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).
and
java.util.TreeSet:
public Iterator<E> iterator();
Returns an iterator over the elements in this set in ascending order.
The Set interface itself is for unordered container implementations. But there might be implementations of Set that do return the elements in a particular order.
Also see the documentation of Set.iterator:
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)
I would like a map that preserves the order of the elements if there is such a thing.
I am aware that it would not perform near as well as a HashMap, but I only plan to use it for small/temporary programs.
There's no ArrayMap. :)
But a LinkedHashMap will preserve the insertion order, and a TreeMap will order based on the keys' natural ordering.
If you mean a defined ordering of the items you can use a TreeMap (doc here).. otherwise if you are talking about insertion order you can use a LinkedHashMap (doc).
You should check the fastutil project, a memory and time efficient Java Collection framework.
It provides an array map implementation, such as Int2IntArrayMap
Give it a try! I don't use anymore the standard library, fastutils really make the difference.
Hope it helps
There is an ArrayMap in the Android support libraries. There are some non-JDK components, but it shouldn't be that difficult to port.
Source
Have a look at LinkedHashSet and -Map.
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.
This implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet, without incurring the increased cost associated with TreeSet. It can be used to produce a copy of a set that has the same order as the original, regardless of the original set's implementation.
Or how about a ListOrderedMap that retains order of the elements. ListOrderedMap Api