2009-09-26 12 views
49

ArrayListのアレイスライスをJavaでどのように取得できますか? - それは互換性がないですJavaでArrayListからArrayListをスライスするにはどうすればよいですか?

ArrayList<Integer> inputA = input.subList(0, input.size()/2); 
// where 'input' is a prepouplated ArrayList<Integer> 

だから私は仕事にこれを期待が、JavaはListを返します。具体的に私はこのような何かをしたいです。それをキャストしようとすると、Javaは私を許さないでしょう。 ArrayListが必要です - 何ができますか?

+4

なぜあなたは 'ArrayList'の使用を主張しますか? 'List'と' ArrayList'は ''互換性がありません ''' ArrayList''が 'List'を実装しているため、インターフェイスの仕組みが少し分からないかもしれないと思います。 – Bombe

+2

私はArrayListの使用を主張しています。これは、厳密なメソッドプロトタイプのinteview質問です。私は明らかに、subListはList型を返すはずですが、返されたListをArrayListにキャストできないため、理解が不十分です。だからあなたは私に人を教えてくれます.. –

+4

'ArrayList'を必要とするのは、' ArrayList'を受け入れるメソッドを呼び出す必要があるからです。おそらくこのような方法はあまり設計されておらず、代わりに 'List'を受け入れるべきですが、このような状況はインタビューの質問だけでなく、他人が書いたコードでも起こり得ます。同僚や図書館は必ずしも完璧というわけではありません。 – Gravity

答えて

86

Javaでは、APIの具象クラスではなくインターフェイスタイプを使用することをお勧めします。

実際にListを使用する必要があるArrayList(多分多くの場所)を使用していることが問題です。その結果、リストがArrayListであるという不必要な制約を受けて、問題が発生しました。問題へのあなたの提案「溶液」だった


List input = new ArrayList(...); 

public void doSomething(List input) { 
    List inputA = input.subList(0, input.size()/2); 
    ... 
} 

this.doSomething(input); 
は/これです:

これはあなたのコードがどのように見えるかです

のコピーを作成することにより動作します
new ArrayList(input.subList(0, input.size()/2)) 

サブリスト通常の意味でのスライスではありません。さらに、サブリストが大きい場合、コピーを作成するのは高価になります。


あなたは、あなたが、あなたはArrayListのカスタムサブクラスを実装することができるかもしれない、に持ってArrayListとしてinputAを宣言ようにあなたがを変更することはできませんのAPIによって制約されている場合はこれでsubListメソッドが返しますArrayListのサブクラスです。ただし:

  1. 設計、実装、テストするには多くの作業が必要です。
  2. ArrayListクラスの文書化されていないアスペクト(したがって、変更される可能性があります)に依存する可能性があり、コードベースに重要な新しいクラスを追加しました。
  3. ArrayListインスタンスを作成するコードベースの関連する場所を変更して、代わりにサブクラスのインスタンスを作成する必要があります。

「アレイをコピーする」ソリューションはより実用的です...これらは真のスライスではないことに留意してください。

使用すると、1つは、ArrayListの

から削除する必要がある要素ののstartIndexとendIndexがendIndexを開始すると終了インデックスはそれぞれ配列から削除されるように、alは、元のArrayListとstartIndexとする知っていれば、私は方法を発見した

+3

実際には、subListはコピーを作成しません。 (http://docs.oracle.com/javase/6/docs/api/java/util/List.html#subList%28int,%20int%29) – Matthew

+2

実際に@Matthew、私は元のリストにビューを返しますOPの自己解答を参照しています。これは、次のようになります。 'new ArrayList(input.subList(0、input.size()/ 2))' –

6

既存のメソッドがない場合は、0からinput.size()/2までの繰り返しが可能で、各連続する要素を取得して新しいArrayListに追加することができます。

EDIT:実際には、私はあなたがそのリストを利用してone of the ArrayList constructorsを使って新しいArrayListをインスタンス化することができると思います。

+2

私があなたの編集を読む前に私の答えを掲載しました)。ありがとう:) –

+0

しかし、それは*新しいArrayListを作る*リストをコピーします。 – Joren

+2

@BT - この文脈では、これは「スライス」という用語が通常意味するものではありません。 –

-4

これは私がそれを解決した方法です。私は、サブリストが元のリストの要素を直接参照していることを忘れていたので、なぜそれがうまくいかないのか分かりません。

ArrayList inputA = new ArrayList(input.subList(0、input.size()/ 2));

2

al.subList(startIndex, endIndex + 1).clear(); 
関連する問題