web-dev-qa-db-ja.com

JavaでArrayListからArrayListをスライスするにはどうすればよいですか?

JavaでArrayListの配列スライスを取得するにはどうすればよいですか?具体的には、私はこのようなことをしたいです:

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

だから私はこれがうまくいくと思っていましたが、JavaはListを返します-互換性がありません。キャストしようとすると、Javaウォンさせてくれません。ArrayListが必要です-何ができますか?

66
B T

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

あなたの問題は、本当にArrayListを使用する必要がある場所でList(おそらく多くの場所で)を使用していることです。その結果、リストが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))

これは、サブリストのコピーを作成することで機能します。通常の意味でのスライスではありません。さらに、サブリストが大きい場合、コピーの作成には費用がかかります。


変更不可のようなAPIに制約されている場合変更する必要があるinputAArrayListとして宣言すると、 ArrayListメソッドがsubListのサブクラスを返すArrayListのカスタムサブクラスを実装します。しかしながら:

  1. 設計、実装、およびテストには多くの労力がかかります。
  2. ArrayListクラスのドキュメント化されていない側面(したがって、「変更の対象」)側面に依存する可能性がある、重要な新しいクラスをコードベースに追加しました。
  3. 代わりにサブクラスのインスタンスを作成するには、ArrayListインスタンスを作成しているコードベースの関連する場所を変更する必要があります。

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

108
Stephen C

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

[〜#〜] edit [〜#〜]:実際、そのリストを取得し、それを使用して新しいArrayListをインスタンス化することができると思います- ArrayListコンストラクターの1つ

6

ArrayListから削除する必要がある要素のstartIndexとendIndexを知っている場合、私は方法を見つけました

alを元のArrayListに、startIndexendIndexを配列から削除する開始インデックスと終了インデックスにそれぞれします。

al.subList(startIndex, endIndex + 1).clear();
5
Aman Gupta

この投稿は非常に古いものですが。誰かがこれを探している場合.

Guavaは、リストを指定されたサイズのサブリストに分割しやすくします

List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
    List<List<Integer>> subSets = Lists.partition(intList, 3);
0
Hari Rao