可选的比较器<T>
Comparator for Optional<T>
我有abstract class OptionalComparator<T extends Comparable<T>> implements Comparator<Optional<T>>
到目前为止,还不错。
按照 Optional 本身使用的模型,我认为最好有这个 class 的单个实例,并在必要时转换它(例如,转换为 OptionalComparator<Integer>
)。
所以我做了private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST
。
当我试图赋值时,麻烦来了。类型应该是什么?
new OptionalComparator<Comparable<Object>>() {...}
无效。
new OptionalComparator<Comparable<Comparable<Object>>>() {...}
无效。
例如,new OptionalComparator<Integer>() {...}
确实有效,但我想要尽可能不明确的类型。
我做错了什么?如何创建此 class 的基本实例?
您可以有多个 OptionalComparator
的实现,如下所示:
private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST = new AbsentFirst<>();
private static final OptionalComparator<? extends Comparable<?>> ABSENT_LAST = new AbsentLast<>();
private interface OptionalComparator<T extends Comparable<T>> extends Comparator<Optional<T>> { }
private static class AbsentFirst<T extends Comparable<T>> implements OptionalComparator<T> {
@Override
public int compare(Optional<T> obj1, Optional<T> obj2) {
if (obj1.isPresent() && obj2.isPresent()) {
return obj1.get().compareTo(obj2.get());
} else if (obj1.isPresent()) {
return -1;
} else if (obj2.isPresent()) {
return 1;
} else {
return 0;
}
}
}
private static class AbsentLast<T extends Comparable<T>> implements OptionalComparator<T> {
@Override
public int compare(Optional<T> obj1, Optional<T> obj2) {
if (obj1.isPresent() && obj2.isPresent()) {
return obj1.get().compareTo(obj2.get());
} else if (obj1.isPresent()) {
return 1;
} else if (obj2.isPresent()) {
return -1;
} else {
return 0;
}
}
}
static <T extends Comparable<T>> OptionalComparator<T> absentFirstComparator() {
@SuppressWarnings("unchecked")
OptionalComparator<T> comp = (OptionalComparator<T>) ABSENT_FIRST;
return comp;
}
static <T extends Comparable<T>> OptionalComparator<T> absentLastComparator() {
@SuppressWarnings("unchecked")
OptionalComparator<T> comp = (OptionalComparator<T>) ABSENT_LAST;
return comp;
}
public static void main(String... args) {
OptionalComparator<Integer> absentFirstInt = absentFirstComparator();
System.out.println(absentFirstInt.compare(Optional.of(1), Optional.empty()));
OptionalComparator<Integer> absentLastInt = absentLastComparator();
System.out.println(absentLastInt.compare(Optional.of(1), Optional.empty()));
OptionalComparator<Double> absentFirstDouble = absentFirstComparator();
System.out.println(absentFirstDouble.compare(Optional.of(1.0), Optional.empty()));
OptionalComparator<Double> absentLastDouble = absentLastComparator();
System.out.println(absentLastDouble.compare(Optional.of(1.0), Optional.empty()));
}
输出:
-1
1
-1
1
您可能只需要进行不安全的转换。考虑 ImmutableList
如何处理空列表情况:
private static final ImmutableList<Object> EMPTY =
new RegularImmutableList<Object>(ObjectArrays.EMPTY_ARRAY);
/**
* Returns the empty immutable list. This set behaves and performs comparably
* to {@link Collections#emptyList}, and is preferable mainly for consistency
* and maintainability of your code.
*/
// Casting to any type is safe because the list will never hold any elements.
@SuppressWarnings("unchecked")
public static <E> ImmutableList<E> of() {
return (ImmutableList<E>) EMPTY;
}
在这种情况下,使用原始类型实例可能同样最简单。只要您将 return ABSENT_FIRST
的所有调用都用通用类型转换,就可以了,调用代码不应有任何警告。
Guava 现在提供(自 21.0 起,不再提供 @Beta since 27.1) Comparators
.emptiesLast(Comparator)
和 emptiesFirst(Comparator)
.
示例:Comparator<Optional<Instant>> compareOptInst = Comparators.emptiesLast(Comparator.naturalOrder());
我有abstract class OptionalComparator<T extends Comparable<T>> implements Comparator<Optional<T>>
到目前为止,还不错。
按照 Optional 本身使用的模型,我认为最好有这个 class 的单个实例,并在必要时转换它(例如,转换为 OptionalComparator<Integer>
)。
所以我做了private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST
。
当我试图赋值时,麻烦来了。类型应该是什么?
new OptionalComparator<Comparable<Object>>() {...}
无效。
new OptionalComparator<Comparable<Comparable<Object>>>() {...}
无效。
new OptionalComparator<Integer>() {...}
确实有效,但我想要尽可能不明确的类型。
我做错了什么?如何创建此 class 的基本实例?
您可以有多个 OptionalComparator
的实现,如下所示:
private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST = new AbsentFirst<>();
private static final OptionalComparator<? extends Comparable<?>> ABSENT_LAST = new AbsentLast<>();
private interface OptionalComparator<T extends Comparable<T>> extends Comparator<Optional<T>> { }
private static class AbsentFirst<T extends Comparable<T>> implements OptionalComparator<T> {
@Override
public int compare(Optional<T> obj1, Optional<T> obj2) {
if (obj1.isPresent() && obj2.isPresent()) {
return obj1.get().compareTo(obj2.get());
} else if (obj1.isPresent()) {
return -1;
} else if (obj2.isPresent()) {
return 1;
} else {
return 0;
}
}
}
private static class AbsentLast<T extends Comparable<T>> implements OptionalComparator<T> {
@Override
public int compare(Optional<T> obj1, Optional<T> obj2) {
if (obj1.isPresent() && obj2.isPresent()) {
return obj1.get().compareTo(obj2.get());
} else if (obj1.isPresent()) {
return 1;
} else if (obj2.isPresent()) {
return -1;
} else {
return 0;
}
}
}
static <T extends Comparable<T>> OptionalComparator<T> absentFirstComparator() {
@SuppressWarnings("unchecked")
OptionalComparator<T> comp = (OptionalComparator<T>) ABSENT_FIRST;
return comp;
}
static <T extends Comparable<T>> OptionalComparator<T> absentLastComparator() {
@SuppressWarnings("unchecked")
OptionalComparator<T> comp = (OptionalComparator<T>) ABSENT_LAST;
return comp;
}
public static void main(String... args) {
OptionalComparator<Integer> absentFirstInt = absentFirstComparator();
System.out.println(absentFirstInt.compare(Optional.of(1), Optional.empty()));
OptionalComparator<Integer> absentLastInt = absentLastComparator();
System.out.println(absentLastInt.compare(Optional.of(1), Optional.empty()));
OptionalComparator<Double> absentFirstDouble = absentFirstComparator();
System.out.println(absentFirstDouble.compare(Optional.of(1.0), Optional.empty()));
OptionalComparator<Double> absentLastDouble = absentLastComparator();
System.out.println(absentLastDouble.compare(Optional.of(1.0), Optional.empty()));
}
输出:
-1
1
-1
1
您可能只需要进行不安全的转换。考虑 ImmutableList
如何处理空列表情况:
private static final ImmutableList<Object> EMPTY = new RegularImmutableList<Object>(ObjectArrays.EMPTY_ARRAY); /** * Returns the empty immutable list. This set behaves and performs comparably * to {@link Collections#emptyList}, and is preferable mainly for consistency * and maintainability of your code. */ // Casting to any type is safe because the list will never hold any elements. @SuppressWarnings("unchecked") public static <E> ImmutableList<E> of() { return (ImmutableList<E>) EMPTY; }
在这种情况下,使用原始类型实例可能同样最简单。只要您将 return ABSENT_FIRST
的所有调用都用通用类型转换,就可以了,调用代码不应有任何警告。
Guava 现在提供(自 21.0 起,不再提供 @Beta since 27.1) Comparators
.emptiesLast(Comparator)
和 emptiesFirst(Comparator)
.
示例:Comparator<Optional<Instant>> compareOptInst = Comparators.emptiesLast(Comparator.naturalOrder());