Hashmap не работает с int, char
Возможный дубликат:
Сохранение примитивных значений в коллекции 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 не справляется с примитивными типами данных.
Ответы
Ответ 1
Общие параметры могут привязываться только к ссылочным типам, а не к примитивным типам, поэтому вам необходимо использовать соответствующие типы обёртки. Вместо этого попробуйте HashMap<Character, Integer>
.
Однако мне трудно понять, почему HashMap не справляется с примитивными типами данных.
Это связано с стиранием типа. У Java не было дженериков с самого начала, поэтому HashMap<Character, Integer>
действительно является HashMap<Object, Object>
. Компилятор выполняет кучу дополнительных проверок и неявных бросков, чтобы убедиться, что вы не ввели неправильный тип значения или не получили неправильный тип, но во время выполнения существует только один класс HashMap
и он хранит объекты.
Другие языки "специализируют" типы, поэтому в С++ a vector<bool>
сильно отличается от vector<my_class>
внутри, и они не имеют общего типа vector<?>
супер-типа. Java определяет вещи, хотя для List<T>
является List
, независимо от того, что T
для обратного совместимость с предварительным кодом. Это требование обратной совместимости о том, что должен быть один класс реализации для всех параметризаций общего типа, не позволяет тип специализации шаблона, который позволяет связывать общие параметры с примитивами.
Ответ 2
Дженерики не могут использовать примитивные типы в форме ключевых слов.
использование
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 и более поздними версиями вы можете использовать оператор diamond.
HashMap<Character, Integer> checkSum = new HashMap<>();
Ответ 3
Generics поддерживает только типы объектов, а не примитивы. В отличие от шаблонов С++, генерики не связаны с генерацией кода, и существует только один код HashMap независимо от количества его общих типов.
Trove4J обойдется в этом, предварительно создав выбранные коллекции, чтобы использовать примитивы и поддерживает TCharIntHashMap, который можно обернуть для поддержки Map<Character, Integer>
, если вам нужно.
TCharIntHashMap: открытая адресная реализация Map для ключей char и значений int.
Ответ 4
Hashmaps могут использовать только classes
, а не primitives
. Эта страница из programmerinterview.com может быть полезной для указания ответа. Честно говоря, я сам не выяснил ответ на эту проблему.
Ответ 5
Вы не можете вводить примитивные типы в коллекции. Тем не менее, вы можете объявить их, используя их соответствующие обертки объектов, и все еще добавлять примитивные значения, если позволяет бокс.
Ответ 6
Общие классы коллекции не могут использоваться с примитивами. Вместо этого используйте классы оболочки символов и целого.
Map<Character , Integer > checkSum = new HashMap<Character, Integer>();
Ответ 7
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;
}