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

Не удается создать массив LinkedLists в Java...?

Я работаю над разреженным матричным классом, которому требуется, чтобы использовать массив LinkedList для хранения значений матрицы. Каждый элемент массива (т.е. Каждый LinkedList) представляет собой строку матрицы. И каждый элемент массива LinkedList представляет столбец и сохраненное значение.

В моем классе у меня есть объявление массива как:

private LinkedList<IntegerNode>[] myMatrix;

И, в моем конструкторе для SparseMatrix, я пытаюсь определить:

myMatrix = new LinkedList<IntegerNode>[numRows];

Ошибка, которую я получаю, составляет

Невозможно создать общий массив LinkedList<IntegerNode>.

Итак, у меня есть две проблемы:

  • Что я делаю неправильно, и
  • Почему допустимый тип объявления для массива, если он не может быть создан?

IntegerNode - это класс, который я создал. И все мои файлы классов упакованы вместе.

4b9b3361

Ответ 1

Вы не можете использовать создание общего массива. Это недостаток дженериков java.

Способы без предупреждений:

  • Использование списка списков вместо массива списков:

    List< List<IntegerNode>> nodeLists = new LinkedList< List< IntegerNode >>();
    
  • Объявление специального класса для массива списков:

    class IntegerNodeList {
        private final List< IntegerNode > nodes;
    }
    

Ответ 2

По какой-то причине вам нужно указать тип и сделать объявление следующим образом:

myMatrix = (LinkedList<IntegerNode>[]) new LinkedList<?>[numRows];

Ответ 3

Помимо проблем с синтаксисом, мне кажется странным использовать массив и связанный список для представления матрицы. Чтобы иметь доступ к произвольным ячейкам матрицы, вам, вероятно, понадобится фактический массив или, как минимум, ArrayList для хранения строк, поскольку LinkedList должен пересечь весь список из первого элемента в какой-либо конкретный элемент, O(n), а не намного быстрее O(1) с ArrayList или фактическим массивом.

Поскольку вы упомянули, что эта матрица разрежена, хотя, возможно, лучший способ хранения данных - это карта карт, где ключ на первой карте представляет собой индекс строки, а его значение представляет собой карту строк, ключи которой индекс столбца со значением, являющимся вашим классом IntegerNode. Таким образом:

private Map<Integer, Map<Integer, IntegerNode>> myMatrix = new HashMap<Integer, Map<Integer, IntegerNode>>();

// access a matrix cell:
int rowIdx = 100;
int colIdx = 30;
Map<Integer, IntegerNode> row = myMatrix.get(rowIdx); // if null, create and add to matrix
IntegerNode node = row.get(colIdx); // possibly null

Если вам нужно пройти по строке по строке, вы можете сделать тип карты строк TreeMap, а также для перемещения столбцов в индексном порядке, но если вам не нужны эти случаи, HashMap быстрее, чем TreeMap. Разумеется, полезны методы-помощники для получения и установки произвольной ячейки, обрабатывающие ненулевые значения.

Ответ 4

myMatrix = (LinkedList<IntegerNode>[]) new LinkedList[numRows];

литье этого способа работает, но все же оставляет вам неприятное предупреждение:

"Тип безопасности: выражение типа List [] требует необработанного преобразования.."

Объявление специального класса для массива списков:

class IntegerNodeList { private final List< IntegerNode > nodes; }

- умная идея, чтобы избежать предупреждения. возможно, немного лучше использовать интерфейс для него:

public interface IntegerNodeList extends List<IntegerNode> {}

затем

List<IntegerNode>[] myMatrix = new IntegerNodeList[numRows];

компилируется без предупреждений.

не выглядит слишком плохо, не так ли?

Ответ 5

class IntegerNodeList extends LinkedList<IntegerNode> {}

IntegerNodeList[] myMatrix = new IntegerNodeList[numRows]; 

Ответ 7

List<String>[] lst = new List[2];
lst[0] = new LinkedList<String>();
lst[1] = new LinkedList<String>();

Никаких предупреждений. NetBeans 6.9.1, jdk1.6.0_24

Ответ 8

Если я сделаю следующее, я получаю соответствующее сообщение об ошибке

LinkedList<Node>[] matrix = new LinkedList<Node>[5];

Но если я просто удалю тип списка в объявлении, он, кажется, имеет желаемую функциональность.

LinkedList<Node>[] matrix = new LinkedList[5];

Являются ли эти два объявления радикально разными, каким образом я не знаю?

ИЗМЕНИТЬ

А, думаю, я столкнулся с этой проблемой сейчас.

Итерация по матрице и инициализация списков в for-loop, похоже, сработают. Хотя это не так идеально, как некоторые другие предлагаемые решения.

for(int i=0; i < matrix.length; i++){

    matrix[i] = new LinkedList<>();
}

Ответ 9

Вам нужен массив List, один из вариантов - попробовать:

private IntegerNode[] node_array = new IntegerNode[sizeOfYourChoice];

Затем node_array[i] хранит головку (первая) node ArrayList<IntegerNode> или LinkedList<IntegerNode> (независимо от вашей избранной реализации списка).

В соответствии с этой конструкцией вы потеряете метод произвольного доступа list.get(index), но затем вы можете по-прежнему перемещаться по списку, начиная с хранилища head/fist node в безопасном массиве типов.

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