86

n個のオブジェクトの配列が与えられ、それが文字列の配列であり、次の値を持っているとしましょう。

foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";

配列内の「a」に等しいすべての文字列/オブジェクトを削除/削除するにはどうすればよいですか?

4

20 に答える 20

114

[すぐに使用できるコードが必要な場合は、(カット後の)私の「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()明示的なサイズを間違える方が簡単な場合があるため(たとえば、間違ったリストを呼び出す)、私のアプローチを好みます。

于 2008-09-21T23:30:33.667 に答える
32

Java 8 の代替手段:

String[] filteredArray = Arrays.stream(array)
    .filter(e -> !e.equals(foo)).toArray(String[]::new);
于 2014-04-20T23:44:12.827 に答える
20

を使用しListて配列から作成し、適切なすべての要素Arrays.asList()を呼び出します。remove()次に、「リスト」を呼び出しtoArray()て、再び配列に戻します。

それほどパフォーマンスは良くありませんが、適切にカプセル化すれば、後でいつでもより迅速に何かを行うことができます。

于 2008-09-21T23:18:06.753 に答える
15

あなたはいつでもすることができます:

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);
于 2008-09-23T06:55:15.150 に答える
7

外部ライブラリを使用できます。

org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)

プロジェクトApacheCommonsLanghttp ://commons.apache.org/lang/にあります

于 2011-02-04T14:41:12.980 に答える
6

以下のコードを参照してください

ArrayList<String> a = new ArrayList<>(Arrays.asList(strings));
a.remove(i);
strings = new String[a.size()];
a.toArray(strings);
于 2014-01-26T20:37:36.540 に答える
3

それのリストを作成してから削除してから配列に戻すことについての何かが間違っていると思います。テストしていませんが、次のほうがパフォーマンスが良いと思います。はい、おそらく過度に事前に最適化しています。

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];
   }
}
于 2008-09-22T12:50:22.027 に答える
3

これは非常に古い投稿であることは承知していますが、ここでの回答のいくつかは私を助けてくれました。

ArrayListリストのサイズを変更せずに変更しない限り、書き戻す配列のサイズを変更する必要があることを微調整する前に、これを機能させるのにかなり苦労しました。

ArrayList変更している の要素が最初よりも多いか少ない場合は、その行で例外が発生するため、新しい (正しい) サイズの配列を作成するには、またはのList.toArray()ようなものが必要です。List.toArray(new String[] {})List.toArray(new String[0])

私がそれを知っていることは明らかです。これは、新しくなじみのないコード構造に慣れようとしている Android/Java の初心者には明らかではなく、ここにある以前の投稿のいくつかからも明らかではないため、私のように何時間も頭を悩ませている他の人にこの点を本当に明確にしたかっただけです。 !

于 2013-07-05T11:49:34.520 に答える
1

編集:

配列内のヌルを持つポイントがクリアされました。私のコメントで申し訳ありません。

オリジナル:

ええと... ライン

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 値を残さずに。

于 2008-09-22T20:20:13.740 に答える
1

この問題に対する私の小さな貢献。

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;
}

}

于 2013-11-30T13:52:34.807 に答える
0

それはあなたが「取り除く」とはどういう意味かによるのですか?配列は固定サイズの構造であり、その中の要素の数を変更することはできません。したがって、a)不要な要素を含まない新しい短い配列を作成するか、b)不要なエントリを「空」ステータスを示すものに割り当てることができます。プリミティブを使用していない場合、通常はnullです。

最初のケースでは、配列からリストを作成し、要素を削除して、リストから新しい配列を作成します。パフォーマンスが重要な場合は、削除してはならない要素をリストに割り当てて配列を繰り返し処理し、リストから新しい配列を作成します。2番目のケースでは、単純に調べて、配列エントリにnullを割り当てます。

于 2008-09-24T21:15:40.847 に答える
0

インデックス 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) );
            }
于 2016-06-11T19:00:40.007 に答える
0

コードが正しく表示されません。すみません、うまくいきました。もう一度申し訳ありませんが、質問を正しく読んでいないと思います。

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++;
    }
}
于 2008-09-22T12:59:37.747 に答える
0

要素の順序が問題でない場合。要素 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);
}
于 2019-08-06T19:44:22.287 に答える
-7

配列の場所にnullを割り当てます。

于 2008-09-21T23:19:47.810 に答える