【问题标题】:How to cast lambda method parameters?如何转换 lambda 方法参数?
【发布时间】:2016-09-08 12:10:55
【问题描述】:

我有一个如下所示的 lambda 表达式。我想问的是有没有什么简单的方法或最佳实践来转换方法参数?

        results.forEach(
            (result) ->
            {
                ((JSONObject)result).put("test", "test"); 
                ((JSONObject)result).put("time", System.currentTimeMillis());  
                otherList.add(((JSONObject)result));
            }
    );

当我尝试改变输入类型时

(JSONObject result) ->

我遇到了错误;

incompatible types: Consumer<JSONObject> cannot be converted to Consumer<? super Object>

【问题讨论】:

  • 如消息所述,这些类型不兼容。为什么不直接引入局部变量?
  • @OliverCharlesworth 起初我认为(创建一个新的局部变量)但是如果我有 5-6 个输入怎么办?我需要为所有这些变量创建一个新变量吗?
  • 这个问题不是 lambdas 独有的——它适用于任何方法。 (也就是说,如果你有一个有 5-6 个输入的 lambda,可能会发生一些奇怪的事情!)
  • 正确参数化列表:使用List&lt;JSONObject&gt; 而不是ListList&lt;Object&gt;,这不是问题...
  • 如果由于某种原因您无法正确键入列表,您可以使用:results.stream().map(JSONObject.class::cast).forEach((JSONObject result)-&gt;{ … });。在标准的 Java API 中,没有超过两个参数的场景……

标签: java lambda java-8


【解决方案1】:

错误消息向您说明,从技术上讲,从编译器的角度来看,您的列表可能包含不属于 JSONObject 类的元素。因此你不能在这里使用Consumer&lt;JSONObject&gt;。 lambda (JSONObject result) -&gt; ... 实际上这样一个不兼容的消费者。

假设您无法控制 results 的元素类型,您可能只是在使用它们之前将元素映射到正确的类型。如果您期望的不仅仅是 JSONObject 元素,您可以使用 filter() 方法来忽略所有不兼容的元素并仅处理 JSONObject 实例。

results.filter(JSONObject.class::isInstance) // only needed if you expect non JSONObject elements, too
       .map(result -> (JSONObject) result)
       .forEach(result -> {
         result.put("test", "test"); 
         result.put("time", System.currentTimeMillis());  
         otherList.add(((JSONObject)result));
       });

【讨论】:

    【解决方案2】:

    正如在 cmets 下建议的 Fabian,您可能已经初始化了您的 results,例如 ListList&lt;Object&gt;

    你可以做的是,你可以拥有List&lt;JSONObject&gt;

    results.forEach(
                (result) ->
                {
                    result.put("test", "test"); 
                    result.put("time", System.currentTimeMillis());  
                    otherList.add(result);
                }
    

    【讨论】:

      【解决方案3】:

      您可以通过这样的方式使用流函数在一个步骤中进行类型转换,然后在后续步骤中进行查询-

          List<String> collect = Lists.newArrayList(obj.get("graph").getAsJsonObject().get("nodes").getAsJsonArray()).stream().
                      map(x -> (JsonObject) x).
                      map(x -> {
                          String res = "";
                          try {
                              res = CommonUtils.getAsString(x,"modelKey");
                          } catch (Exception e) {
                          }
                          return res;
                      }).collect(Collectors.toList());
      

      【讨论】:

      • 这与问题有什么关系?
      • 这种代码破坏了Java中类型安全的漏洞
      猜你喜欢
      • 1970-01-01
      • 2013-04-18
      • 2022-12-18
      • 1970-01-01
      • 2017-12-31
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      相关资源
      最近更新 更多