Home > Blockchain >  Sonarqube is giving HashMap initalization code compliant issue
Sonarqube is giving HashMap initalization code compliant issue

Time:05-02

I have this code where I am initializing this HashMap like:

final HashMap<String, String> propertiesValueMap = new HashMap<String, String>(){{
            put(SOME_STRING, SOME_STRING);
            put(SOME_STRING, SOME_STRING);
            put(SOME_STRING, SOME_STRING);
         }};

The above code is giving non complaint code issue in SonarQube. is there any other way by which i can initialize?

I know one way like

Stream.of(new String[][]{
            { SOME_STRING, SOME_STRING},{SOME_STRING, SOME_STRING}
    }).collect(Collectors.toMap(data->data[0],data->data[1]
    ));

But this will return me Map<String,String> and I want HashMap<String,String>.

CodePudding user response:

As Sonarsource saying:

Double Brace Initialization (DBI) is so obscure...

Double Brace Initialization should not be used

You could do something like

Map<String, String> propertiesValueMap = createMap();
 
private static Map<String, String> createMap() {
    Map<String, String> myMap = new HashMap<String, String>();
    myMap.put(SOME_STRING, SOME_STRING)
    return myMap;
}

Or, if you are creating an immutable Map and using Java 9 :

import static java.util.Map.entry;    

Map<String, String> propertiesValueMap = Map.ofEntries(
    entry("SOME_STRING", "SOME_STRING"),
    entry("SOME_STRING2", "SOME_STRING2")
);

CodePudding user response:

This issue arose because you are writing your code against concrete implementations. Which doesn't bays you anything. It only makes your code inflexible, more difficult to maintain, more verbose and less expressive. Consider reading this question What does it mean to "program to an interface"?.

In regard to Collectors.toMap() (which expects only two arguments) currently, it does return you a HashMap. And it is not specified, because sometime in the future it could be replaced with enhanced general purpose implementation that will better in some cases than HashMap. If you would write your code against Map interface instead of requesting a particular implementation (you can do it by using a flavor of toMap() that expects a supplier mapFactory), you would get an implementation for free without changing the code.

In regard to new HashMap<String, String>(){{ someCode }};, I suggest you to utilize Java 9 static methods of the Map interface Map.of() or Map.ofEntries() instead. It makes your code leaner and saves from disadvantages that double brace initialization can bring, like possibility of memory leaks, which might emerge because the anonymous inner class that it creates under the hood would hold reference to the instance of the enclosing class. That's why this practice is considered to be an antipattern.

  • Related