Как создать массив коллекции?
Возможный дубликат:
В чем причина, по которой я могу создать типичные типы массивов в Java?
HashSet<Integer>[] rows = new HashSet<Integer>[9];
дает ошибку компиляции: создание общего массива.
Ответы
Ответ 1
Простой ответ: не смешивать массивы с дженериками!
Используйте список хешсет:
ArrayList<HashSet<Integer>> rows = new ArrayList<HashSet<Integer>>();
Проблема в том, что спецификация Java не позволяет вам объявлять массив объектов generics.
Обходным путем является использование шаблона, но вы потеряете безопасность типа:
HashSet<?>[] rows = new HashSet<?>[9];
for (int i = 0; i < rows.length; ++i)
rows[i] = new HashSet<Integer>();
Это, в вашем случае, не создаст проблем, когда вы собираетесь проверять, содержится ли элемент: вы можете легко сделать rows[0].contains(4)
, но при добавлении нового содержимого вы будете вынуждены задавать строку в нужном типе и подавить предупреждение о неконтролируемом произведении:
((HashSet<Integer>)rows[0]).add(4);
Замечание: если вы чувствуете, что пионер просто загружает фреймворк Trove Collections, который имеет не-генерическую, высоко оптимизированную версию integer hashset, выполненный для работы с примитивным типом, я говорю о классе TIntHashSet
: он решит вашу проблему и вы получите быстрый код.
Ответ 2
Процитировать Эффективное Java Второе издание Джошуа Блоха, стр. 119
Из-за этих фундаментальных различия, массивы и дженерики не хорошо перемешать. Например, это Запретить создание массива тип общего типа, параметризованный тип или параметр типа. Ни один из этих массивов выражения создания являются законными: new
List<E>[], new List<String>[], new
E[]
. Все приведет к генерическому массиву ошибки создания во время компиляции.
Почему это незаконно, чтобы создать общий массив? Потому что он не является типичным. Если это были законные, броски, сгенерированные компилятор в противном случае программа может выйти из строя во время выполнения с ClassCastException
. Это нарушит основная гарантия, предоставляемая система общего типа.
(я пропустил часть, объясняющую стирание стираемого типа)
В главе "Общие" этой книги доступен как PDF.
Ответ 3
Вы можете объявить общий текст в объявлении типа, но не тогда, когда вы фактически выделите объект. Не уверен, какая именно причина, возможно, для повторного применения концепции о том, что некоторая информация генериков не сохраняется во время компиляции.
Set<Integer> rows[] = new HashSet[3];
for (int i = 0; i < rows.length; i++) {
rows[i] = new HashSet<Integer>();
}
Ответ 4
Всякий раз, когда вы цепляете дженерики или встраиваете такие структуры данных, пришло время сделать шаг назад и подумать о том, что вы действительно пытаетесь сделать.
Было бы лучше, если бы он был инкапсулирован в класс обертки? Вероятно, это может сделать вещи менее сложными позже. Через неделю, когда вам придется отлаживать что-то в вашем массиве хэш-массивов arraylists массивов какого-то простого типа данных, потому что вы думали, что просто продолжаете их обертывать, вам будет жаль.
-edit: массивы являются незаконными? Точка отметила. Я все еще чувствую, что аргумент здесь стоит.
Вы используете Java; не бойтесь делать некоторые дополнительные занятия.
public class MyIntegers {
private HashSet<Integer> theIntegers;
// wrap methods
public boolean add(Integer i) { return theIntegers.add(i); }
public boolean contains(Integer i)...
public boolean remove(Integer i)...
}
// later...
public static void main(String[] args) {
MyIntegers[] rows = new MyIntegers[NUM_ROWS];
}