Java8转Java7 - 迁移Comparators

4

我有困难理解如何在Java7中“迁移”一个简单的比较器。

我在Java8中使用的实际版本是:

 private static final Comparator<Entry> ENTRY_COMPARATOR = Comparator.comparing(new Function<Entry, EntryType>() {
    @Override
    public EntryType apply(Entry t) {
        return t.type;
    }
})
        .thenComparing(Comparator.comparingLong(new ToLongFunction<Entry>() {
            @Override
            public long applyAsLong(Entry value) {
                return value.count;
            }
        }).reversed());

但在构建阶段,我遇到了这个错误:
static interface method invocations are not supported in -source 7

我该如何将同样的比较器迁移到Java7?我正在搜索解决方案,但唯一能想到的是将自己的类实现为Comparator接口的实现。

但是如果我这样做,如何在同一个“compare”方法中应用“comparing”、“then comparing”和“reverse”呢?

提前致谢。


2
我会使用guava,它有ComparisonChain,我认为它可以为您处理这个。 - Eugene
顺便说一句,你没有分享你尝试过的Java 7代码版本,这个版本出现了你提到的错误。 - Naman
3个回答

6

即使是您的Java 8版本,也可以通过以下方式缩短并使代码更易读:

Comparator.comparing(Entry::getType)
          .thenComparingLong(Entry::getCount)
          .reversed();

使用 guava(适用于Java 7),这看起来有点啰嗦:

    @Override
    public int compare(Entry left, Entry right) {
        return ComparisonChain.start()
                .compare(left.getType(), right.getCount(), Ordering.natural().reversed())
                .compare(left.getCount(), right.getCount(), Ordering.natural().reversed())
                .result();
    }

3
你可以在一个单独的compare方法中编写逻辑:
public int compare (Entry one,Entry two) {
    int result = two.getType().compareTo(one.getType());
    if (result == 0) {
        result = Long.compare(two.getCount(),one.getCount());
    }
    return result;
}

请注意,通过交换比较的Entry实例的顺序来实现反向排序。

要反转结果,只需在返回时在结果前加上一个“-”即可。 - Flown
2
@Flown 那可能行不通。比较方法允许返回任何整数值。但是Integer.MIN_VALUE的否定本身就是它本身,因此在这种情况下无法实现反转比较的效果。 - Stuart Marks
@StuartMarks 哦,你说得完全正确。也许应该应用 Math::signum 来避免这种错误并取反结果。(我假设有适当的 -1、0、1 值)。 - Flown

1
您可以按照Java 7的方式构建一个Comparator<Entry>,然后可以链接默认方法,就像在Java 8中一样,但不使用lambda表达式或方法引用作为参数:
private static final Comparator<Entry> ENTRY_COMPARATOR = new Comparator<Entry>() {
    @Override
    public int compare(Entry left, Entry right) {
        return left.type.compareTo(right.type);
    }
}
.thenComparingLong(new ToLongFunction<Entry>() {
    @Override
    public long applyAsLong(Entry entry) {
        return entry.value;
    }
})
.reversed();

上面的代码是使用-source 1.7编译的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接