How would you go about maintaining an order of collection business objects
<BO1, BO2, BO3, BO4>
so that when you remove BO2, amd BO4 you get
<BO1, BO3>
and then when you add BO2
<BO1, BO2, BO3>
You have several ways of doing that but it depends of the type of collection you want to use. Obviously, you don't want to maintain the order of insertions but an order based on the type of elements in the list.
So, before saying use this or that, ask yourself the following question:
Can my collection hold duplicate elements?
1) If YES: then you could use an implementation of a List object (ArrayList, LinkedList, etc). But you will need to sort the list after each insertion:
List<MyObj> list = ...
list.add(myObjInstance);
Collections.sort(list);
To avoid having to sort the list on each insertion you could use the TreeList implementation from Apache Commons Collections.
2) If the answer to the previous question is NO. Then use a TreeSet, you won't need sort the collection on each insertion with that implementation.
Be aware that your object elements have to implement the Comparable interface in order to be sortable.
Unless you use a sorted order, I don't see how the collection is supposed to know that BO2 should go in the middle.
This will do what you want if your Business object implement Comparable
SortedSet<BusObj> bos = new TreeSet<>();
bos.addAll(Arrays.asList(bo1, bo2, bo3, bo4));
bos.removeAll(Arrays.asList(bo2, bo4));
bos.add(bo2);
Make your business object Comparable and use a sorted collection (like TreeSet which is a SortedSet).
Use a SortedSet
http://docs.oracle.com/javase/7/docs/api/java/util/SortedSet.html
There are 2 options: use a List and do the sorting yourself by inserting at the proper location or use a sorted collection.
The sorted collection I think you want is SortedSet http://docs.oracle.com/javase/6/docs/api/java/util/SortedSet.html.
The SortedSet requires entries to implement the Comparable interface.
There is also another question that you should look at: Sorted collection in Java
Aswering my question:
I guess also PriorityQueue would be a solution, if one were not interested in the random access.
Related
Set<Student> ts = new TreeSet<Student>();
for(Student s : studentInfo){
ts.add(s);
}
System.out.println(ts);
I've written this above snippet in one of my case block in order to sort a collection of Student Objects.
My question is: What is the difference between using this approach and using Collections.sort(); method.
The difference is that a TreeSet keeps you data sorted at all times while the Collections.sort() method sorts it when you call the method on your Set.
The time complexity of Collections.sort() is O(n*log(n)) while the TreeSet's add()'s complexity is log(n). If you use the same size of data then the complexity in the TreeSet's case will be the same because you repeat the add operation n times.
So you only have to decide whether you want your Set ordered at all times or just at some point. If there is a case in your code when you don't need sorting then you don't need TreeSet but if you will always need it to be sorted then you should use TreeSet.
Please keep in mind that if you want to sort your Set you have to create a List from it first which might introduce some overhead!
Another caveat: As others mentioned TreeSet can only take 1 Comparator while you can supply different Comparators to Collections.sort(). So it depends on your usage. You should give us more information on your use case in order to give you a thorough answer.
1) A TreeSet like all Set refuses duplicate values.
2) A TreeSet maintains the sort every time you insert elements while a list sorted with Collections.sort() will only be sorted after the call to sort() (and will not maintain this sort upon add()).
3) Collections.sort() allows to sort the list on differents criterias using different Comparators. With a TreeSet, you can also give a Comparator but you will need to instantiate one TreeSet for each Comparator.
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.
I've got Treasure objects in a TreasureCollectionDB class.
The TreasureCollectionDB class has a Map<Long, Treasure> (long being an id generated by the TreasureCollectionDB) called treasures
and a second data collection/list (available treasures).
The thing I need the other Collection or List to do is hold Treasures which I will add/remove through JSP pages. The Treasures in this list should be unique, but sorted alphabetically (if there's no data holder that does this by it self, I will write a sort method).
Anyone know what data holder I should use? Answers on the internet are confusing me as to which is most suitable.
You may use TreeSet, that should give you the desired results.
Set doesn't allow duplicates and Tree maintains sorted order.
The Treasures may implement Comparable interface so that you can sort on the desired field(s).
You would need to create equals and hash code methods and also write a comparator. That comparator you may pass to a TreeSet and use SortedSet interface.
I have a collection of a big number of objects that are defined by name/value pairs.
I need to have fast access to any of their values and to be able to return them ordered alphabetically by name. First I thought I might use a HashMap to get fast access. But it gave me no ordering. I decided to switch to LinkedHashSet.
The problem with it is that I need to be able to insert new Objects in the right places of the list, but LinkedHashSet doesn't allow that. I also need to be able to access Objects by their index as well as by name.
Will be thankful for any ideas.
Why not try TreeSet. Does your list not allow duplicates? If so then the Set should be ok. As you are adding strings and this implements Comparator the set will be automatically sorted for you
If you had
Set<String> s = new TreeSet<String>();
s.add("B");
s.add("C");
s.add("A");
then the contents of the set would be A, B, C
You can use TreeMap
A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
I would use a TreeSet which is a SortedSet. You need to define your custom class as Comparable based on the name and your collection will always be sorted.
Note: sorted collections have an O(log N) access time.
Have you looked at TreeMap? It's based off of Red-Black trees which help maintain ordering, but still gives fast access.
A TreeMap should address your requirements. If your keys are not literals then use appropriate Comparator in TreeMap constructor.
I wish to
Avoid duplicated item being inserted.
When I iterate through the collection class, the returned item is same as insertion order.
May I know, what thing I should consider, to choose either ArrayList (explicitly perform contains check before insertion) or LinkedHashSet?
Thanks.
Definitely use LinkedHashSet. It is made for what you need. Searching entire ArrayList every time you need to insert something will be performance killer (O(n) every time))
Use LinkedHashSet if you don't want duplicate items inserted.
A LinkedHashSet seems to fit the bill perfectly.
When you build your own objects, and plan to use them in a Collection like LinkedHashSet here. Don't forget to override both equals and hashcode for the item you are going to store in it.
Please check this out:
http://wiki3.cosc.canterbury.ac.nz/images/e/e9/JavaCollections.png
LinkedHashSet is what you need, because it's an implementation of the Set interface. Set has one very cool habit: it doesn't allows duplicates by default. So, we are done with your 1.
What about 2?
We know, that we need one of the Set implementation, but which ?
HashMap - you are able to store K,V pairs, but there is no order.
TreeSet - this is the slowest solution, because it's using a compareTo method to keep every item sorted and ordered. This is why you can pass a comparator to it, when you are constructing a TreeSet.
LinkedHashSet - Gives back the elements in order of INSERTING them. It is the ordered version of a HashSet.
Please find a cool description here:
http://java67.blogspot.co.uk/2014/01/when-to-use-linkedhashset-vs-treeset-vs-hashset-java.html?_sm_au_=iVVMtMLHSDQ5P0P7