如果 else 与 Java 8 Lambda

huangapple go评论75阅读模式
英文:

If else with java 8 Lambda

问题

public class IfElseLambda {

    public static void main(String[] args) {

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

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

        value = (dataObjs != null) ? 
                dataObjs.stream().map(dataObject -> getValue(dataObject)).filter(Objects::nonNull).findFirst().orElse(null) :
                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;
    }
}
英文:

I want to replace conventional if else with lambda. Consider following highlighted code, is there some simple way to have this represented with Lambda ?

public class IfElseLambda {

    public static void main(String[] args) {

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

        List&lt;DataObj&gt; dataObjs = data.getDataObjs();

        ***if (dataObjs != null) {

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

    }


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

class DataObj {
    List&lt;DataObj&gt; dataObjs;

    public List&lt;DataObj&gt; getDataObjs() {
        return dataObjs;
    }

    public void setDataObjs(List&lt;DataObj&gt; dataObjs) {
        this.dataObjs = dataObjs;
    }
}

答案1

得分: 2

你可以做的一件事是将空列表更改为产生相同输出的内容:

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

data.getDataObjs()为null的情况下,dataObjs现在将是一个只包含一个元素的列表。

现在你不需要使用if/else了:

value = dataObjs.stream().map(dataObject -> getValue(dataObject)).filter(Objects::nonNull).findFirst().orElse(null);
英文:

One thing you can do is to change the null list to something which results in the same output:

List&lt;DataObj&gt; dataObjs = Optional.ofNullable(data.getDataObjs()).orElse(Collections.singletonList(data));

dataObjs will now be a list with a single element in the case that data.getDataObjs() is null.

Now you don't need the if/else:

value = dataObjs.stream().map(dataObject -&gt; getValue(dataObject)).filter(Objects::nonNull).findFirst().orElse(null);

答案2

得分: 0

你的目标是隔离你的 if-else 逻辑,并且可能允许它被替换,也许你可以按照以下方式操作:
你的 lambda 接受数据列表作为输入,并返回一个字符串值。因此,你可以使用 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 来保护空列表)。然而,通过这种结构,如果你在代码中使提取器函数可替换,你的三元运算符的逻辑就是可替换的。

示例:

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

    // 现在,如果你想要改变你的提取逻辑,可以这样做
    doStuff(dataList, whatever -> "返回一个固定的标题");
}

public static void doStuff(final List<DataObj> dataList, final Function<List<DataObj>, String> titleExtractor) {
   // 在这里进行操作
}
英文:

I your aim is to isolate the logic of your if-else, and potentially allowing it to be replaced, maybe you could do the following :
Your lambda take as input your data list, and gives you back a String value. Therefore, you can use a java.util.Function interface, like this:

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

Note, you still have a ternary operator (Do not see how you could do without it, because if your list can be null, you cannot even use Stream.concat to protect from empty-list). However, with that construct, the logic of your ternary operator is replaceable if you make the extractor function replaceable in your code.

Exemple:

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

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

    doStuff(dataList, extractor);

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

public static void doStuff(final List&lt;DataObj&gt; dataList, final Function&lt;List&lt;DataObj, String&gt; titleExtractor) {
   // Do stuff here
}

huangapple
  • 本文由 发表于 2020年4月7日 14:44:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/61074238.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定