n個のオブジェクトの配列が与えられ、それが文字列の配列であり、次の値を持っているとしましょう。
foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";
配列内の「a」に等しいすべての文字列/オブジェクトを削除/削除するにはどうすればよいですか?
n個のオブジェクトの配列が与えられ、それが文字列の配列であり、次の値を持っているとしましょう。
foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";
配列内の「a」に等しいすべての文字列/オブジェクトを削除/削除するにはどうすればよいですか?
[すぐに使用できるコードが必要な場合は、(カット後の)私の「Edit3」までスクロールしてください。残りは後世のためにここにあります。]
ダストマンのアイデアを具体化するには:
List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);
編集:私は現在、Arrays.asList
代わりに使用していますCollections.singleton
:シングルトンは1つのエントリに制限されていますが、このasList
アプローチでは、後で除外するために他の文字列を追加できます:Arrays.asList("a", "b", "c")
。
Edit2:上記のアプローチは同じ配列を保持します(したがって、配列は同じ長さのままです)。最後の後の要素はnullに設定されます。必要なサイズの新しいアレイが必要な場合は、代わりに次を使用してください。
array = list.toArray(new String[0]);
Edit3:同じクラスでこのコードを頻繁に使用する場合は、これをクラスに追加することを検討してください。
private static final String[] EMPTY_STRING_ARRAY = new String[0];
次に、関数は次のようになります。
List<String> list = new ArrayList<>();
Collections.addAll(list, array);
list.removeAll(Arrays.asList("a"));
array = list.toArray(EMPTY_STRING_ARRAY);
new
これにより、関数が呼び出されるたびに編集される、役に立たない空の文字列配列がヒープに散らばるのを防ぐことができます。
cynicalmanの提案(コメントを参照)もヒープのポイ捨てに役立ちます。公平を期すために、次のように言及する必要があります。
array = list.toArray(new String[list.size()]);
size()
明示的なサイズを間違える方が簡単な場合があるため(たとえば、間違ったリストを呼び出す)、私のアプローチを好みます。
Java 8 の代替手段:
String[] filteredArray = Arrays.stream(array)
.filter(e -> !e.equals(foo)).toArray(String[]::new);
を使用しList
て配列から作成し、適切なすべての要素Arrays.asList()
を呼び出します。remove()
次に、「リスト」を呼び出しtoArray()
て、再び配列に戻します。
それほどパフォーマンスは良くありませんが、適切にカプセル化すれば、後でいつでもより迅速に何かを行うことができます。
あなたはいつでもすることができます:
int i, j;
for (i = j = 0; j < foo.length; ++j)
if (!"a".equals(foo[j])) foo[i++] = foo[j];
foo = Arrays.copyOf(foo, i);
外部ライブラリを使用できます。
org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)
プロジェクトApacheCommonsLanghttp ://commons.apache.org/lang/にあります
以下のコードを参照してください
ArrayList<String> a = new ArrayList<>(Arrays.asList(strings));
a.remove(i);
strings = new String[a.size()];
a.toArray(strings);
それのリストを作成してから削除してから配列に戻すことについての何かが間違っていると思います。テストしていませんが、次のほうがパフォーマンスが良いと思います。はい、おそらく過度に事前に最適化しています。
boolean [] deleteItem = new boolean[arr.length];
int size=0;
for(int i=0;i<arr.length;i==){
if(arr[i].equals("a")){
deleteItem[i]=true;
}
else{
deleteItem[i]=false;
size++;
}
}
String[] newArr=new String[size];
int index=0;
for(int i=0;i<arr.length;i++){
if(!deleteItem[i]){
newArr[index++]=arr[i];
}
}
これは非常に古い投稿であることは承知していますが、ここでの回答のいくつかは私を助けてくれました。
ArrayList
リストのサイズを変更せずに変更しない限り、書き戻す配列のサイズを変更する必要があることを微調整する前に、これを機能させるのにかなり苦労しました。
ArrayList
変更している の要素が最初よりも多いか少ない場合は、その行で例外が発生するため、新しい (正しい) サイズの配列を作成するには、またはのList.toArray()
ようなものが必要です。List.toArray(new String[] {})
List.toArray(new String[0])
私がそれを知っていることは明らかです。これは、新しくなじみのないコード構造に慣れようとしている Android/Java の初心者には明らかではなく、ここにある以前の投稿のいくつかからも明らかではないため、私のように何時間も頭を悩ませている他の人にこの点を本当に明確にしたかっただけです。 !
編集:
配列内のヌルを持つポイントがクリアされました。私のコメントで申し訳ありません。
オリジナル:
ええと... ライン
array = list.toArray(array);
削除された要素があった配列内のすべてのギャップをnullに置き換えます。要素が削除されるため、これは危険な場合がありますが、配列の長さは同じままです!
これを避けたい場合は、新しい配列を toArray() のパラメーターとして使用してください。removeAll を使用したくない場合は、代わりに Set を使用できます。
String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };
System.out.println(Arrays.toString(array));
Set<String> asSet = new HashSet<String>(Arrays.asList(array));
asSet.remove("a");
array = asSet.toArray(new String[] {});
System.out.println(Arrays.toString(array));
与えます:
[a, bc, dc, a, ef]
[dc, ef, bc]
Chris Yester Young からの現在受け入れられている回答は次のとおりです。
[a, bc, dc, a, ef]
[bc, dc, ef, null, ef]
コードで
String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };
System.out.println(Arrays.toString(array));
List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);
System.out.println(Arrays.toString(array));
null 値を残さずに。
この問題に対する私の小さな貢献。
public class DeleteElementFromArray {
public static String foo[] = {"a","cc","a","dd"};
public static String search = "a";
public static void main(String[] args) {
long stop = 0;
long time = 0;
long start = 0;
System.out.println("Searched value in Array is: "+search);
System.out.println("foo length before is: "+foo.length);
for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
System.out.println("==============================================================");
start = System.nanoTime();
foo = removeElementfromArray(search, foo);
stop = System.nanoTime();
time = stop - start;
System.out.println("Equal search took in nano seconds = "+time);
System.out.println("==========================================================");
for(int i=0;i<foo.length;i++){ System.out.println("foo["+i+"] = "+foo[i]);}
}
public static String[] removeElementfromArray( String toSearchfor, String arr[] ){
int i = 0;
int t = 0;
String tmp1[] = new String[arr.length];
for(;i<arr.length;i++){
if(arr[i] == toSearchfor){
i++;
}
tmp1[t] = arr[i];
t++;
}
String tmp2[] = new String[arr.length-t];
System.arraycopy(tmp1, 0, tmp2, 0, tmp2.length);
arr = tmp2; tmp1 = null; tmp2 = null;
return arr;
}
}
それはあなたが「取り除く」とはどういう意味かによるのですか?配列は固定サイズの構造であり、その中の要素の数を変更することはできません。したがって、a)不要な要素を含まない新しい短い配列を作成するか、b)不要なエントリを「空」ステータスを示すものに割り当てることができます。プリミティブを使用していない場合、通常はnullです。
最初のケースでは、配列からリストを作成し、要素を削除して、リストから新しい配列を作成します。パフォーマンスが重要な場合は、削除してはならない要素をリストに割り当てて配列を繰り返し処理し、リストから新しい配列を作成します。2番目のケースでは、単純に調べて、配列エントリにnullを割り当てます。
インデックス i を除くすべての要素をコピーします。
if(i == 0){
System.arraycopy(edges, 1, copyEdge, 0, edges.length -1 );
}else{
System.arraycopy(edges, 0, copyEdge, 0, i );
System.arraycopy(edges, i+1, copyEdge, i, edges.length - (i+1) );
}
コードが正しく表示されません。すみません、うまくいきました。もう一度申し訳ありませんが、質問を正しく読んでいないと思います。
String foo[] = {"a","cc","a","dd"},
remove = "a";
boolean gaps[] = new boolean[foo.length];
int newlength = 0;
for (int c = 0; c<foo.length; c++)
{
if (foo[c].equals(remove))
{
gaps[c] = true;
newlength++;
}
else
gaps[c] = false;
System.out.println(foo[c]);
}
String newString[] = new String[newlength];
System.out.println("");
for (int c1=0, c2=0; c1<foo.length; c1++)
{
if (!gaps[c1])
{
newString[c2] = foo[c1];
System.out.println(newString[c2]);
c2++;
}
}
要素の順序が問題でない場合。要素 foo[x] と foo[0] を交換してから、foo.drop(1) を呼び出すことができます。
foo.drop(n)
(n) 個の最初の要素を配列から削除します。
これが最も簡単でリソース効率の良い方法だと思います。
PS :indexOf
さまざまな方法で実装できます。これが私のバージョンです。
Integer indexOf(String[] arr, String value){
for(Integer i = 0 ; i < arr.length; i++ )
if(arr[i] == value)
return i; // return the index of the element
return -1 // otherwise -1
}
while (true) {
Integer i;
i = indexOf(foo,"a")
if (i == -1) break;
foo[i] = foo[0]; // preserve foo[0]
foo.drop(1);
}
配列の場所にnullを割り当てます。