Win a copy of Production-Ready Serverless (Operational Best Practices) this week in the Cloud/Virtualization forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Junilu Lacar
  • Paul Clapham
  • Knute Snortum
Saloon Keepers:
  • Stephan van Hulst
  • Ron McLeod
  • Tim Moores
  • salvin francis
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Vijitha Kumara

sort array list of strings in descending order comparing to its equivalent in hashmap  RSS feed

 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,
I'm newbie learning java.

My need is to iterate through hashmap with languages names and display those with score 60 or above. This part works well.

Then I should sort array list of strings in descending order comparing to its equivalent in hashmap. Can't really imagine how do I solve this part. Please advise. See my current version of code below. Thanks ahead.

 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually it can be done using functional programming and stream with one string:

In your example you have Map.Entry not use generics and you make unneseccerily conversions for key and value (they already are String and Integer). Also you don't need to sort resulting list ascending to apply then reverse descending sort.
 
Marshal
Posts: 63777
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What do you want to do? Do you want to sort your List according to what the values in the Map are? I suggest you start by looking at this Java™ Tutorials section. Go through it carefully. It will tell you that you will need to create a Comparator<XYZ> to pass to the sort() method.
Does it say anything in the link I posted about Comparator#comparingInt()? That might supply what you need. If you go through the Comparator interface, you may find a method to reverse the Comparator; that would be better than using a reverse() method.
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry my mistake in the code: use Collections.reverseOrder() instead of Collections::reverseOrder for sorted()
 
Campbell Ritchie
Marshal
Posts: 63777
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tyoma Sakurakoji wrote:. . .. . .

Please check that carefully; I think you are getting a List of the values. I thought OP wanted a List of the keys.
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Input map is Map<String, Integer>, code is filter using value and map using key. I think it's correct...
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Marcello Lippi wrote: Hi all,
Then I should sort array list of strings in descending order comparing to its equivalent in hashmap


It seems I doesn't get the whole problem. Are you need to preserve the original order of the input hashmap entries and just reverse it afterwards? If so, then remove sorted call and reverse the resulting list:
 
Saloon Keeper
Posts: 5753
56
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Marcello Lippi wrote:Then I should sort array list of strings in descending order comparing to its equivalent in hashmap.


Sorry, I can't quite parse this sentence. "Equivalent" based on what? The key? The Value? It's hash order?
 
Marcello Lippi
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Carey Brown wrote:

Marcello Lippi wrote:Then I should sort array list of strings in descending order comparing to its equivalent in hashmap.


Sorry, I can't quite parse this sentence. "Equivalent" based on what? The key? The Value? It's hash order?


I meant taking keys order from hashmap and displaying it in reverse order comparing to hashmap. It is not just alphabetical reverse order, but reverse comparing to what is in hashmap.
 
Marcello Lippi
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tyoma Sakurakoji wrote:

Marcello Lippi wrote: Hi all,
Then I should sort array list of strings in descending order comparing to its equivalent in hashmap


It seems I doesn't get the whole problem. Are you need to preserve the original order of the input hashmap entries and just reverse it afterwards? If so, then remove sorted call and reverse the resulting list:



I'm getting error

How do I fix it? What should I import before declaring method?
 
Marcello Lippi
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Honestly, I would love to see solution for my initial code. Yes, it is extremely ugly, but at least I do understand it. In the same time, your solutions are brilliant, but I don't understand streams completely yet.
 
Carey Brown
Saloon Keeper
Posts: 5753
56
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Ranch Hand
Posts: 483
23
AngularJS Eclipse IDE Firefox Browser Java Spring VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tyoma Sakurakoji wrote:Are you need to preserve the original order of the input hashmap entries and just reverse it afterwards? If so, then remove sorted call and reverse the resulting list


Their is no such thing like order for HashMap as it is a unordered data structure, even HashSet is unordered and and streams also does not guarantee any ordering(Encounter order) for such objects. if you really want to preserve ordering LinkedHashMap preserves the same.
 
