• Post Reply Bookmark Topic Watch Topic
  • New Topic

Sorting my HashMap  RSS feed

 
Ricardo Jost
Greenhorn
Posts: 7
1
Android Chrome Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is up guys, so i have a HashMap of Products, and i want to sort my HashMap by the score(double) that this Products have, productID is used for the keys, i want to have sorted by the higher scores, how should i proceed with that? By the solutions i searched, the problem is that i can't sort by the type Product

This is one of the sollutions that i've found on web

 
Piet Souris
Master Rancher
Posts: 2041
75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Ricardo,

unfortunately, you cannot have a TreeMap that is sorted by the values. It must always be sorted on the keys.

But is a sorted List also good? For instance:
 
Ricardo Jost
Greenhorn
Posts: 7
1
Android Chrome Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:hi Ricardo,

unfortunately, you cannot have a TreeMap that is sorted by the values. It must always be sorted on the keys.

But is a sorted List also good? For instance:


So, yes, i think a separate list would do it, should i pass the HashMap to a List and sort the List?
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 66304
152
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You keep saying HashMap but your code uses a TreeMap. Which is it?
 
Piet Souris
Master Rancher
Posts: 2041
75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ricardo Jost wrote:So, yes, i think a separate list would do it, should i pass the HashMap to a List and sort the List?

You could do:

but I'm not sure if that is what you meant.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ricardo Jost wrote:What is up guys, so i have a HashMap of Products, and i want to sort my HashMap by the score(double) that this Products have, productID is used for the keys,
...
i want to have sorted by the higher scores, how should i proceed with that? By the solutions i searched, the problem is that i can't sort by the type Product

The thing that puzzles me is that although you talk about "products", I don't see a Product class anywhere. It would appear that you're trying to extract specific bits of information and sort (or order) those correctly, rather than dealing with this a a function of a collection of products.

In other words, you're treating this as an algorithm (or procedure), rather than an "objective" function.

Since your "ID" is a String, I would assume that your HashMap is something like:
  HashMap<String, Product>

however, if "ID" is the "natural" way of distinguishing a Product - ie, product1 equals() product2 if, and only if, their IDs are equal - then your HashMap could easily be a HashSet<Product> - or possibly even better: a LinkedHashSet<Product>.

And if it implements Comparable on the same basis, it could even be a TreeSet<Product> - although I'm not sure if that buys you anything.

However, you now want an new order for your Products - score - and I presume there's no guarantee that scores can't be duplicated.

So you need a collection that can hold "duplicates" - and Java provides only two: Collection and List. And since both of them are unordered, you'll need to sort them.

Now, you can do that Piet's nifty, version 8 way, or you can do it the old-fashioned way:
1. Create a Comparator<Product> (let's call it 'scoreOrder') that orders pairs of Products by their score.
2. Create a List<Product> of all the products in your Map, viz:
  List<Product> products = new ArrayList<>( productMap.values() );
3. Sort it:
  Collections.sort(products, scoreOrder);

You takes your money and you takes your choice - but my advice: Keep in mind that you are dealing with Products; not "bits of a product".

HIH

Winston
 
Piet Souris
Master Rancher
Posts: 2041
75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Winston,

indeed, this 'Product" thing is unclear to me as well, but I handled the situation of sorting a HashMap based on the values in it.
OP tried to do that with a TreeMap and a suitable Comparator, but that didn't work.

I have a generic version for this sort, with the two types either implementing Comparable or when supplied with a Comparator,
but that is not so easy to read. I therefore gave a simple example using Strings and Doubles, but I hope it is clear enough to apply
it to other types.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:indeed, this 'Product" thing is unclear to me as well, but I handled the situation of sorting a HashMap based on the values in it.

And I have absolutely no problem with it, except that it requires version 8 (which, I have to admit, I'm not on yet - although I know I should be ).

Winston
 
Ricardo Jost
Greenhorn
Posts: 7
1
Android Chrome Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just for the update, it was way easyer to just put the values into a ArrayList and sort from there, the problem is now solved thanks brothers!
 
Stephan van Hulst
Saloon Keeper
Posts: 7964
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for getting back to us Ricardo, it's good you managed to sort it out (heh heh heh).

Piet, if you're going to use Java 8 for that piece of code, I would prefer to write it like this:

Usually though, when I want my entries in some specific order while retaining constant lookup time, I just keep a List or Set of keys side by side with my Map:
 
Piet Souris
Master Rancher
Posts: 2041
75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:(...)
Piet, if you're going to use Java 8 for that piece of code, I would prefer to write it like this:

Yes, this is what I had first, but then I found my way much easier to write and to uderstand. It keeps the code within the stream much shorter. (Apart from that, I still prefer the e -> f(e) notation, instead of the ::.)

But beside a personal preference, is there also some compelling reason for your preference?
Stephan van Hulst wrote:
Usually though, when I want my entries in some specific order while retaining constant lookup time, I just keep a List or Set of keys side by side with my [tt]Map

Yes, that is handy. It is kind of like adding indexes (indices?) to a database. But is that worth the effort, since a key comparator is usually so easy to write?
 
Stephan van Hulst
Saloon Keeper
Posts: 7964
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:Yes, this is what I had first, but then I found my way much easier to write and to uderstand. It keeps the code within the stream much shorter. (Apart from that, I still prefer the e -> f(e) notation, instead of the ::.)
But beside a personal preference, is there also some compelling reason for your preference?

Not really. I personally find it's quicker to understand what a piece of code is supposed to do when it's written with method handles rather than lambdas, because the code resembles spoken language a lot more. It's also good practice in functional languages, and I think it's good to adopt functional language conventions when using Java streams.

Of course, it's fine to stick with personal preference, as long as your team doesn't have a style guideline for this. I imagine people will prefer using method handles as they become more accustomed to them.

Yes, that is handy. It is kind of like adding indexes (indices?) to a database. But is that worth the effort, since a key comparator is usually so easy to write?

Can you elaborate? I don't see what the ease of writing comparators has to do with whether or not having constant time lookups is appropriate.
 
Piet Souris
Master Rancher
Posts: 2041
75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Getting your map in a given order is so easy that that job can be done whenever you need it. Creating a dedicated class for that purpose seems overkill.

But maybe I am misunderstanding you completely. Can you elaborate? Have you used this often?
 
Stephan van Hulst
Saloon Keeper
Posts: 7964
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, I'm not talking about a dedicated class. In my example, Stuff is just the class that is using the Map. It starts out having a HashMap because it needs to perform lookups somewhere inside of it. Then later I add a List or a Set of keys if I find that it need to iterate over entries in some special order.

When I need to pass an ordered mapping to a method, or need to return one from it, I just plug my map into a new TreeMap. When the order is determined by the values though, having a list of map entries is probably best though.

If this is a common occurrence within the application, I don't think a dedicated class is overkill. It can be generic enough to be reused in multiple applications.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!