私は、行列の値を格納するためにLinkedList
の配列を使用するneedsというスパース行列クラスに取り組んでいます。配列の各要素(各LinkedList
)は、行列の行を表します。また、LinkedList
配列の各要素は列と格納された値を表します。
私のクラスでは、次のような配列の宣言があります。
private LinkedList<IntegerNode>[] myMatrix;
そして、SparseMatrix
のコンストラクターで、以下を定義しようとします:
myMatrix = new LinkedList<IntegerNode>[numRows];
私が得ることになったエラーは
LinkedList<IntegerNode>
の汎用配列を作成できません。
したがって、これには2つの問題があります。
IntegerNode
は私が作成したクラスです。そして、私のクラスファイルはすべて一緒にパッケージ化されています。
汎用配列の作成は使用できません。これは、Java generics。
警告なしの方法は次のとおりです。
リストの配列の代わりにリストのリストを使用する:
List< List<IntegerNode>> nodeLists = new LinkedList< List< IntegerNode >>();
リストの配列の特別なクラスの宣言:
class IntegerNodeList {
private final List< IntegerNode > nodes;
}
何らかの理由で、型をキャストし、次のように宣言する必要があります。
myMatrix = (LinkedList<IntegerNode>[]) new LinkedList<?>[numRows];
構文の問題は別として、配列とリンクリストを使用して行列を表すのは奇妙に思えます。マトリックスの任意のセルにアクセスできるようにするには、おそらく実際の配列または少なくともArrayList
が行を保持する必要があります。LinkedList
は最初の要素からリスト全体を横断する必要があるためArrayList
または実際の配列を使用した非常に高速のO(n)
とは対照的な、特定の要素、O(1)
操作。
ただし、このマトリックスはスパースであると述べたので、おそらくデータを格納するより良い方法は、マップのマップとしてです。最初のマップのキーは行インデックスを表し、その値はキーが列インデックスである行マップです、値は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
よりも高速です。もちろん、設定されていないnull値を処理する任意のセルを取得および設定するヘルパーメソッドは便利です。
class IntegerNodeList extends LinkedList<IntegerNode> {}
IntegerNodeList[] myMatrix = new IntegerNodeList[numRows];
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];
警告なしでコンパイルします。
見た目は悪くありませんか?
Java 1.5(または私が知る限り1.6))には一般的な配列の作成はありません。 https://community.Oracle.com/message/4829402 を参照してください。
List<String>[] lst = new List[2];
lst[0] = new LinkedList<String>();
lst[1] = new LinkedList<String>();
警告はありません。 NetBeans 6.9.1、jdk1.6.0_24
リストの配列が必要です。1つの選択肢は以下を試すことです:
_private IntegerNode[] node_array = new IntegerNode[sizeOfYourChoice];
_
次に、_node_array[i]
_は、_ArrayList<IntegerNode>
_または_LinkedList<IntegerNode>
_(好きなリストの実装が何であれ)のhead(first)ノードを格納します。
この設計では、ランダムアクセスメソッドlist.get(index)
は失われますが、タイプセーフ配列のヘッド/フィストノードストアからリストを走査することができます。
これは、ユースケースによっては許容できる設計の選択肢になる場合があります。たとえば、この設計を使用してグラフの隣接リストを表します。ほとんどのユースケースでは、リスト内の頂点にランダムにアクセスするのではなく、特定の頂点について隣接リストを走査する必要があります。
次の操作を行うと、問題のエラーメッセージが表示されます
LinkedList<Node>[] matrix = new LinkedList<Node>[5];
しかし、宣言からリストタイプを削除するだけで、目的の機能が得られるようです。
LinkedList<Node>[] matrix = new LinkedList[5];
これらの2つの宣言は、私が知らない方法で大幅に異なりますか?
[〜#〜] edit [〜#〜]
ああ、私は今この問題に遭遇したと思います。
Forループで行列を反復処理し、リストを初期化するとうまくいくようです。ただし、提供されている他のソリューションのいくつかほど理想的ではありません。
for(int i=0; i < matrix.length; i++){
matrix[i] = new LinkedList<>();
}