Лямбда-выражение java, параметр передачи - PullRequest
0 голосов
/ 07 июня 2019

У меня проблема с лямбда-выражениями в java.

List<String> l = new ArrayList<String>();
l.add("Besit");
l.add("Java");
String str = "Java";
boolean flag = false;
int counter = 0;
l.forEach((h) -> {
    if (h.equals(str)) {
        counter++;
        flag = true.
    }
});

Очевидно, у меня ошибка, потому что forEach не видит str и flag, я знаю, что в C ++ лямбда-выражения мы можемпередать некоторые параметры по ссылке.Возможно ли сделать это в Java?

Ответы [ 3 ]

4 голосов
/ 07 июня 2019

Вам следует подойти к проблеме по-другому, чтобы вам не нужно было обновлять flag в лямбде (хотя вы можете получить доступ к str):

boolean flag = l.stream().anyMatch(h -> h.equals(str));

Для вашего обновленного кода вы делаете это с:

int counter = (int) list.stream().filter(h -> h.equals(str)).count();
// or int counter = (int) list.stream().filter(h -> h.equals(str)).mapToInt(h -> 1).sum(); 
boolean flag = count > 0;
0 голосов
/ 07 июня 2019

Дело не в том, что str, counter и flag не видны, а в том, что они должны быть эффективно финальными, другими словами, код лямбды не может их изменить, что было бы верно в любом случае, потому что они передаются по значению и строка не может быть изменена. Вы можете создать другой объект с открытыми полями или методами получения / установки для различных интересующих вас величин, объявить экземпляр объекта как окончательный и передать его в ...

public class Stuff {

   public String str = "Java";
   public int counter = 0;
   public boolean flag = false;
}

final Stuff stuff = new Stuff();

l.forEach((h) -> {
    if (h.equals(stuff.str)) {
        stuff.counter++;
        stuff.flag = true.
    }
});
0 голосов
/ 07 июня 2019

@ Ответ AndyTurner верен, однако я хочу объяснить, почему вы не можете делать то, что пытались.

Лямбда может видеть переменные в содержащей области только в том случае, если они помечены как окончательные (или фактически являются окончательными).

Ваш String str по сути является окончательным, но вы не можете пометить boolean flag как окончательный, потому что хотите, чтобы ваша лямбда его изменила.

Один из способов обойти это - использовать окончательный AtomicBoolean вместо вашего boolean flag. Затем вы можете вызвать set() в AtomicBoolean, чтобы изменить содержащееся в нем значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...