116

我正在尝试构建一个 HashMap,它将整数作为键,对象作为值。

我的语法是:

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

但是,返回的错误是 - 标记“int”上的语法错误,此标记后预期的维度 - 我不明白为什么我应该添加一个维度(即:将 int 变成一个数组),因为我只需要存储一个数字作为关键。

我能做什么?

提前致谢!:)

4

12 回答 12

149

改为使用Integer

HashMap<Integer, MyObject> myMap = new HashMap<Integer, MyObject>();

Java 会自动将int原始值自动装箱为Integer对象。

从 Oracle Java 文档中阅读有关自动装箱的更多信息。

于 2013-04-22T13:41:11.600 回答
45

对于为 Android 设备编写 Java 并最终在这里结束的每个人:使用SparseArray以获得更好的性能;

private final SparseArray<myObject> myMap = new SparseArray<myObject>();

有了这个,您可以使用 int 而不是 Integer 之类的;

int newPos = 3;

myMap.put(newPos, newObject);
myMap.get(newPos);
于 2013-12-08T15:06:01.847 回答
28

您不能使用原语,因为 HashMap 在内部使用对象作为键。所以你只能使用继承自 Object 的对象(即任何对象)。

那是 HashMap 中的函数 put(),正如你所看到的,它使用 Object for K:

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

表达式“k = e.key”应该很清楚。

我建议使用像 Integer 和 autoboxing 这样的包装器。

于 2013-04-22T14:02:46.830 回答
5

您可以尝试使用 Trove http://trove.starlight-systems.com/
TIntObjectHashMap 可能是您正在寻找的。

于 2013-12-18T09:55:36.623 回答
4

HashMap 不允许原始数据类型作为参数。它只能接受对象,所以

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

不管用。

您必须将声明更改为

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

所以即使您执行以下操作

myMap.put(2,myObject);

原始数据类型自动装箱为 Integer 对象。

8 (int) === boxing ===> 8 (Integer)

您可以在此处阅读有关自动装箱的更多信息http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

于 2013-04-22T14:04:37.200 回答
4

HashMap不允许原语作为键的主要原因是 HashMap 的设计方式是为了比较键,它使用equals()方法,并且只能在对象上调用方法,而不是在原语上。

因此,当 int 自动装箱为 Integer 时,Hashmap 可以在 Integer 对象上调用equals()方法。

这就是为什么你应该使用整数而不是整数。我的意思是 hashmap 在将 int 作为键时抛出错误(不知道抛出的错误的含义)

如果您认为,您可以通过将原语作为键来提高 Map 性能,有一个名为FastUtil的库,其中包含一个以 int 类型作为键的 Map 实现。

正因为如此,它比Hashmap 快得多

于 2015-09-30T12:32:41.820 回答
3

如果您在 Android 中编码,则存在SparseArray,将整数映射到对象。

于 2013-08-28T07:06:23.000 回答
3

对于那些对此类地图感兴趣的人,因为您想减少Java 中对原始类型的包装器的自动装箱占用,我建议使用 Eclipse 集合Trove 不再受支持,我相信从这个意义上说它是非常不可靠的库(尽管它仍然很受欢迎)并且无法与Eclipse 集合相提并论。

import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap;

public class Check {
    public static void main(String[] args) {
        IntObjectHashMap map = new IntObjectHashMap();

        map.put(5,"It works");
        map.put(6,"without");
        map.put(7,"boxing!");

        System.out.println(map.get(5));
        System.out.println(map.get(6));
        System.out.println(map.get(7));
    }
}

在上面的这个例子中 IntObjectHashMap

当您需要int->object映射时,还要考虑使用YourObjectType[]数组或List<YourObjectType>按索引访问值(因为 map 本质上是一个关联数组)。

于 2020-06-04T12:35:00.647 回答
1

将 int 用作 Object 而不是原始类型

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();
于 2013-04-22T13:42:01.210 回答
1

如果您正在使用 Netty 并希望使用带有原始 int 类型键的映射,您可以使用它的IntObjectHashMap

使用原始类型集合的一些原因:

  • 通过使用专门的代码来提高性能
  • 减少对 GC 造成压力的垃圾

专业集合与通用集合的问题可以决定具有高吞吐量要求的程序的成败。

于 2020-12-10T23:00:48.620 回答
0

请用 HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

于 2013-04-22T13:42:39.370 回答
0

我不明白为什么我应该添加一个维度(即:将 int 变成一个数组),因为我只需要存储一个数字作为键。

数组也是一个对象,因此HashMap<int[], MyObject>使用 int 数组作为键的有效构造也是如此。

编译器不知道您想要什么或需要什么,它只是看到一个几乎正确的语言结构,并警告缺少什么以使其完全正确。

于 2017-12-05T06:39:31.950 回答