Javaで配列から要素を削除するための高速(そして見栄えの良い)方法はありますか?
あなたはcommons langのArrayUtilsを使うことができます。
array = ArrayUtils.removeElement(array, element)
あなたの質問はあまり明確ではありません。あなた自身の答えから、私はあなたがやろうとしていることをよりよく伝えることができます。
public static String[] removeElements(String[] input, String deleteMe) {
List result = new LinkedList();
for(String item : input)
if(!deleteMe.equals(item))
result.add(item);
return result.toArray(input);
}
NB:これはテストされていません。エラーチェックは読者への課題として残されています(inputまたはdeleteMeがnullの場合はIllegalArgumentExceptionがスローされます。nullリスト入力の空のリストは意味がありません。配列からnull文字列を削除することは意味がありますが、 llもそれを練習として残します;現在、deleteMeがnullの場合、deleteMeのequalsを呼び出そうとするとNPEをスローします。
私がここで行った選択:
LinkedListを使用しました。繰り返しは同じくらい速くなければならず、サイズ変更や、たくさんの要素を削除してしまう場合は大きすぎるリストの割り当ては避けます。 ArrayListを使用して、初期サイズを入力長に設定することができます。大した違いはないでしょう。
最良の選択はコレクションを使用することですが、それが何らかの理由で解決されない場合は、 arraycopy
を使用してください。これを使用して、わずかに異なるオフセットで同じ配列との間でコピーすることができます。
例えば:
public void removeElement(Object[] arr, int removedIdx) {
System.arraycopy(arr, removedIdx + 1, arr, removedIdx, arr.length - 1 - removedIdx);
}
コメントに応えて編集する(tl; dr):
それは別の良い方法ではありません、それは本当に唯一の許容できる方法です - この機能を可能にするツール(Java.ArrayListやApache utilsのような)はカバーの下でこのメソッドを使うでしょう。また、あなたは本当にArrayList(あるいは途中から削除するのであればリンクリスト)を使うべきなので、宿題としてやっているのでなければ問題にならないはずです。
コレクションを割り当てる(新しい配列を作成する)には、(コレクションがarraycopyを使用して行うように)要素を削除してから、削除ごとにtoArrayを呼び出して(2番目の新しい配列を作成する)最適化の問題にならないようにします。 、それは犯罪的に悪いプログラミングです。
たとえば、100MBのRAMを占有するアレイがあるとします。今度はそれを反復し、20の要素を削除したいと思います。
試してみる...
それほど大きくはならない、または一度にたくさん削除した場合は別の方法でコーディングしていると思われることはわかっていますが、そのような仮定をしているような大量のコードを修正しました。
基本Java配列から要素を削除することはできません。代わりにさまざまなCollectionsとArrayListを見てください。
見栄えの良い解決策は、まず配列ではなくリストを使用することです。
List.remove(index)
もしあなたが配列を使うべきなら、System.arraycopy
への2回の呼び出しが最も速いでしょう。
Foo[] result = new Foo[source.length - 1];
System.arraycopy(source, 0, result, 0, index);
if (source.length != index) {
System.arraycopy(source, index + 1, result, index, source.length - index - 1);
}
(Arrays.asList
も配列を扱うのに適した候補ですが、remove
をサポートしているようには見えません。)
私は問題が解決策を求めていたと思います なしで コレクションAPIの使用。パフォーマンスが重要となる低レベルの詳細、または疎結合SOA統合のいずれかに配列を使用します。後で、それらをコレクションに変換し、それをビジネスロジックに渡すことは問題ありません。
低レベルのパフォーマンスについては、通常、forループなどによる迅速で汚い命令的な状態の混在によってすでに難読化されています。その場合、コレクションと配列の間で行ったり来たりする変換は面倒で、読みにくく、さらにはリソース集約型です。
ところで、TopCoder、誰?常にそれらの配列パラメータ!だからアリーナにいるときにそれらを処理できるように準備してください。
以下が私の問題の解釈と解決策です。それはBill Kとjelovirtによって与えられるものの両方とは機能的に異なります。 - )また、要素が配列内にない場合も適切に処理されます。
それが役立つことを願っています!
public char[] remove(char[] symbols, char c)
{
for (int i = 0; i < symbols.length; i++)
{
if (symbols[i] == c)
{
char[] copy = new char[symbols.length-1];
System.arraycopy(symbols, 0, copy, 0, i);
System.arraycopy(symbols, i+1, copy, i, symbols.length-i-1);
return copy;
}
}
return symbols;
}
あなたは ArrayUtils API を「見栄えの良い方法」で削除することができます。これは配列に対して多くの操作(削除、検索、追加、包含など)を実装しています。
見てください。それは私の人生をよりシンプルにしました。
配列の長さを変更することはできませんが、新しい値をコピーして既存のインデックス番号に格納することで、インデックスが保持する値を変更できます。 1 =マイク、2 = jeff // 10 = george 11は1を上書きしてマイクを書きます。
Object[] array = new Object[10];
int count = -1;
public void myFunction(String string) {
count++;
if(count == array.length) {
count = 0; // overwrite first
}
array[count] = string;
}
Bill Kとdadinnによって書かれたものには、さらにいくつかの前提条件が必要です。
Object[] newArray = new Object[src.length - 1];
if (i > 0){
System.arraycopy(src, 0, newArray, 0, i);
}
if (newArray.length > i){
System.arraycopy(src, i + 1, newArray, i, newArray.length - i);
}
return newArray;
大丈夫、THXたくさん今私はこのようにSTHを使用します。
public static String[] removeElements(String[] input, String deleteMe) {
if (input != null) {
List<String> list = new ArrayList<String>(Arrays.asList(input));
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(deleteMe)) {
list.remove(i);
}
}
return list.toArray(new String[0]);
} else {
return new String[0];
}
}
Javaコレクション/ Javaコモンズコレクションを使用してください。
Java.util.ArrayListを使うと、次のようなことができます。
yourArrayList.remove(someObject);
yourArrayList.add(someObject);
もっと簡単な方法は、List、Set ...を使ってremove()メソッドを使うことです。
配列のサイズを変更しても問題ない場合は、削除するアイテムを最後のアイテムと入れ替えます。