Извлечение многострочного лямбда-выражения при использовании ForEach при итерации карты в Java 8 - PullRequest
3 голосов
/ 02 июля 2019

Я повторяю карту, как показано ниже, используя Java 8 с forEach

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) Можем ли мы достичь этого?

Ответы [ 3 ]

3 голосов
/ 02 июля 2019

Я понимаю, что метод forEach в этом случае ожидает, что Consumer Functional Interface` имеет сигнатуру ниже

forEach() ожидает действительно Consumer, но для обработки Consumer выне нужно обязательно Consumer.Вам нужен метод, который учитывает ввод / вывод функционального интерфейса Consumer, то есть Entry<Integer,String> input / void output.

Таким образом, вы можете просто вызвать метод с параметром 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 ....");                        
}

Объявление Consumer<Map.Entry<Integer,String>>, которое вы передаете forEach(), такое как:

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

имеет смысл, только если потребитель в вашем forEach() предназначен для вариабельности в некоторомпуть (вычисляется / передается клиентом или в любом случае).
Если вы не в этом случае и используете Consumer, вы, наконец, сделали вещи более абстрактными и сложными, чем это фактически требуется.

1 голос
/ 02 июля 2019

Как насчет

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));
0 голосов
/ 02 июля 2019

Вы можете использовать ссылку на метод:

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 ....");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...