76

可能重复:
在 Java 集合中存储原始值?

在java中,当我使用以下内容时: -

public HashMap<char, int> buildMap(String letters)
{
    HashMap<char, int> checkSum = new HashMap<char, int>();

    for ( int i = 0; i < letters.length(); ++i )
    {
        checkSum.put(letters.charAt(i), primes[i]);
    }

    return checkSum;
}

我收到与不适当类型有关的错误。我分别使用 Character 和 Integer 而不是 char 和 int 解决了我的问题。但是,我无法弄清楚为什么 HashMap 无法处理原始数据类型。

4

7 回答 7

139

泛型参数只能绑定引用类型,不能绑定原始类型,所以需要使用对应的包装类型。试试HashMap<Character, Integer>吧。

但是,我无法弄清楚为什么 HashMap 无法处理原始数据类型。

这是由于类型擦除。Java 从一开始就没有泛型,所以 aHashMap<Character, Integer>真的是HashMap<Object, Object>. 编译器会进行一系列额外的检查和隐式转换,以确保您不会输入错误类型的值或输出错误类型,但在运行时只有一个HashMap类并且它存储对象。

其他语言“专门化”类型,因此在 C++ 中,a 与内部的 avector<bool>非常不同vector<my_class>,它们不共享通用vector<?>的超类型。Java 定义了一些东西,因此 aList<T> 是 a List不管什么T是为了向后兼容预通用代码。这种向后兼容要求必须有一个用于泛型类型的所有参数化的单个实现类,这阻止了允许泛型参数绑定到基元的模板特化。

于 2012-11-04T05:32:16.907 回答
14

泛型不能以关键字的形式使用原始类型。

利用

public HashMap<Character, Integer> buildMap(String letters)
{
    HashMap<Character, Integer> checkSum = new HashMap<Character, Integer>();

    for ( int i = 0; i < letters.length(); ++i )
    {
        checkSum.put(letters.charAt(i), primes[i]);
    }

    return checkSum;
}

更新:在 Java 7 及更高版本中,您可以使用菱形运算符。

HashMap<Character, Integer> checkSum = new HashMap<>();
于 2012-11-04T05:33:43.440 回答
3

泛型只支持对象类型,不支持原语。与 C++ 模板不同,泛型不涉及代码生成,并且无论您使用多少泛型类型,都只有一个 HashMap 代码。

Trove4J通过预先生成选定的集合来使用原语并支持TCharIntHashMapMap<Character, Integer>来解决这个问题,如果需要的话可以包装它来支持。

TCharIntHashMap:char 键和 int 值的开放寻址 Map 实现。

于 2012-11-04T08:18:59.117 回答
2

Hashmaps 只能使用classes,不能primitives。这个来自programmerinterview.com 的页面可能有助于指导您找到答案。老实说,我自己并没有详细弄清楚这个问题的答案。

于 2012-11-04T05:32:52.333 回答
2

您不能将原始类型放入集合中。但是,只要装箱允许,您可以使用它们相应的对象包装器声明它们并仍然添加原始值。

于 2012-11-04T05:33:54.227 回答
2

泛型集合类不能与原语一起使用。请改用 Character 和 Integer 包装类。

Map<Character , Integer > checkSum = new HashMap<Character, Integer>();

于 2012-11-04T05:34:33.127 回答
2

Generics只能使用Wrapper类来定义。如果您不想使用 Wrapper 类型进行定义,您可以使用下面的 Raw 定义

@SuppressWarnings("rawtypes")
public HashMap buildMap(String letters)
{
    HashMap checkSum = new HashMap();

    for ( int i = 0; i < letters.length(); ++i )
    {
       checkSum.put(letters.charAt(i), primes[i]);
    }
    return checkSum;
}

或者使用包装类型定义 HashMap,并存储原始类型。原始值将被提升为它们的包装器类型。

public HashMap<Character, Integer> buildMap(String letters)
{
  HashMap<Character, Integer> checkSum = new HashMap<Character, Integer>();

  for ( int i = 0; i < letters.length(); ++i )
  {
    checkSum.put(letters.charAt(i), primes[i]);
  }
  return checkSum;
}
于 2012-11-04T05:35:32.300 回答