【问题标题】:Extract Multiline Lambda Expression while using ForEach while iterating a Map in Java 8在 Java 8 中迭代 Map 时使用 ForEach 提取多行 Lambda 表达式
【发布时间】:2019-07-02 11:32:33
【问题描述】:

我正在使用 Java 8forEach 来迭代如下图

Map<Integer,String> testMap = new HashMap<>();
testMap.put(1, "Atul");
testMap.put(2, "Sudeep");
testMap.put(3, "Mayur");
testMap.put(4, "Suso");

testMap.entrySet().forEach( (K)-> {         
                System.out.println("Key ="+K.getKey()+" Value = "+K.getValue());
                System.out.println("Some more processing ....");            
            }

    );

我的问题是:

1) 在地图中处理时,我们如何从forEach 中提取方法?

2)也就是说forEach里面的代码部分应该被包裹在方法里面:

        System.out.println("Key ="+K.getKey()+" Value = "+K.getValue());
        System.out.println("Some more processing ....");    

3) 我理解在这种情况下 forEach 方法需要一个 Consumer 功能接口`,它具有以下签名 -

void accept(T t); 

4)所以我想要的是这样的:

   //declare a consumer object 
   Consumer<Map.Entry<Integer,String>> processMap = null;

  // and pass it to ForEach 
  testMap.entrySet().forEach(processMap);

5) 我们能做到这一点吗?

【问题讨论】:

    标签: java foreach java-8


    【解决方案1】:

    我了解这种情况下的 forEach 方法需要一个消费者 具有以下签名的功能接口

    forEach() 确实需要Consumer,但要处理Consumer,您不一定需要Consumer。您需要的是一种尊重Consumer功能接口的输入/输出的方法,即Entry&lt;Integer,String&gt;输入/void输出。

    所以你可以调用一个以Entry为参数的方法:

    testMap.entrySet().forEach(k-> useEntry(k)));
    

    testMap.entrySet().forEach(this::useEntry));
    

    用 useEntry() 如:

    private void useEntry(Map.Entry<Integer,String> e)){        
        System.out.println("Key ="+e.getKey()+" Value = "+e.getValue());
        System.out.println("Some more processing ....");                        
    }
    

    声明您传递给forEach()Consumer&lt;Map.Entry&lt;Integer,String&gt;&gt;,例如:

    Consumer<Map.Entry<Integer,String>> consumer = this::useEntry;
    //...used then :
    testMap.entrySet().forEach(consumer);
    

    仅当您的 forEach() 中的消费者被设计为以某种方式(由客户端计算/传递或无论如何)可变时才有意义。
    如果您不在这种情况下并且您使用消费者,那么您最终使事情变得比实际需要的更抽象和复杂。

    【讨论】:

    • 但是使用private void useEntry(Integer key, String value)testMap.forEach(this::useEntry); 比使用entrySet() 更具可读性。
    • @Holger 一如既往的好。谢谢。更具可读性:同意。更具可读性:我不会走这么远:)
    【解决方案2】:

    怎么样

    public void processMap(Map.Entry K){
      System.out.println("Key ="+K.getKey()+" Value = "+K.getValue());
      System.out.println("Some more processing ....");
    }
    

    然后像这样使用它:

    testMap.entrySet().forEach((K)-> processMap(K));
    

    【讨论】:

      【解决方案3】:

      您可以使用方法参考:

      Consumer<Map.Entry<Integer,String>> processMap = SomeClass::someMethod;
      

      其中方法定义为:

      public class SomeClass {
      
          public static void someMethod (Map.Entry<Integer,String> entry) {
              System.out.println("Key ="+entry.getKey()+" Value = "+entry.getValue());
              System.out.println("Some more processing ....");
          }
      
      }
      

      如果您愿意,您甚至可以使该方法更通用:

      public static <K,V> void someMethod (Map.Entry<K,V> entry) {
          System.out.println("Key ="+entry.getKey()+" Value = "+entry.getValue());
          System.out.println("Some more processing ....");
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-07
        • 2016-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-16
        • 1970-01-01
        相关资源
        最近更新 更多