Если еще с java 8 лямбда - PullRequest
       7

Если еще с java 8 лямбда

0 голосов
/ 07 апреля 2020

Я хочу заменить обычную лямбду на другую. Рассмотрите следующий выделенный код, есть ли какой-нибудь простой способ представить его с помощью Lambda?

public class IfElseLambda {

    public static void main(String[] args) {

        String value = null;
        DataObj data = new DataObj();

        List<DataObj> dataObjs = data.getDataObjs();

        ***if (dataObjs != null) {

            value = dataObjs.stream().map(dataObject -> getValue(dataObject)).filter(Objects::nonNull).findFirst().orElse(null);
        } else {
            value = getValue(data);
        }***

    }


    public static String getValue(DataObj dataObj) {
        return "Get value from dataObj";
    }
}

class DataObj {
    List<DataObj> dataObjs;

    public List<DataObj> getDataObjs() {
        return dataObjs;
    }

    public void setDataObjs(List<DataObj> dataObjs) {
        this.dataObjs = dataObjs;
    }
}

Ответы [ 2 ]

3 голосов
/ 07 апреля 2020

Одна вещь, которую вы можете сделать, это изменить пустой список на что-то, что приведет к тому же выводу:

List<DataObj> dataObjs = Optional.ofNullable(data.getDataObjs()).orElse(Collections.singletonList(data));

dataObjs теперь будет списком с одним элементом в случае, если data.getDataObjs() is null.

Теперь вам не нужно if / else:

value = dataObjs.stream().map(dataObject -> getValue(dataObject)).filter(Objects::nonNull).findFirst().orElse(null);
0 голосов
/ 07 апреля 2020

I Ваша цель состоит в том, чтобы изолировать лог c вашего if-else и, возможно, разрешить его замену, возможно вы могли бы сделать следующее: ваша лямбда-выражение принимает в качестве входных данных ваш список данных, и возвращает вам строковое значение. Поэтому вы можете использовать интерфейс java .util.Function , например:

Function<List<DataObj>, String> extractor = dataList 
    -> dataList == null? Stream.of(DEFAULT_DATA_OBJ) : dataList.stream()
       .map(dataObject -> getValue(dataObject))
       .filter(Objects::nonNull)
       .findFirst()
       .orElse(null)

Обратите внимание, у вас все еще есть троичный оператор (не Посмотрите, как вы можете обойтись без него, потому что если ваш список может быть нулевым, вы даже не можете использовать Stream.concat для защиты от пустого списка). Однако с этой конструкцией логика c вашего троичного оператора заменяется, если вы делаете заменяющую функцию экстрактора в своем коде.

Пример:

public static void main(String... args) {

    final List<DataObj> dataList = ...;
    final DataObj defaultValue = ...;

    Function<List<DataObj>, String> extractor = dataList 
        -> dataList == null? Stream.of(defaultValue) : dataList.stream()
           .map(dataObject -> getValue(dataObject))
           .filter(Objects::nonNull)
           .findFirst()
           .orElse(null);

    doStuff(dataList, extractor);

    // Now, if you want to change your extraction logic, do
    doStuff(dataList, whatever -> "Return a constant title");
}

public static void doStuff(final List<DataObj> dataList, final Function<List<DataObj, String> titleExtractor) {
   // Do stuff here
}
...