Java Функция в версии 1.7 (преобразование лямбда-выражений) - PullRequest
0 голосов
/ 04 августа 2020

Я работаю над старым java приложением, которое использует Java 1.7. Я хотел бы использовать интерфейс java.util.function.Function. Однако это поддерживается только в Java 1.8 +.

Поэтому я хотел бы написать свою собственную реализацию в Java 1.7.

import java.util.Objects;

public interface Function<T, R> {
    
    R apply(T t);
    
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v)); // lambda expression
    }
    
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t)); // lambda expression
    }
    
    static <T> Function<T, T> identity() {
        return t -> t; // lambda expression
    }
}

Вышеупомянутое дает мне ошибки компиляции на лямбда-выражения.

Вопрос

Как мне записать вышеуказанные лямбда-выражения в Java 1.7?

Ответы [ 2 ]

2 голосов
/ 04 августа 2020

Поскольку на самом деле вы не можете создать интерфейс с помощью методов по умолчанию, я думаю, что ваш лучший шанс - это методы stati c.

public interface Function<T, R> {
    R apply(T t);

    public static <T, V, R> Function<V, R> compose(Function<? super V, ? extends T> before, Function<? super T, ? super R> after) {
        return new CombiningFunction<T, V, R>(before, after);
    }
    
    public static <T, R, V> Function<T, V> andThen(Function<? super T, ? super R> before, Function<? super R, ? extends V> after) {
        return new CombiningFunction<T, V, R>(before, after);
    }
    
    static <T> Function<T, T> identity() {
        return new Function<T, T> {
            T apply(T t) { return t; }
        }
    }
}

class CombiningFunction<T, V, R> implements Function<T, R> {
    Function<T, V> first;
    Function<V, R> second;

    public R apply(T t) {
        V intermediate = first.apply(t);
        return second.apply(intermediate);
    }
}

Но, как KarelG упоминает в комментариях, на самом деле не рекомендуется сделай это; не говоря уже о том, что это не так элегантно, как в Java 8; в конце концов, функциональные интерфейсы в значительной степени ориентированы на лямбды, и если у вас их нет, любое использование будет таким же неудобным, как и реализация выше.

1 голос
/ 04 августа 2020

Вы можете использовать IntellijIdea , чтобы изменить его автоматически. Результатом будет IntellijIdea :

import java.util.Objects;

public interface Function<T, R> {

    R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return new Function<V, R>() {
            @Override
            public R apply(V v) {
                return Function.this.apply(before.apply(v));
            }
        }; // lambda expression
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        Function<T, V> tvFunction = new Function<T, V>() {
            @Override
            public V apply(T t) {
                return after.apply(Function.this.apply(t));
            }
        };
        return tvFunction; // lambda expression
    }

    static <T> Function<T, T> identity() {
        return new Function<T, T>() {
            @Override
            public T apply(T t) {
                return t;
            }
        }; // lambda expression
    }
}
...