I've written an utility method in Java:
public static final ImmutableSortedSet<TimeUnit> REVERSED_TIMEUNITS = ImmutableSortedSet.copyOf(
Collections.<TimeUnit>reverseOrder(),
EnumSet.allOf(TimeUnit.class)
);
/**
* Get the number of ..., minutes, seconds and milliseconds
*
* You can specify a max unit so that you don't get days for exemple
* and can get more than 24 hours if you want to display the result in hours
*
* The lowest unit is milliseconds
* @param millies
* @param maxTimeUnit
* @return the result map with the higher unit first
*/
public static Map<TimeUnit,Long> getCascadingDateDiff(long millies,TimeUnit maxTimeUnit) {
if ( maxTimeUnit == null ) {
maxTimeUnit = TimeUnit.DAYS;
}
Map<TimeUnit,Long> map = new TreeMap<TimeUnit,Long>(Collections.<TimeUnit>reverseOrder());
long restInMillies = millies;
Iterable<TimeUnit> forUnits = REVERSED_TIMEUNITS.subSet(maxTimeUnit,TimeUnit.MICROSECONDS); // micros not included
// compute the number of days, then number of hours, then minutes...
for ( TimeUnit timeUnit : forUnits ) {
long numberForUnit = timeUnit.convert(restInMillies,TimeUnit.MILLISECONDS);
map.put(timeUnit,numberForUnit);
restInMillies = restInMillies - timeUnit.toMillis(numberForUnit);
}
return map;
}
It works with:
Map<TimeUnit,Long> map = new TreeMap<TimeUnit,Long>(Collections.reverseOrder());
But I first tried with
Map<TimeUnit,Long> map = Maps.newTreeMap(Collections.reverseOrder());
My IntelliJ doesn't say anything, while my compiler says:
DateUtils.java:[302,48] incompatible types; no instance(s) of type variable(s) K,V exist so that java.util.TreeMap conforms to java.util.Map [ERROR] found : java.util.TreeMap [ERROR] required: java.util.Map
It works fine without the comparator:
Map<TimeUnit,Long> map = Maps.newTreeMap();
But I tried with:
Map<TimeUnit,Long> map = Maps.newTreeMap(Collections.<TimeUnit>reverseOrder());
And with:
Map<TimeUnit,Long> map = Maps.newTreeMap(new Comparator<TimeUnit>() {
@Override
public int compare(TimeUnit timeUnit, TimeUnit timeUnit1) {
return 0;
}
});
And i got the same error. So it seems each time i'm using a comparator in the TreeMap, type inference doesn't work anymore. Why?
The signature of the Guava method is:
public static <C, K extends C, V> TreeMap<K, V> newTreeMap(Comparator<C> comparator)
The expected return type is of type so without a comparator, Java is able to infer that K = TimeUnit and V = Long.
With a comparator of type TimeUnit, Java knows that C is TimeUnit. It also knows that the expected return type is of type so K = TimeUnit and V = Long. K extends C is respected since TimeUnit extends TimeUnit (anyway I tried also with an Object comparator if you think it's wrong...)
So i just wonder why type inference doesn't work in this case?
Type inference represents the Java compiler's ability to look at a method invocation and its corresponding declaration to check and determine the type argument(s). The inference algorithm checks the types of the arguments and, if available, assigned type is returned.
Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.
The Target-Type of an expression is the data type that the Java Compiler expects depending on where the expression appears. Java 8 supports inference using Target-Type in a method context.
Like Michael Laffargue suggested, it is an OpenJDK6 type inference bug:
https://bugs.openjdk.java.net/show_bug.cgi?id=100167
http://code.google.com/p/guava-libraries/issues/detail?id=635
It works fine in my IntelliJ, and with a OpenJDK in version 7, and with others JDK in version 6.
The following suggestion of kutschkem works:
Map<TimeUnit,Long> map = Maps.<TimeUnit,TimeUnit,Long>newTreeMap(Collections.<TimeUnit>reverseOrder());
Notice the <TimeUnit,TimeUnit,Long>
which permits to force the typed parameters explicitly.
Check this related topic: What's this generics usage in Java? X.<Y>method()
Thanks all
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With