Sonarqube提供了符合概念的Hashmap Interization Inspory问题

发布于 2025-01-25 13:38:21 字数 663 浏览 3 评论 0 原文

我有此代码在其中初始化此 hashmap 类似:

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

以上代码在Sonarqube中提供了非投诉代码问题。 还有其他我可以初始化的方式吗?

我知道类似的方式

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

,但这会返回我 map&lt; string&gt; ,并且我想要 hashmap&lt; string,string&gt;

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>.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

带上头具痛哭 2025-02-01 13:38:21

正如Sonarsource所说:

双支架初始化(DBI)是如此晦涩……

双支架初始化不应使用

您可以做类似的事情

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;
}

,如果您要创建一张不变的地图并使用Java 9:

import static java.util.Map.entry;    

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

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")
);
东风软 2025-02-01 13:38:21

此问题之所以出现,是因为您正在编写针对具体实现的代码。什么都没托付你。它只会使您的代码不灵活,更难以维护,更详细和表现力较低。考虑阅读此问题对“对界面”的程序意味着什么”?

关于 collectors.tomap(),当前只期望两个参数),它确实返回您 hashmap 。并且没有指定它,因为将来的某个时候可以用增强的通用实现替换,在某些情况下,它会比 hashmap 更好。如果您要使用 MAP 接口而不是请求特定实现,则可以免费获得实现,而无需更改代码。

正如我提到的,您可以使用 tomap() >。

Collector<T,?,M> toMap(Function<? super T,? extends K> keyMapper,
                       Function<? super T,? extends U> valueMapper,
                       BinaryOperator<U> mergeFunction,
                       Supplier<M> mapFactory)

但是我的建议是在需要时使用它,例如特殊目的实现喜欢 linkedhashmap treemap feekedhashmap et。默认情况下,最佳当前通用实现(当前<代码> hashmap )将提供给您,只需针对接口编写代码,就可以了。

tomap 的这种风味的用法示例:

Map<String, String> result =
    list.stream()
          .collect(Collectors.toMap(
              data->data[0],
              data->data[1],
              (left, right) -> { throw new AssertionError(); }, // this argument is meant to resolve duplicates and because all keys are expected to be unique it'll trows an error if duplicate will occure
              LinkedHashMap::new));

关于 新的HashMap&lt; string,string&gt;(){{somecode}}}; ,我建议您使用Java 9 map 接口 map.ofentries() 而不是。它使您的代码更精细,并从双支支架初始化可以带来的缺点,就像内存泄漏的可能性一样,这可能会出现,因为它在引擎盖下创建的匿名内部类别会符合对实例的参考。封闭类。这就是为什么这种做法被认为是 antpattern 的原因。

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 an 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 would get an implementation for free without changing the code.

As I've mentioned, you can request a particular implementation of the Map interface by using a flavor of toMap() that expects a supplier mapFactory.

Collector<T,?,M> toMap(Function<? super T,? extends K> keyMapper,
                       Function<? super T,? extends U> valueMapper,
                       BinaryOperator<U> mergeFunction,
                       Supplier<M> mapFactory)

But my suggestion is to use it when need a special purpose implementation like LinkedHashMap, TreeMap, WeakedHashMap, etc. The best current general purpose implementation (which currently a HashMap) will be provided to you by default, just write your code against interfaces, and you'll be fine.

An example of usage of this flavor of toMap:

Map<String, String> result =
    list.stream()
          .collect(Collectors.toMap(
              data->data[0],
              data->data[1],
              (left, right) -> { throw new AssertionError(); }, // this argument is meant to resolve duplicates and because all keys are expected to be unique it'll trows an error if duplicate will occure
              LinkedHashMap::new));

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.

蓝颜夕 2025-02-01 13:38:21

从Java 9开始,定义固定 map&lt&lt; k,v&gt; 的最简单方法是仅使用 map.of(...) variants (或 ofentries 如果您需要10个以上的条目)。

Map<String, String> myMap = Map.of(
    KEY1, VALUE1,
    KEY2, VALUE2);

该人返回一个非特异性 map&lt&lt; k,v&gt; 虽然(即不能保证确切的类型,但结果的某些属性是) em> a hashmap 那么,最简​​单的方法就是将上述结果传递到 new Hashmap&gt;&gt;()

HashMap<String, String> myMap = new HashMap<>(Map.of(
    KEY1, VALUE1,
    KEY2, VALUE2));

虽然此 di em>创建两个地图(其中之一将很快被垃圾收集),我认为这是可以接受的缺点,因为您避免创建一个仅仅用于初始化某些值的全新类。

Starting with Java 9, the easiest way to define a fixed Map<K,V> is to just use one of the Map.of(...) variants (or ofEntries if you need more than 10 entries).

Map<String, String> myMap = Map.of(
    KEY1, VALUE1,
    KEY2, VALUE2);

That one returns a non-specific Map<K,V> though (i.e. the exact type is not guaranteed, but some properties of the result are), so if you need a HashMap then the easiest way is to just pass the result of the above to new HashMap<>():

HashMap<String, String> myMap = new HashMap<>(Map.of(
    KEY1, VALUE1,
    KEY2, VALUE2));

While this does create two maps (one of which will quickly be garbage-collected), I consider this an acceptable drawback, given that you avoid creating a whole new class just for initializing some values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文