praveen kumaar
Ranch Hand
Posts: 483
23
AngularJS Eclipse IDE Firefox Browser Java Spring VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Carey Brown wrote:


How can you guarantee ordering for any map...
 
Carey Brown
Saloon Keeper
Posts: 5753
56
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

praveen kumaar wrote:

Carey Brown wrote:


How can you guarantee ordering for any map...


Maybe this is naive of me, but if you have a HashMap I would expect it to be in hashCode order. If it's a TreeMap I would expect it to be in key order. If it's a LinkedHashMap then I would expect it to be in the order it was added.
 
Carey Brown
Saloon Keeper
Posts: 5753
56
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Part of this boils down to my question regarding the sentence in the original requirements.
 
praveen kumaar
Ranch Hand
Posts: 483
23
AngularJS Eclipse IDE Firefox Browser Java Spring VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well i think their is a design issue inherent in the problem. OP has declared a map as a parameter and what he wants is this map to retain the input order which i think is a strong precondition in terms of contract of a Map and thus failing Liskov Substitution principle. But i will like it to be reviewed by some staff members like Junilu, Campbell.
 
Campbell Ritchie
Marshal
Posts: 63777
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tyoma Sakurakoji wrote:Input map is Map<String, Integer>, code is filter using value and map using key. I think it's correct...

Yes, I think you are right, but I don't think it answers OP's original question.
I think OP wants the List sorted by the values in the Map, but backwards.
 
Bartender
Posts: 20557
120
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

praveen kumaar wrote:Well i think their is a design issue inherent in the problem. OP has declared a map as a parameter and what he wants is this map to retain the input order which i think is a strong precondition in terms of contract of a Map and thus failing Liskov Substitution principle. But i will like it to be reviewed by some staff members like Junilu, Campbell.



I like that: https://www.tomdalling.com/blog/software-design/solid-class-design-the-liskov-substitution-principle/

Not sure if it's strictly applicable, but I like the meme, anyway.

You cannot retrieve the entries in a Map in the same order they were added, since unless the underlying data storage is some sort of ordered collection (for example, a List), the initial information is lost. See Stephen Hawking's assertions on black holes for a similar example. And in the case of a HashMap, there's certainly no assurance of such an underlying data store, which means that any algorithm assuming otherwise cannot be assumed to work in all cases.

Now if I just wanted to pull items in a collection (Map) that meet a certain criterium (value >= 60), I'd iterate the keySet and add the keys which, when fed to getValue() returned an applicable value to a List<String>. I could then sort that list to get key order (collating sequence). Or, I could sort with an inverted Comparator to get them in inverse collating order and save doing an extra pass to reverse them.

That's the traditional way. However, now we have lambdas, and I'm fairly certain that you could collapse most of that down into a lambda expression.
 
Campbell Ritchie
Marshal
Posts: 63777
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

praveen kumaar wrote:. . . Their is no such thing like order for HashMap . . . .

I thought the resultant List was to be sorted backwards by the “V”s in the Map. That is different from encounter order.
 
praveen kumaar
Ranch Hand
Posts: 483
23
AngularJS Eclipse IDE Firefox Browser Java Spring VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim wrote:Not sure if it's strictly applicable, but I like the meme, anyway.


I think that meme is conveying more than the rest of the page there. and here also i think OP has got a wrong abstraction...
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

praveen kumaar wrote:. . . Their is no such thing like order for HashMap . . . .

I thought the resultant List was to be sorted backwards by the “V”s in the Map. That is different from encounter order.


Sorry, still can't get why you think values would be used? The code of the first post and the problem description was saying that it first needed to display only those languages that has score >= 60, then list of string should be reversed against its original order. The only String values here are keys. In the original code also values were added in the list.
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tyoma Sakurakoji wrote:In the original code also values were added in the list.


I mean keys
 
Sheriff
Posts: 13343
221
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It seems to me a concrete example is needed to clarify the requirements. Plain English descriptions can be inexact and ambiguous and open to individual interpretation.

