私は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;
}
それは以下で動作します:
Map<TimeUnit,Long> map = new TreeMap<TimeUnit,Long>(Collections.reverseOrder());
しかし、私は最初に試しました
Map<TimeUnit,Long> map = Maps.newTreeMap(Collections.reverseOrder());
私のIntelliJは何も言いませんが、私のコンパイラは次のように言います。
DateUtils.java:[302,48]互換性のないタイプ。型変数K、Vのインスタンスが存在しないため、java.util.TreeMapがjava.util.Mapに準拠します[エラー]が見つかりました:java.util.TreeMap [エラー]が必要です:java.util.Map
コンパレータがなくても正常に動作します。
Map<TimeUnit,Long> map = Maps.newTreeMap();
しかし、私は試してみました:
Map<TimeUnit,Long> map = Maps.newTreeMap(Collections.<TimeUnit>reverseOrder());
そしてと:
Map<TimeUnit,Long> map = Maps.newTreeMap(new Comparator<TimeUnit>() {
@Override
public int compare(TimeUnit timeUnit, TimeUnit timeUnit1) {
return 0;
}
});
そして、私は同じエラーを受け取りました。したがって、TreeMapでコンパレータを使用するたびに、型推論が機能しなくなったようです。なんで?
Guavaメソッドのシグネチャは次のとおりです。
public static <C, K extends C, V> TreeMap<K, V> newTreeMap(Comparator<C> comparator)
期待される戻り型は型であるため、コンパレータがない場合、JavaはK=TimeUnitおよびV=Longであると推測できます。
タイプTimeUnitのコンパレータを使用すると、JavaはCがTimeUnitであることを認識します。また、期待される戻り型が型であることがわかっているため、K=TimeUnitおよびV=Longです。TimeUnitはTimeUnitを拡張するので、K extends Cは尊重されます(とにかく、間違っていると思われる場合は、オブジェクトコンパレータでも試しました...)
だから私はなぜこの場合型推論が機能しないのか疑問に思いますか?