web-dev-qa-db-ja.com

ArrayListを新しいサイズに縮小する

本当に自分で実装する必要がありますか?

private void shrinkListTo(ArrayList<Result> list, int newSize) {
  for (int i = list.size() - 1; i >= newSize; --i)
  list.remove(i);
}
58
ripper234

削除する要素の範囲で sublist を作成し、返されたリストで clear を呼び出します。

list.subList(23, 45).clear()

このアプローチは ListArrayList の両方のドキュメントでイディオムとして言及されています。


完全に単体テストされたコードの例を次に示します!

// limit yourHappyList to ten items
int k = yourHappyList.size();
if ( k > 10 )
    yourHappyList.subList(10, k).clear();
    // sic k, not k-1
112
mP.

または、 subList メソッドを使用できます。

public static <T> List<T> shrinkTo(List<T> list, int newSize) {
    return list.subList(0, newSize - 1);
}
7
dfa

ArrayList#removeRange() メソッドを使用:

protected void removeRange(int fromIndex、int toIndex)

FromIndex(両端を含む)とtoIndex(両端を除く)の間にあるインデックスを持つすべての要素をこのリストから削除します。後続の要素を左にシフトします(インデックスを減らします)。この呼び出しは、(toIndex-fromIndex)要素によってリストを短縮します。 (toIndex == fromIndexの場合、この操作は効果がありません。)

次に、 ArrayList#trimToSize() メソッドを使用します。

このArrayListインスタンスの容量をリストの現在のサイズにトリミングします。アプリケーションはこの操作を使用して、ArrayListインスタンスのストレージを最小化できます。

5
dfa

私の解決策:

public static void shrinkTo(List list, int newSize) {
    int size = list.size();
    if (newSize >= size) return;
    for (int i = newSize; i < size; i++) {
        list.remove(list.size() - 1);
    }
}

使用するだけ:

shrinkTo(yourList, 6);
3

別の考慮事項があります。メソッドシグネチャでArrayListを使用することを避け、代わりにListインターフェースに取り組んで、ArrayList実装に結び付けて、たとえば、LinkedListの方がニーズに適している場合、難しい行です。この密結合を防ぐには、コストがかかります。

別のアプローチは次のようになります。

_private void shrinkListTo(List<Result> list, int newSize) {
  list.retainAll(list.subList(0, newSize);
}
_

残念ながら、サブクラスが実装するList.retainAll()メソッドはオプションであるため、catchと_UnsupportedOperationException,_を実行してから別の操作を行う必要があります。

_private void shrinkListTo(List<Result> list, int newSize) {
  try {
    list.retainAll(list.subList(0, newSize);
  } catch (UnspportedOperationException e) {
     //perhaps log that your using your catch block's version.
     for (int i = list.size() - 1; i >= newSize; --i)
        list.remove(i);
     }
  }
}
_

それはあなたのオリジナルほど簡単ではありません。渡すリストのインスタンスに縛られていない場合は、subList(int start, int end)を呼び出すことで簡単に新しいインスタンスを返すことができ、メソッドを作成する必要さえありません。 (Java 6)では、リスト、オフセット、サイズを含む_AbstractList.SubList_のインスタンスを取得するため、これはより高速な実装にもなります。反復する必要はありません。

クラスではなくインターフェイスへのコーディングの引数に興味がある場合は、 このお気に入りの記事はAllen Holubによる を参照してください。

1
akf