Как создать массив объектов generi c, который будет использоваться для таблицы Ha sh? - PullRequest
0 голосов
/ 03 августа 2020

Итак, у меня есть три класса HashTest , HashTable и HashObject . Цель HashTest - протестировать HashTable с использованием трех разных источников ввода: целых чисел, длинных чисел и строк.

В зависимости от того, какой источник указан, я создам HashTable соответственно, и начать вставку элементов.

В моем классе HashTable я должен использовать массив, который будет заполнен HashObjects данного типа. Моя проблема возникает, когда я пытаюсь создать массив и заполнить его объектами generi c. Первоначально я использовал следующее объявление в моем классе HashTable, чтобы попытаться создать массив HashObjects:

private HashObject<G>[] table = (HashObject<G>)new Object[95957];

который будет компилироваться с предупреждением о непроверенном приведении, однако, когда я запускаю, я получаю Выброшено исключение ClassCastException. Я не совсем уверен, почему я получаю это ClassCastException (точная ошибка ниже), но я знаю, что это как-то связано с тем фактом, что я объявляю массив типа generi c и пытаюсь привести инициализацию объекта к generi c тип. Пожалуйста, исправьте меня, если я ошибаюсь.

Сообщение ClassCastException

Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [LHashObject; ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; [LHashObject; is in unnamed module of loader 'app')
        at HashTable.<init>(HashTable.java:3)
        at HashTest.main(HashTest.java:28)

Во время экспериментов я изменил способ создания объекта HashTable в HashTest, так что параметр передано в HashTable >, а затем я объявляю массив G [] в HashTable и преобразую его в G [] в моей инициализации:

private G[] table = (G[])new Object[95957];

Это избавляет от моего ClassCastException, однако в дальнейшем в моем коде я не больше не могу использовать мои методы HashObject, потому что эти методы не существуют для «неопределенного» типа данных G.

((G)table[currIndex]).incrementDuplicates();

Вышеупомянутое не будет работать, потому что метод incrementDuplicates () «не определен для type G ".

Я прошу помощи: есть ли другой способ объявить этот массив, чтобы я мог хранить в нем HashObject, или есть другой способ вызвать метод HashObjects, а каждый элемент инициализируется как Object.

Ответы [ 3 ]

0 голосов
/ 03 августа 2020

Здесь несколько проблем ...

private HashObject<G>[] table = (HashObject<G>) new Object[95957];

Во-первых, вы должны выполнять приведение к (HashObject<G>[]) вместо (HashObject<G>). Во-вторых, приведение таких массивов не работает, поскольку тип массива инвариантен . Однако вы можете сделать следующее ...

@SuppressWarnings("unchecked")
private HashObject<G>[] table = new HashObject[95957];

Создание экземпляра массива в порядке, поскольку HashObject сам по себе не является общим c и преобразование между HashObject[] и HashObject<G>[] также работает, так как во время выполнения HashObject<G>[] стирается до HashObject[], т.е. они становятся одного типа.

0 голосов
/ 03 августа 2020

Вы получаете исключение приведения класса, потому что массив Object не может быть преобразован в массив HashObject, точно так же, как вы не можете взять экземпляр Object и преобразовать его в свой собственный класс.

Чтобы создать массив HashObject, используйте new HashObject[size]. С дженериками:

HashObject<G>[] table = (HashObject<G>[]) new HashObject<?>[95957];
0 голосов
/ 03 августа 2020

Краткий ответ: вы не можете .

Object - это supertype из HashObject, а не подтип, поэтому вы не можете добавить объект, созданный как Object в массив, объявленный как HashObject, независимо от того, что вы делаете. Если вы подумаете, что Object действительно может быть чем угодно, вы могли бы попытаться добавить Integer к массиву HashObject, что, очевидно, не может работать. Однако вы можете сделать наоборот. Вы можете объявить массив как массив Object и добавить экземпляры HashObject.

...