【问题标题】:Java8 to Java7 - Migrate ComparatorsJava8 到 Java7 - 迁移比较器
【发布时间】:2018-12-18 13:16:10
【问题描述】:

我无法理解如何在 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 接口实现。

但是如果我走那条路,我如何在同一个“比较”方法中同时应用“比较”、“然后比较”和“反向”?

提前致谢

【问题讨论】:

  • 我会使用guava,它有ComparisonChain,我认为它可以为你处理这个问题
  • 顺便说一句,你没有分享你尝试过的java 7代码版本,这给出了你提到的错误

标签: java-8 migration java-7 comparator


【解决方案1】:

甚至你的 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();
    }

【讨论】:

    【解决方案2】:

    您可以在单个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 这可能行不通。允许比较方法返回 any 整数值。但是 Integer.MIN_VALUE 的取反是它本身,所以在这种情况下并没有达到反转比较意义的效果。
    • @StuartMarks 啊,你完全正确。也许应该应用Math::signum 以避免此类错误并否定结果。 (我假设正确的 -1、0、1 值)。
    【解决方案3】:

    你可以用 java 7 的方式构造一个Comparator&lt;Entry&gt;,然后,你可以像在 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编译的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      相关资源
      最近更新 更多