В java8, как установить глобальное значение в блоке lambdas foreach?
public void test(){
String x;
List<String> list=Arrays.asList("a","b","c","d");
list.forEach(n->{
if(n.equals("d"))
x="match the value";
});
}
1. Как и код выше, я хочу установить значение переменной рядом с блоком foreach, может ли он работать?
2. И почему?
3. Итератор foreach в порядке или беспорядке?
4. Я думаю, что блок lamdas foreach классный и простой для итератора, но это действительно сложная задача, а не одна и та же работа в java 7 или раньше.
Ответы
Ответ 1
Вы могли бы, конечно, "сделать внешнее значение изменчивым" с помощью трюка:
public void test() {
String[] x = new String[1];
List<String> list = Arrays.asList("a", "b", "c", "d");
list.forEach(n -> {
if (n.equals("d"))
x[0] = "match the value";
});
}
Приготовьтесь к избиению функциональным пуристом в команде. Однако гораздо приятнее использовать более функциональный подход (похожий на подход Sleiman):
public void test() {
List<String> list = Arrays.asList("a", "b", "c", "d");
String x = list.stream()
.filter("d"::equals)
.findAny()
.map(v -> "match the value")
.orElse(null);
}
Ответ 2
Ответ 3
В дополнение к уже предоставленным идиоматическим примерам, другой взлом должен был бы использовать AtomicReference, но я бы рекомендовал его, только если вам нужно "forEach" и предпочитайте что-то более читаемое, чем функционально-функциональный вариант:
public void test(){
AtomicReference<String> x = new AtomicReference<>();
List<String> list= Arrays.asList("a", "b", "c", "d");
list.forEach(n->{
if(n.equals("d"))
x.set("match the value");
});
}
Ответ 4
Как уже объяснялось, вы не можете изменить локальную переменную внешнего метода из тела лямбда (а также из тела анонимного класса). Мой совет - не пытайтесь использовать лямбды, когда они совершенно не нужны. Ваша проблема может быть решена следующим образом:
public void test(){
String x;
List<String> list = Arrays.asList("a","b","c","d");
if(list.contains("d"))
x = "match the value";
}
В общем, lambdas дружат с функциональным программированием, где у вас редко есть изменяемые переменные (каждая переменная назначается только один раз). Если вы используете лямбды, но продолжаете думать в императивном стиле, у вас всегда будут такие проблемы.