2017-05-17 29 views
0

これは一般的な問題であればどこでも見つけるのは難しいですが、本質的にカスケード型の問題を扱っています。Javaの汎用型宣言の継承

public class Graph<E> { 

    private LinkedList<Node<E>> nodes; 

    public Graph() { 
     this.nodes = new LinkedList<>(); 
    } 

    public E[] getNodes() { 
     ArrayList<E> list = new ArrayList<>(); 
     for (Node<E> node : nodes) 
      list.add(node.getObject()); 
     return list.toArray(new E[0]); // any way to make this line work? 
    } 

    // other important stuff 
} 

私はこのようなことをしたいと思いますが、このようにジェネリックアレイをインスタンス化することはできません。ここでgetNodes()はノード自体の内容ではなくノードの内容を返しますが、どのように把握できません。

私は、Graphジェネリックで定義されているNodeジェネリックは、Nodeクラスが常にGraphクラスと同じタイプであることを意味すると考えていました。そうじゃないの?

Nodeクラスは

public class Node<E> { 

    private LinkedList<Edge> edges; 
    private E obj; 

    public E getObject() { 
     return obj; 
    } 

    // other useful stuff 
} 

のような任意の助けをありがとうね!

EDIT:正しいタイプの返された配列を作成する必要があります。ジェネリック型の割り当てを持つArrayListからArrayを取得する方法はありますか?

+0

可能であれば、 'ArrayList'はそれをしたと思いませんか? – shmosel

+0

これは私が抱えている問題の一般的なバージョンです。今は、新しい機能は追加しないが、実際のコードは追加するので、カスタムクラスの作成には何の意味もありません。私が知る限り、私はこのタイプの実装が必要な方法を見つけることができません。 – user3785637

+2

'ArrayList'は何をしますか?' public T [] getThings(T [] a){戻り値things.toArray(a); } ' – shmosel

答えて

1

toArray(E[])メソッドに渡すための配列を作成することができます質問のコメント欄にあるので、私はここで繰り返し、自分の質問に答えます。

このコードは、この問題を解決するために使用します。私は多かれ少なかれ、ArrayListのソースコードからtoArray(E[] a)関数のロジックを取り除いた(もちろんその一部は切り捨てられている)。

@SuppressWarnings("unchecked") 
public E[] getNodes(E[] a) { 
    int size = nodes.size(); 
    // creates an empty array of the right size and type 
    E[] arr =(E[]) java.lang.reflect.Array 
      .newInstance(a.getClass().getComponentType(), size); 
    // fills that array with the correct data 
    for (int i = 0; i < size; i++) 
     arr[i] = nodes.get(i).getObject(); 
    return arr; 
} 

ステップ遠くなり、また、スレッドセーフされた方法で同じタスクを達成いくつかのロジックを確認するために、ArrayListのソースコードを見てみましょう。

+0

渡された配列を使用しない場合は、パラメータとして 'Class 'を使用してください。ほとんど同じですが、アクセスするときに新しい配列を作成する必要はありません。 E.classが行います。 –

1

getThingsメソッドでは、Eの何らかの形が必要です。

getThingsの署名をそのまま使用する場合は、construtorパラメータを追加して、実際のクラスEを提供することができます。そのクラスを使用すると、他の誰かが機能しなかった答えを思い付いたのが、私に働くことになったアイデアを与えたが、彼らはまた、中にそれを置くList<E>

private final Class<E> type; 
private final List<E> list; 

public CustomClass(Class<E> type) { 
    this.type = type; 
    this.list = new ArrayList<>(); 
} 

@SuppressWarnings("unchecked") 
public E[] getThings() { 
    Object[] reference = (Object[]) Array.newInstance(type, list.size()); 
    return (E[]) list.toArray(reference); 
} 
+0

申し訳ありません私は答えがより多くの情報を必要とするかもしれないと思ったので別の例に変更しましたが、実際にはうまくいくかもしれません。しかし、ちょうど疑問に思って、どのように 'クラス型は正確に動作しますか? – user3785637

+0

'Class type'パラメータを' getThings() 'メソッドに移動することもできます。 – Andreas

+0

'Class '型を使用して 'Array'型を割り当てることは可能ですか? – user3785637

関連する問題