What I understand is this:

Given a Map<String, Integer> {
 "English" -> 90,
 "Spanish" -> 70,
 "Bahasa" -> 50,
 "Japanese" -> 62,
 "Tamil" -> 5,
 "French" -> 73,
 "German" -> 79
}

The first step of filtering results in a String array containing everything except Bahasa and Tamil since these have values less than 60.

Next step is to sort them in descending order by value in the Map so:

["English", "German", "French", "Spanish", "Japanese"]

That is final result.

Is this the correct interpretation of the requirements?
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

praveen kumaar wrote:

Tyoma Sakurakoji wrote:Are you need to preserve the original order of the input hashmap entries and just reverse it afterwards? If so, then remove sorted call and reverse the resulting list


Their is no such thing like order for HashMap as it is a unordered data structure, even HashSet is unordered and and streams also does not guarantee any ordering(Encounter order) for such objects. if you really want to preserve ordering LinkedHashMap preserves the same.


You right, I mean encounter order
 
Carey Brown
Saloon Keeper
Posts: 5753
56
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Carey Brown wrote:

Marcello Lippi wrote:Then I should sort array list of strings in descending order comparing to its equivalent in hashmap.


Sorry, I can't quite parse this sentence. "Equivalent" based on what? The key? The Value? It's hash order?


Exactly! We're guessing at the OP's requirements.
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:It seems to me a concrete example is needed to clarify the requirements. Plain English descriptions can be inexact and ambiguous and open to individual interpretation.

What I understand is this:

Given a Map<String, Integer> {
 "English" -> 90,
 "Spanish" -> 70,
 "Bahasa" -> 50,
 "Japanese" -> 62,
 "Tamil" -> 5,
 "French" -> 73,
 "German" -> 79
}

The first step of filtering results in a String array containing everything except Bahasa and Tamil since these have values less than 60.
Next step is to sort them in descending order by value in the Map so:

["English", "German", "French", "Spanish", "Japanese"]

That is final result.

Is this the correct interpretation of the requirements?


I think the last step is not sorting, but reverse against encounter order, so the answer would be (asumming encounter order would be the same as it is written above):

["German", "French", "Japanese", "Spanish", "English"]
 
Junilu Lacar
Sheriff
Posts: 13343
221
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Marcello Lippi wrote:Then I should sort array list of strings in descending order comparing to its equivalent in hashmap


No, I'm almost 100% sure my interpretation of the above is correct. In other words, sort the languages in descending order according to their corresponding values in the HashMap.

If this were graph data and the values were millions of people in a certain population who spoke a language, then this will show you the most widely spoken language first and the least widely spoken language last for all languages spoken by at least 60 million people.
 
Tim Holloway
Bartender
Posts: 20557
120
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

praveen kumaar wrote:. . . Their is no such thing like order for HashMap . . . .

I thought the resultant List was to be sorted backwards by the “V”s in the Map. That is different from encounter order.



Hashcodes are integers, so no "V". You're thinking of the default output of toString, which is actually based on heap internal storage location or something like that, I think.
 
Tim Holloway
Bartender
Posts: 20557
120
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Incidentally, the object's hashCode() value is not the hash value used to find key/value pairs in the Map. The hash value for the Map is an integer whose range runs from 0..primary_hash_slots, and thus depends on what parameters were passed to (or defaulted by) the HashMap constructor. An object's hashCode is used as a fast comparator for two objects of the same class so that complex classes don't have to be compared field-by-field to determine equals(). In the case, for example, of JPA Entity elements, two objects are equals() if both have identical key values, for keys of 1..n fields, so the hashCode algorithm for them makes a combined hash of the individual key components, but ignores the other data fields. That's how changes in a record can be determined - they're equals(), but not field-for-field identical.

There is no iterator for a Map. Instead you have to get the keySet, entrySet or valueSet and iterate that. Sets iterate in no guaranteed order, and while you might assume that a HashSet might iterate its keys in ascending hashvalue order, there are no assurances, and even if there were, you'd have to consider whether overflows were handled depth-first or not.

