代码之家  ›  专栏  ›  技术社区  ›  iamkenos

Java 8:流式传输列表并基于不同的过滤器映射到另一个列表

  •  5
  • iamkenos  · 技术社区  · 7 年前

    我有以下几点 代码:

    public boolean foo(List<JSONObject> source, String bar, String baz) {
        List<String> myList = newArrayList();
    
        source.forEach(json -> {
            if (!(json.get(bar) instanceof JSONObject)) {
                myList.add(json.get(bar).toString());
            } else {
                myList.add(json.getJSONObject(attribute).get("key").toString());
            }
        });
    
        /**
         * do something with myList and baz
         */
    }
    

    我只是想知道有没有办法 if-else 使用筛选器内联条件。

    大致如下:

    List<String> myList = source.stream()
                    .filter(json -> !(json.get(bar) instanceof JSONObject))
                    .map(item -> item.get(attribute).toString())
                    .collect(Collectors.toList());
    

    如果我按照上面的方法去做,我将错过应该是“else”的条件。如何使用 java-8 方法

    提前感谢!

    4 回复  |  直到 7 年前
        1
  •  6
  •   Eran    7 年前

    我所看到的唯一方法是将条件置于 map 呼叫如果您使用 filter 你失去了“其他”部分。

    List<String> myList = source.stream()
                .map(item -> {
                      if (!(item.get(bar) instanceof JSONObject)) {
                          return item.get(bar).toString();
                      } else {
                          return item.getJSONObject(attribute).get("key").toString();
                      }
                })
                .collect(Collectors.toList());
    

    或者,正如霍尔格在评论中所建议的,使用三元条件运算符:

    List<String> myList = source.stream()
                .map(i -> (i.get(bar) instanceof JSONObject ? i.getJSONObject(attribute).get("key") : i.get(bar)).toString())
                .collect(Collectors.toList());
    
        2
  •  5
  •   Bentaye    7 年前

    像这样的怎么样?

      List<String> myList = source.stream()
          .map(json -> !(json.get(bar) instanceof JSONObject) ? 
                json.get(bar).toString() : 
                json.getJSONObject(attribute).get("key").toString())
          .collect(Collectors.toList());
    

    没有经过测试,但你明白了。

        3
  •  2
  •   Dimitri    7 年前

    您可以使用该功能 partitioningBy 这需要 Predicate 和返回 Map<Boolean, List<T>> . 这个 true 键包含谓词和 false 键包含其他值。

    因此,您可以像这样重写代码:

    Map<Boolean, List<String>> partition = source.stream()
                .collect(Collectors.partitionBy(json -> !(json.get(bar) instanceof JSONObject));
    

    在这种情况下,无需使用过滤器功能。

    List<String> valuesWhenTrue = partition.get(Boolean.TRUE).stream().map(item -> item.get(attribute).toString()).collect(Collectors.toList());   
    
    List<String> valuesWhenFalse = partition.get(Boolean.FALSE).stream().map(json.getJSONObject(attribute).get("key").toString()).collect(Collectors.toList());
    
        4
  •  1
  •   Frablamo    7 年前

    将if-else提取到私有函数中如何

    private String obtainAttribute(JSONObject json){
      if (!(json.get(bar) instanceof JSONObject)) {
        return json.get(bar).toString();
      }
        return json.getJSONObject(attribute).get("key").toString();
    }
    

    用lambda表达式调用它。

        List<String> myList = source.stream()
        .map(item -> obtainAttribute(item))
        .collect(Collectors.toList());