可选<t> </t>的比较器

时间:2015-04-10 20:27:48

标签: java generics guava

我有abstract class OptionalComparator<T extends Comparable<T>> implements Comparator<Optional<T>>

到目前为止,非常好。

遵循Optional本身使用的模型,我认为最好有一个这个类的实例,并在必要时进行转换(例如,转移到OptionalComparator<Integer>)。

所以我做了private static final OptionalComparator<? extends Comparable<?>> ABSENT_FIRST

当我尝试分配值时遇到了麻烦。该类型应该是什么?

new OptionalComparator<Comparable<Object>>() {...}无法正常工作。

new OptionalComparator<Comparable<Comparable<Object>>>() {...}无法正常工作。

例如,

new OptionalComparator<Integer>() {...}确实有效,但我希望最不具体的类型可能。

我做错了什么?如何创建此类的基本案例实例?

3 个答案:

答案 0 :(得分:6)

您可以使用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

答案 1 :(得分:4)

Guava现在提供(自21.0开始,但仍为@BetaComparators .emptiesLast(Comparator)emptiesFirst(Comparator)

示例:Comparator<Optional<Instant>> compareOptInst = Comparators.emptiesLast(Comparator.<Instant>naturalOrder());

答案 2 :(得分:2)

你可能只需做一个不安全的演员。考虑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;
}

在这种情况下,使用原始类型实例可能同样最简单。只要您使用通用强制类型转换所有返回ABSENT_FIRST的调用,这样就可以了,并且调用代码不应该有任何警告。