Don't use double-brace initialization in BlockHound.java
leventov opened this issue · comments
Double-brace initialization is considered an anti-patten.
Desired solution
Many uses of double-brace initialization in BlockHound.java
could be replaced with Collections.singletonMap()
call; the rest, with more mundane code like
map = new HashMap<>();
map.put(...)
Or a small static factory dedicated for this purpose.
Thanks for submitting an issue.
I am aware that there are some cases where it may cause issues. However, unless one can prove our use of the double-brace initialisation harmful, I'm keen to keep it as is.
Just to give a bit of background and what motivated me to use them on a first place:
singletonMap
returns an immutable Map, while the maps we store are mutable and can be configured with the builder. One would need to wrap it withnew HashMap<>(singletonMap(...))
and it creates additional noisesingletonMap
works only for one key/value pair. Adding more blocking methods, for example, would require a rewrite.- We have a couple of imperative
if/else
that would be hard to use with a small static factory
Thus I would prefer to continue using the current approach. Feel free to re-open the issue if you still think there is anything harmful in it, e.g. it caused a memory leak or anything.
@bsideup why not use a helper method that accepts a supplier, consumer?
You could do it completely flexible with initMap
or if you only use HashMap
anyway use a more dedicated method hashMap
.
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
public class TestMap {
public static <K,V> Map<K,V> initMap(Supplier<Map<K,V>> creator, Consumer<Map<K,V>> initializer) {
Map<K,V> map = creator.get();
initializer.accept(map);
return map;
}
public static <K,V> Map<K,V> hashMap(Consumer<Map<K,V>> initializer) {
Map<K,V> map = new HashMap<>();
initializer.accept(map);
return map;
}
@Test
public void InitMapWithMultiArgs(){
Map<String,String> testMap = initMap(HashMap::new, map -> {
map.put("a", "b");
map.put("b", "c");
});
assertThat(testMap)
.containsEntry("a", "b")
.containsEntry("b", "c")
.hasSize(2);
}
@Test
public void HashMapWithMultiArgs(){
Map<String,String> testMap = hashMap(map -> {
map.put("a", "b");
map.put("b", "c");
});
assertThat(testMap)
.containsEntry("a", "b")
.containsEntry("b", "c")
.hasSize(2);
}
}
@leonard84 because it works already, there are no issues with the current approach, and I simply don't want to make a change for the sake of a change?