Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

a weird code with generics  RSS feed

 
Pierrot Mongonnam
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello together,

I was about to play with the Java 8 Map API. Following my code:



so far, so good. But the situation which makes me confused, is the following:

if I want to sort my Map and display the content of the map, I can write something like this:



eclipse Neon returns the following warning: Type safety: Unchecked cast from Object to Map.Entry<String, String>

Question 1: why do I have the warning?

to avoid the warning I changed the code like this, after have seen a similar code in internet:

Question 2: could somebody help me to decrypt the syntax used? In other words what the hell should this weird syntax mean?
Map.Entry.<String,String>comparingByKey().... e.g.  the diamond operator direct after the point, directly followed by a function.
Why is it necessary, to write it so komplex? Probably I have to learn something concerning the generics.

thanks for helping
 
Tobias Bachert
Ranch Foreman
Posts: 85
18
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The warning is caused by the fact, that you are calling reversed on the comparator -> the compiler will no longer infer the type arguments of the comparator based on the sorted call as another method call is added inbetween -> type parameter is erased to Object.
As a result you currently create a Comparator<Object> that casts its argument to Map.Entry, which leads to the warning. You can specify the type of the argument instead of casting to prevent the unchecked cast as following:

or, a bit shorter

In your second example you are explicitly specifying the type arguments of the called method (comparingByKey has <K extends Comparable<? super K>, V> as type parameters (and returns Comparator<Map.Entry<K, V>>) -> you are telling the method to use String as type for K and V). The reason why this is required is again the intermediate reversed call which makes type infering based on the sorted call impossible.
 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 103
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The answer given by Tobias is excellent. Java is unable to infer the type, so you have to indicate it. You might however do this by other means, which, although less efficient, are worth considering:

You may declare the function on its own, which would make it reusable (it might be useful in some cases):



or you might parameterize the call to the comparing method:



The first example is probably the cleanest and the easiest to read. It has however a performance impact, since it forces the creation of an object to represent the function, which is not the case with the other examples.

The second example uses a parameterized method call, exactly like your example with the comparingByKey method. It is ugly, and has the drawback of probably not being so well known by Java developers, so it might make your code difficult to read to others. On the other hand, it might make them learn something ;-) Parameterized method calls are essential if you intend to do functional programming in Java.

 
Pierre-Yves Saumont
Author
Ranch Hand
Posts: 103
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another possibility would be to use the following:



or you might call reverse later:



And if the keys are to be sorted ignoring case, you might simplify this further:




 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!