java 8 - [SonarLint]: make this anonymous inner class a lambda -
the below code works, have notification sonarlint because use anonymous class in stream instead of lambda expression, , don't see how improve below code avoiding notification:
properties prop = new properties(); properties temp = new properties(); //... add values , keys in prop , temp prop.putall(temp.entryset().stream() .filter( entry -> !prop.containskey(entry.getkey())) .map( new function<entry<object, object>, entry<string, string>>(){ @override public entry<string, string> apply(entry<object, object> entry) { return new entry<string, string>() { @override public string setvalue(string value) { return value.trim().tolowercase(); } @override public string getvalue() { return ((string) entry.getvalue()).trim().tolowercase(); } @override public string getkey() { return ((string) entry.getkey()).trim().tolowercase(); } }; } }) .collect(collectors.tomap(entry<string,string>::getkey, entry<string,string>::getvalue))); explication of code: use properties class java.util , unfortunately, entryset of properties returns entry<object, object>, not entry<string, string>. want "join" 2 properties objects putting key , value in lower case. so, map allows convert entry<object, object> in entry<string,string>. that's why, there anonymous class.
sonar suggesting replace
prop.putall(temp.entryset().stream() .filter( entry -> !prop.containskey(entry.getkey())) .map( new function<entry<object, object>, entry<string, string>>(){ @override public entry<string, string> apply(entry<object, object> entry) { return new entry<string, string>() { @override public string setvalue(string value) { return value.trim().tolowercase(); } @override public string getvalue() { return ((string) entry.getvalue()).trim().tolowercase(); } @override public string getkey() { return ((string) entry.getkey()).trim().tolowercase(); } }; } }) .collect(collectors.tomap(entry::getkey, entry::getvalue))); (i removed unnecessary type arguments in collector)
with
prop.putall(temp.entryset().stream() .filter( entry -> !prop.containskey(entry.getkey())) .map(entry -> new entry<string, string>() { @override public string setvalue(string value) { return value.trim().tolowercase(); } @override public string getvalue() { return ((string) entry.getvalue()).trim().tolowercase(); } @override public string getkey() { return ((string) entry.getkey()).trim().tolowercase(); } }) .collect(collectors.tomap(entry::getkey, entry::getvalue))); which uses lambda expression replacement anonymous inner class implementing function, not entry implementation.
still, doesn’t make sense implement entry interface manually here, not unwanted setvalue method in contract violating way. want immutable entry instance, therefore, can create instance of existing class instead:
prop.putall(temp.entryset().stream() .filter( entry -> !prop.containskey(entry.getkey())) .map(entry -> new abstractmap.simpleimmutableentry<>( ((string) entry.getkey()).trim().tolowercase(), ((string) entry.getvalue()).trim().tolowercase())) .collect(collectors.tomap(entry::getkey, entry::getvalue))); as last improvement, can rid of entry instance entirely, when performing transformation in functions passed tomap collector:
prop.putall(temp.entryset().stream() .filter( entry -> !prop.containskey(entry.getkey())) .collect(collectors.tomap( entry -> ((string) entry.getkey()) .trim().tolowercase(), entry -> ((string) entry.getvalue()).trim().tolowercase())));
Comments
Post a Comment