Реализация функции карты - PullRequest
       4

Реализация функции карты

2 голосов
/ 06 ноября 2019

Я создаю 'SpecialList' и мне требуется реализовать функцию карты. Список должен быть ленивым, и будет давать значения только при оценке.

toString () возвращает "?"если значение еще не доступно;в противном случае возвращает строковое представление значения.

get () вызывается, когда необходимо содержимое. Если значение уже доступно, верните это значение;в противном случае вычислите значение и верните его. Вычисление должно быть выполнено только один раз для одного и того же значения.

Вот что у меня есть:

public <U> SpecialList<U> map(Function<T, U> mapper) {
    if (!this.isAvailable) {
        return new SpecialList<U>(this.supplier);
    }
    return new SpecialList<U>(mapper, value);
}

// private constructor
private SpecialList(CachedSupplier<T> s) {
    this.supplier = s;
    this.isAvailable = false;
}

Однако, это говорит мне, что нет действительного конструктора, потому что T не может быть преобразован в U.

SpecialList.java:65: error: no suitable constructor found for SpecialList(SpecialList<T>.CachedSupplier<T>)
            return new SpecialList<U>(this.supplier);
                   ^
    constructor SpecialList.SpecialList(U) is not applicable
      (argument mismatch; SpecialList<T>.CachedSupplier<T> cannot be converted to U)
    constructor SpecialList.SpecialList(Supplier<U>) is not applicable
      (argument mismatch; SpecialList<T>.CachedSupplier<T> cannot be converted to Supplier<U>)

Разве «U» не становится Т при возврате?

Как мне решить эту проблему? Я все еще немного неясен насчет универсальных типов уровня метода. Но мне сказали, что мне нужно добавить для моего метода карты.

Ниже приведен мой код полностью:

class SpecialList<T> {
    class CachedSupplier<T> {
        private Supplier<? extends T> supplier;
        private T value;
        boolean isAvailable;

        public CachedSupplier(Supplier<? extends T> supplier) {
            this.supplier = supplier;
        }

        public T get() {
            if (!isAvailable) {
                value = supplier.get();
                isAvailable = true;
            }
            return value;
        }
    }

    private CachedSupplier<T> supplier;
    private T value;
    boolean isAvailable;

    private SpecialList(T value) {
        this.value = value;
        this.isAvailable = true;
    }

    private SpecialList(Supplier<T> s) {
        this.supplier = new CachedSupplier<T>(s);
        this.isAvailable = false;
    }

    private SpecialList(CachedSupplier<T> s) {
        this.supplier = s;
        this.isAvailable = false;
    }

    private <R> SpecialList(Function<T, R> mapper, T v) {
        this.supplier = new CachedSupplier<T>(() -> mapper.apply(v));
        this.isAvailable = false;
    }

    public static <T> SpecialList<T> of(T value) {
        return new SpecialList<>(value);
    }

    public static <T> SpecialList<T> of(Supplier<T> supplier) {
        return new SpecialList<>(supplier);
    }

    public <R> SpecialList<R> map(Function<? super T,? extends R> mapper) {
        if (!this.isAvailable) {
            return new SpecialList<>(this.supplier);
        }
        return new SpecialList<R>(mapper, value);
    }

    public T get() {
        if(this.isAvailable) {
            return this.value;
        } else {
            this.value = this.supplier.get();
            this.isAvailable = true;
            return this.value;
        }
    }
}

Я все еще немного запутался с универсальными типами и т. Д. поэтому, пожалуйста, дайте мне знать, если что-то странное / я могу улучшить!

Спасибо

1 Ответ

0 голосов
/ 06 ноября 2019

Согласно опубликованному вами коду, во время компиляции в одном из конструкторов для класса SpecialList ...

private <R> SpecialList(Function<T, R> mapper, T v) {
    this.supplier = new CachedSupplier<T>(() -> mapper.apply(v));
    this.isAvailable = false;
}
* 1004 имеется ошибка во-первых, во-первых, в опубликованном вами коде нетконструктор во внутреннем классе CachedSupplier, который принимает параметр Function, поэтому вам нужно добавить его с такой сигнатурой:
public <R> CachedSupplier(Function<T, R> mapper)

И вторая проблема с конструктором SpecialList - это лямбда-выражение. Абстрактный метод apply в интерфейсе Function имеет параметр, который отсутствует в вашем лямбда-выражении. Поэтому код конструктора должен быть:

private <R> SpecialList(Function<T, R> mapper, T v) {
    this.supplier = new CachedSupplier<T>((v) -> mapper.apply(v));
    this.isAvailable = false;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...