Java8 to Java7 - Migrate Comparators

Viewed 218

I'm having troubles understanding how to "migrate" a simple Comparator in Java7.

The actual version I'm using in Java8 is like:

 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());

But in build phase I get this error:

static interface method invocations are not supported in -source 7

How can I migrate the same comparator to Java7? I'm googling and searching for solution but the only thing I can think of, is to implement my own class as a Comparator interface implementation.

But If I go down that road, how can I apply both "comparing", "then comparing" and "reverse" in the same "compare" method?

Thanks in advance

3 Answers

Even your java-8 version can be made a lot shorter and easier to read with:

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

With guava (java-7 compatible), this looks a bit more verbose:

    @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();
    }

You can write the logic in a single compare method:

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;
}

Note that the reversed order in achieved by swapping the order of the compared Entry instances.

You can construct a Comparator<Entry> the java 7 way, afterward, you can chain the default methods as you can do in java 8, but without using lambda expressions or method references as a parameter :

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();

The code above is compiled with -source 1.7.

Related