Можно ли дать функцию в качестве конструктора перечисления param? - PullRequest
1 голос
/ 07 ноября 2019

Я использую несколько компонентов, которые не могу отредактировать, моя ситуация такая:

private enum Radio {

    SPACE(" "),
    PLUS("+"),
    MINUS("-");


    private String value;

    private Radio(final String value) {
        this.value = value;
    }

    public static void setSelection(final CodeEntry entry, final String flag) {
        entry.getButtonWhite().setSelection(flag.equals(SPACE.value));
        entry.getButtonGreen().setSelection(flag.equals(PLUS.value));
        entry.getButtonRed().setSelection(flag.equals(MINUS.value));
    }
}

Мне это не нравится. Я хочу связать кнопку с перечислением. Все остальное не соответствует действительности, если не сказать больше. Но я не знаю, как

private enum Radio {

    SPACE(" ", CodeEntry::getButtonWhite),
    PLUS("+", CodeEntry::getButtonGreen),
    MINUS("-", CodeEntry::getButtonRed);
...

static reference to the non-static method getButtonWhite()

То, что я хочу, это что-то вроде accept(T t). Поэтому я даю getter в качестве параметра конструктора, затем вызываю этот getter для объекта с enum.accept(t), например так:

private enum Radio {

    SPACE(" ", CodeEntry::getButtonWhite),
    PLUS("+", CodeEntry::getButtonGreen),
    MINUS("-", CodeEntry::getButtonRed);

    setSelection(final CodeEntry entry, final String flag) {
        // Button button = Radio.valueOf(flag).accept(entry);
        // button.setSelection(true);
        Radio.valueOf(flag).accept(entry).setSelection(true);
    }

Я не уверен, возможно ли это, и синтаксис вродепобедить меня.

Ограничения моего примера

Хотя я ценю любой работоспособный ответ, я не могу изменить следующие вещи, поэтому я приму только ответ, помеченный следующим:

  • Флаг является строкой и будет строкой независимо от того, что.

  • Записи будут иметь getButtonX, который не изменится.

  • Я использую Java 8, это не изменится.

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

Ответы [ 2 ]

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

Поскольку вы не указали тип (типы), которые возвращают методы CodeEntry::getButton*, я буду обозначать его T для моего примера.


Ваш второй enumпараметр может быть Function<CodeEntry, T>, что позволит вам использовать ссылку на метод:

private enum Radio {
    SPACE(" ", CodeEntry::getButtonWhite),
    PLUS("+", CodeEntry::getButtonGreen),
    MINUS("-", CodeEntry::getButtonRed);

    private final String value;

    private final Function<CodeEntry, T> buttonFunction;

    private Radio(final String value, Function<CodeEntry, T> buttonFunction) {
        this.value = value;
        this.buttonFunction = buttonFunction;
    }

    public static void setSelection(final CodeEntry entry, final String flag) {
        Arrays.stream(values())
              .filter(radio -> flag.equals(radio.value))
              .findAny()
              .ifPresent(radio -> {
                 radio.buttonFunction.apply(entry).setSelection(true);
              });
    }
}

Предполагается, что параметр flag будет " ", "+" или "-".

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

Вот решение с использованием метода abstract:

private enum Radio {
    SPACE(" ") {
        @Override
        public void setSelection(final CodeEntry entry, final String flag) {
            // do whatever
        }
    },
    ...

    public abstract void setSelection(final CodeEntry entry, final String flag);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...