2013-10-24 6 views
1

Есть ли способ сделать следующий код работы Java?Общий массив инициализации внутреннего класса в java

public class RandomizedQueue<Item> implements Iterable<Item> { 
    private static final int ARRAYSIZE = 8; // default array size 
    private Node[] nodeArray;    // contains pointers to the randomized nodes  
    private int size;      // current size of queue 

    private class Node 
    { 
     private Item item; 
     private Node next; 
     private Node previos; 
    } 

    @SuppressWarnings("unchecked") 
    public RandomizedQueue()   // construct an empty randomized queue 
    { 
     nodeArrays = (Node[]) new Object[ARRAYSIZE]; // fix this and everything works! 
    } 

    // unimportant randomized queue implementation details 
    // ... 
} 

Это происходит сбой во время выполнения при инициализации линии nodeArray со следующей ошибкой:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LRandomizedQueue$Node; at RandomizedQueue.<init>(RandomizedQueue.java:18) at Subset.main(Subset.java:6).

Проблема в том, что я не могу использовать структуры данных библиотек, такие как ArrayList <>, потому что у меня были пользовательские правила переразмера. Кроме того, я не могу реализовать аналог ArrayList сам (в моей задаче не разрешены дополнительные классы).

Код nodeArray = new Node[ARRAYSIZE]; не скомпилирован в Eclipse с ошибкой Cannot create a generic array of RandomizedQueue<Item>.Node.

+6

Почему не 'Node [] nodeArrays = новый узел [ARRAYSIZE ]; –

+1

Вы храните его как 'Node []', зачем его инициализировать как 'Object []'? –

+0

Если бы вы могли указать пользовательские правила изменения размера ArrayList, не могли бы вы его использовать? – Bohemian

ответ

0

См. Также параметризацию внутреннего класса.

class RandomizedQueue<Item> implements Iterable<Item> { 
private static final int ARRAYSIZE = 8; // default array size 
private Node[] nodeArray; // contains pointers to the randomized nodes 
private int size; // current size of queue 

private class Node<Item> { 
    private Item k; 
    private Node next; 
    private Node previos; 

} 

public RandomizedQueue() // construct an empty randomized queue 
{ 
    super(); 
    nodeArray = new Node[ARRAYSIZE]; 
} 

@Override 
public Iterator<Item> iterator() { 
    // TODO Auto-generated method stub 
    return null; 
} 
} 

Inner Class

+0

Не компилируется в Eclipse. Я тоже пробовал это, прежде чем спрашивать. – Seatless

+0

Я могу сделать это в Eclipse. См. Прикрепленный снимок экрана. –

+0

Да, скриншот помог мне решить мою проблему. Спасибо! – Seatless

0

Вы должны это делать.

Node[] nodeArrays = new Node[ARRAYSIZE]; 
+1

@kocko Это сработало бы, даже если 'Node' является интерфейсом. Конечно, вы можете создать массив интерфейса. Однако вы не можете заполнить его экземплярами интерфейса, а только классы, реализующие интерфейс. –

+0

Извините, мой плохой. :) –

0

Не создавать локальную переменную Node[] nodeArrays = (Node[]) new Object[ARRAYSIZE]; в RandomizedQueue() конструктора.

@SuppressWarnings("unchecked") 
public RandomizedQueue()   
{ 
    nodeArray = new Node[ARRAYSIZE]; Now This is fixed 
} 
+0

Я отредактировал мой вопрос, в первую очередь это была не локальная переменная. Кроме того, я попытался инициализировать мой массив таким образом, но он не компилируется в Eclipse: не удается создать общий массив RandomizedQueue .Node – Seatless

2

Ваша проблема заключается в следующем:

общественного класса RandomizedQueue реализует Iterable {
[...] частный класс Node { частного товара;

Во-первых, вы, вероятно, захотите использовать [статический] вложенный класс, а не внутренний класс. Item - общий параметр, который не является очевидным, потому что вы не используете стандартные соглашения о кодировании. Node нужен общий аргумент. Итак:

общественного класса RandomizedQueue реализует Iterable {
[...] частный статический класс Node { частный элемент U;

Итак, теперь вы хотите получить массив из этих Node<U>. Обычно я бы сказал, что использую List<Node<U>>, но я предполагаю, что вы пытаетесь сделать что-то вроде низкого уровня эффективности здесь. Поэтому нам нужно сделать изворотливый массив rawtype и бросить на generics.

 Node<T>[] nodeArrays = (Node<T>[])new Node[ARRAYSIZE]; 

Предполагая, что вы на самом деле хотите, чтобы назначить непосредственно на поле:

 nodeArrays = (Node<T>[])new Node[ARRAYSIZE]; 

Вероятно, лучший способ это сделать Node необщего, а затем бросили на «получает».

private static class Node { 
     [...] 
     Node[] nodeArrays = new Node[ARRAYSIZE]; 
    [...] 
    private T at(int index) { 
     return (T)nodeArrays[index]; 
    } 

BTW: Если вы собираетесь подавлять предупреждения, подавляйте только одну строку. Это может потребовать введения временной переменной.

+0

Это выглядит неплохо, но этот код не компилируется для меня в Eclipse. Работает ли это для вас? Возможно, я вас неправильно понял, поэтому, если у вас есть этот код, вы можете отправить мне личное сообщение (или здесь, если хотите) весь класс (с правильной внутренней идентификацией класса узла и инициализацией массива узла)? – Seatless

1

Node не является статическим внутренним классом, что означает, что в пределах объема общих параметров внешнего класса, и который также означает, что неявно параметризованные с наружным классом общие параметры.

Внутри RandomizedQueue, Node средства RandomizedQueue<Item>.Node. Это означает, что это параметризованный тип. Вы не можете создавать массивы параметризованных типов в Java. Вы можете создавать только массивы типов raw или шаблонов с параметрами подстановочных знаков.

Итак, каков необработанный тип Node? (Это не только Node, как я объяснял ранее.) Вы должны явно квалифицировать его с именем внешнего класса: RandomizedQueue.Node.

Таким образом, решение заключается в создании массива необработанного типа:

nodeArrays = (Node[]) new RandomizedQueue.Node[ARRAYSIZE]; 

или подстановочного-параметризованных типа:

nodeArrays = (Node[]) new RandomizedQueue<?>.Node[ARRAYSIZE]; 
Смежные вопросы