Nestor Milyaev Nestor Milyaev - 10 months ago 59
Java Question

Java8 lambda sequential or piped String transformation

I work on a JCR- based application, and my query breaks when it contains illegal characters.

So I've undertaken a really simple task: given a query string and a map containing a list of "dodgy" characters, sequentially replace those dodgy chars with allowed ones. I want to use lambdas, and am sadly a little bit stuck:

public static Map<String, String> DODGY_CHARS = getDodgyCharMapping();

static Map<String, String> getDodgyCharMapping(){
Map<String, String> map = new HashMap<>();
map.put("'", "''");
return map;

private String sanitizeQueryString(String query){
query = replaceCharacter(query, key, DODGY_CHARS.get(key));
return query;

The query variable inside the lambda is what J8 is not happy with, resulting in the following error:

error: local variables referenced from a lambda expression must be final or effectively final

Answer Source

The problem is that you're accessing the local variable query within the scope of the lambda expression's body. It therefore must be final or effectively final. However, declaring query as final would not solve the problem since you're assigning a value to it.

I would suggest you let the method replaceCharacter takes a StringBuilder and have it replace the contents instead of reading and re-assigning the String variable.