Подтвердить что ты не робот

Как создать экземпляр массива карт в Java?

Я могу объявить массив карт с помощью дженериков, чтобы указать тип карты:

private Map<String, Integer>[] myMaps;

Однако я не могу понять, как правильно его создать:

myMaps = new HashMap<String, Integer>[count]; // gives "generic array creation" error
myMaps = new HashMap[count]; // gives an "unchecked or unsafe operation" warning
myMaps = (Map<String, Integer>[])new HashMap[count]; // also gives warning

Как я могу создать экземпляр этого массива карт без получения компиляции или предупреждения?

Update:

Спасибо всем за ваши ответы. Я закончил с предложением List.

4b9b3361

Ответ 1

Не строго ответ на ваш вопрос, но рассмотрели ли вы вместо этого List?

List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());

кажется, работает нормально.

См. Теория и практика Java: Generics gotchas для подробного объяснения того, почему смешивание массивов с дженериками не рекомендуется.

Обновление:

Как упоминалось в комментариях Дрю, было бы лучше использовать Collection вместо List. Это может пригодиться, если вам когда-либо понадобится перейти на Set или один из других подинтерфейсов Collection. Пример кода:

Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());

В этой начальной точке вам нужно будет только изменить HashSet на ArrayList, PriorityQueue или любой другой класс, который реализует Collection.

Ответ 2

Вы не можете безопасно создать общий массив. Effective Java 2nd Edition подробно описывается в главе "Обобщения". Начните с последнего абзаца на странице 119:

Почему незаконно создавать общий массив? Потому что это не безопасно. Если это было законно, слепки, порожденные компилятор в противном случае правильно Программа может завершиться с ошибкой во время выполнения с ClassCastException. Это нарушит основная гарантия, предоставляемая универсальная система типов.

Чтобы сделать это более конкретным, рассмотрим следующий фрагмент кода:

// Why generic array creation is illegal - won't compile!
List<String>[] stringLists = new List<String>[1]; // (1)
List<Integer> intList = Arrays.asList(42); // (2)
Object[] objects = stringLists; // (3)
objects[0] = intList; // (4)
String s = stringLists[0].get(0); // (5)

Давайте представим, что строка 1, которая создает общий массив, является законным. Строка 2 создает и инициализирует List<Integer>, содержащий один элемент. Линия 3 хранит List<String> массив в Object переменная массива, которая является законной, потому что массивы ковариантны. Линия 4 магазина List<Integer> в подошву элемент массива Object, который удается, потому что дженерики реализовано erasure: среда выполнения тип экземпляра List<Integer> просто List, и тип времени выполнения Экземпляр List<String>[] - это List[], поэтому это назначение не генерирует ArrayStoreException. Сейчас были в беда. Мы сохранили List<Integer> экземпляр в массив, который объявлен только для хранения List<String> экземпляров. В строке 5 мы получаем единственный элемент из единственного списка в этот массив. Компилятор автоматически преобразует полученный элемент в String, но это Integer, поэтому мы получаем ClassCastException во время выполнения. В чтобы этого не случилось, строка 1 (которая создает общий массив) генерирует ошибку во время компиляции.

Поскольку массивы и обобщенные элементы плохо сочетаются (как и по другим причинам), лучше использовать объекты Collection (в частности, объекты List), а не массивы.

Ответ 3

В общем, не рекомендуется смешивать генераторы и массивы в Java, лучше использовать ArrayList.

Если вы должны использовать массив, лучшим способом справиться с этим является создание массива (ваш пример 2 или 3) в отдельном методе и аннотирование его с помощью @SuppressWarnings ( "unchecked" ).

Ответ 4

Короткий ответ кажется, что вы действительно просто не можете.

Обратите внимание на следующее. http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/

Один из комментариев к блогу гласит, что:

Собственно, инженеры сделали создание такого массива незаконным. Таким образом, создание массива из родового класса завершается с ошибкой. Метод Collection.toArray, за которым следует Cast в массив, работает во время компиляции.

Это не решает проблему, что ArrayStoreCheck не может быть выполнен во время выполнения, но вы можете создать массив генериков таким образом.

Как было предложено Биллом Ящерицей, вам, вероятно, лучше использовать

List<Map<String,Integer>>

Ответ 5

Вы можете создать общий массив карты

  • Создайте список карт.

     List<Map<String, ?>> myData = new ArrayList<Map<String, ?>>();
    
  • Инициализировать массив.

     Map<String,?>[]myDataArray=new HashMap[myData .size()];
    
  • Заполнение данных в массиве из списка.

     myDataArray=myData.toArray(myDataArry);
    

Ответ 6

Я знаю, что уже поздно отвечать, но я нашел этот обходной путь полезным для моего случая... Надеюсь, это поможет!

Используйте массив HashMap для хранения HashMaps.

public static void main(String[] args) {
    HashMap[] arr = new HashMap[1];//creating an array of size one..just for sake of example
    HashMap<String, String> arrMap = new HashMap<String, String>();

    //use loops to store desired key-value pairs into the HashMap which will be stored inside the array
    arrMap.put("ABC", "Name");

    //use loop to store your desired hashMap into the array at a particular index
    arr[0] = arrMap;

    //desired manipulation of the stored array.
    System.out.println(arr[0]);
}

Ответ 8

myMaps = new HashMap<String, Integer>[10]();

Чтобы неправильно

Почему бы не создать список карт вместо того, чтобы пытаться создать массив?

List<Map<String, Integer>> mymaps = new ArrayList<Map<String, Integer>>(count);