Использование и переопределение переменной в методе forEach класса Stream
Как можно sql зариплейсить в стриме форич? Мне подчеркивает "variable used in lambda should be final"
Strong sql = "select * from #table#";
listMacros.forEach(macros ->
{
if(macros.contains(entity.getMacros()) && !"".equals(entity.getEntityIdValue())) {
sql = sql.replace(macros, entity.getEntityIdValue());
return;
} else if(macros.contains(entity.getMacros()) && "".equals(entity.getEntityIdValue())) {
sql = sql.replace(macros, entity.getEntityName());
return;
}
})
Ответы (2 шт):
Через метод forEach нельзя, поскольку переменные, используемые в лямбда-выражении, не должны изменяться. Чтобы решить эту проблему, просто не используйте лямбда-выражение. Вместо этого вы можете использовать цикл foreach:
for (Macros macros : listMacros) {
// your code here
}
Однако следует знать, что в этом случае вы не можете изменить объекты итерируемой коллекции. Если же вам нужно их изменить, вы можете использовать итератор:
for (Iterator<Macros> iterator; iterator.hasNext(); ) {
Macros macros = iterator.next();
// your code here
}
Думаю, можно использовать Stream::reduce. Примерный код:
String sql = "select * from #table#";
String processedSql = macrosList.stream().reduce(sql, (s, m) -> processMacro(s, m, entity));
где
static String processMacro(String sql, String macro, Entity entity) {
if (macro.contains(entity.getMacros())) {
if (!"".contentEquals(entity.getEntityIdValue())) {
return sql.replace(macro, entity.getEntityIdValue());
} else if ("".contentEquals(entity.getEntityIdValue())) {
return sql.replace(macro, entity.getEntityName());
}
}
return sql;
}
Если у вас не будут при замене появляться новые макросы, должно работать. В общем случае нужно понимать, какие требования накладываются на функцию, используемую в reduce.