【问题标题】:Suspicious call to 'LinkedHashMap.get'对“LinkedHashMap.get”的可疑调用
【发布时间】:2022-01-25 11:11:31
【问题描述】:

您好,我有以下代码

public static LinkedHashMap<Object, String[]> dataMap = new LinkedHashMap<>();

public static void parseDataset(int line){
  String[] dataArr = dataMap.get(dataMap.keySet().toArray()[line]);
}

由于我用作 Key 的 Object 是动态生成的,我对此一无所知,所以我必须先找到它,然后才能使用它来获取它的值。

此代码向我发出警告Suspicious call to 'LinkedHashMap.get',这是个问题吗?我该如何消除警告?

【问题讨论】:

  • Since the Object I use as a Key is dynamically generated I have no knowledge about it - 如果您对此一无所知,您怎么知道它正确地覆盖了equalshashCode?如果不是,则不应将其用作 HashMap 中的键。
  • @Eran 对于代码的这个特定部分,我并不总是了解它,我确实为我的代码的不同部分覆盖了 equals 和 hashcode。
  • 只是为了回答 为什么会有问题? 因为LinkedHashMap.get() 的复杂度是 O(n),而其他实现的复杂度是 O(1) 或 O(log(n)) .

标签: java hashmap linkedhashmap


【解决方案1】:

您不需要使用get:不要将键转换为数组,而是使用values()。这是因为values() 的迭代顺序与对应的keys() 相同:

String[] dataArr = (String[]) dataMap.values().toArray()[line];

但是你也不需要使用toArray(),它浪费了一个包含所有值的数组,你只需要一个:你可以遍历这些值来获得你想要的东西:

static String[] nthItem(int n) {
  int i = 0;
  for (String[] value : dataMap.values()) {
    if (i == n) return value;
    ++i;
  }
  throw new ArrayIndexOutOfBoundsException();
}

或者:

String[] dataArr = dataMap.values().stream().skip(line).findFirst().orElseThrow();

(这类东西的现有实现可以在常用库中找到,例如Guava's Iterables.get

【讨论】:

  • 如果get不能可靠使用,LinkedHashMap根本不应该使用。
  • values() 返回作为键的对象而不是数组,这将是值和我想要得到的。
  • @oneandonlyk 所以名为values() 的方法返回密钥?
  • @Kayaman 是的,如果我像第一个示例代码一样编写它。
  • @oneandonlyk keySet() 是否会为您返回 Set 的值? :)
猜你喜欢
  • 2016-01-11
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 2013-09-09
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多