In brief:

A) you cannot iterate a Map, only retrieve a Set of data (keys, values, or Entries) from the Map.
B) As Sets have no natural order, you should treat them just like database tables. If you want an order, you have to enforce an order.
 
Campbell Ritchie
Marshal
Posts: 63777
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:. . . Hashcodes are integers, so no "V". You're thinking of the default output of toString . . .

I think we need to hear more from OP, because nobody seems sure how he intends the resultant List to be ordered/sorted.
 
Junilu Lacar
Sheriff
Posts: 13343
221
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I think we need to hear more from OP, because nobody seems sure how he intends the resultant List to be ordered/sorted.


I guess you missed the part where I said "I'm almost 100% sure my interpretation is correct." But yes, OP needs to confirm whether or not that is in fact what he/she meant.
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Marcello Lippi wrote:Honestly, I would love to see solution for my initial code. Yes, it is extremely ugly, but at least I do understand it. In the same time, your solutions are brilliant, but I don't understand streams completely yet.


I just used variable name as inputMap in the sake of clarity, you should use the variable name that is passed inside the method
 
Campbell Ritchie
Marshal
Posts: 63777
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . I guess you missed the part where I said "I'm almost 100% sure my interpretation is correct." . . .

Yes, I did. Sorry. But I'm almost 100% sure my interpretation is the same as yours.
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:There is no iterator for a Map. Instead you have to get the keySet, entrySet or valueSet and iterate that. Sets iterate in no guaranteed order, and while you might assume that a HashSet might iterate its keys in ascending hashvalue order, there are no assurances, and even if there were, you'd have to consider whether overflows were handled depth-first or not.

In brief:

A) you cannot iterate a Map, only retrieve a Set of data (keys, values, or Entries) from the Map.
B) As Sets have no natural order, you should treat them just like database tables. If you want an order, you have to enforce an order.


This is true only for some implementation of the map (i.e. HashMap), but not in general.
Also values are returned from Map as Collection and not as Set since map can hold equal values.
 
Campbell Ritchie
Marshal
Posts: 63777
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:There is no iterator for a Map. . . .

Tim is correct; if you look at the Map interface, you won't find an iterator() method.
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:

Campbell Ritchie wrote:

praveen kumaar wrote:. . . Their is no such thing like order for HashMap . . . .

I thought the resultant List was to be sorted backwards by the “V”s in the Map. That is different from encounter order.



Hashcodes are integers, so no "V". You're thinking of the default output of toString, which is actually based on heap internal storage location or something like that, I think.


I think Richie mean that the orignal problem that was given to TS was to filter all the languages from the map that has score >= 60 (score = majority of the language within the world) and then display them according to majority in decending order. It really sounds logical and I start to thought that it really was the original intention of the problem. That's why Ritchie was insisted on using value instead of the key. We all have been confused by the first post describing the task ))
 
Tyoma Sakurakoji
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:

Tim Holloway wrote:There is no iterator for a Map. . . .

Tim is correct; if you look at the Map interface, you won't find an iterator() method.


Oops, included it in quote accidently (
 
Tim Holloway
Bartender
Posts: 20557
120
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tyoma Sakurako wrote:Also values are returned from Map as Collection and not as Set since map can hold equal values.



My apologies. Keys and Entryies are unique, and returned as Sets. But multiple keys can have the same value, so they are returned as a Collection.

And, in fact, it's a live collection, so if you alter or remove elements from it, the Map that it was returned from is also affected! If you delete a values() collection element, the corresponding key will be removed from the map. Or at least, that's how I read "mapping". It's another case of sloppy documentation, since you could just as easily be keeping the key and setting its value to null.
 
The problems of the world fade way as you eat a piece of pie. This tiny ad has never known problems:
global solutions you can do in your home or backyard
https://coderanch.com/t/708587/global-solutions-home-backyard
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!