質問

    

この質問にはすでに回答があります:

         

わかりました。したがって、ArrayListを反復処理して特定の要素を削除するようにしています。ただし、For-Eachのような構造を使用すると問題が発生します。次のコードを実行すると:

ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)

for(String t : arr)
{
  t = " some other value "; //hoping this would change the actual array
}

for(String t : arr)
{
  System.out.println(t); //however, I still get the same array here
}

私の質問、「t」を「arr」へのポインタにすると、for-eachループの値を変更できるようになりますか?別の構造を使用してArrayListをループできることはわかっていますが、これはとてもきれいで読みやすいように見えます。「t」をポインタにできると便利です。

すべてのコメントを歓迎します!たとえそれを吸い込んで別の構造を使用するべきだと言っても。

役に立ちましたか?

解決

最良のアプローチはforループを使用することだと思います。

    ArrayList<String> arr = new ArrayList<String>();

    for (int i = 0; i < arr.size(); i++) {

        String t = arr.get(i);

        if (// your condition is met) {
            arr.set(i, "your new value");
        }
    }

他のヒント

問題は、ループスコープのリファレンス t を変更して、新しいStringインスタンスを指すようにすることです。これは機能しません。 arraylistの実際のエントリは参照しません。参照の実際のを変更する必要があります。 String が可変で、そのための架空の set()メソッドを提供した場合、理論上は可能です

for (String t : arr) {
    t.set("some other value");
}

またはそうですが、それは不変なので不可能です。通常の for ループを使用して、配列自体のエントリポイントのハンドルを取得する方が良い:

for (int i = 0; i < arr.size(); i++) {
    arr.set(i, "some other value");
}

拡張された for ループの使用を主張する場合、 String StringBuilder に置き換える必要があります。これは可変です:

for (StringBuilder t : arr) {
     t.delete(0, t.length()).append("some other value");
}

Javaは参照渡しではなく値渡しであることに注意してください。

For-eachはインデックスポインターを提供しないため、不変の値を変更するために使用することはできません。

いずれもインデックス付きのforループを使用するか、可変型(StringではなくStringBufferなど)を使用します

Javaのオブジェクト(文字列など)の配列は、順序付けられた一連の参照を含む連続したブロックです。したがって、4つの文字列の配列がある場合、実際に持っているのは、配列に格納されている4つの参照と、配列の外側にあるがその4つの要素によって参照される4つの文字列オブジェクトです。

Javaのfor-eachコンストラクトは、ローカル変数を作成し、反復ごとに、その反復に対応する配列セルからの参照をそのローカル変数にコピーします。ループ変数を設定すると( t =&quot; some other value&quot; )、新しい文字列&quot; some other value&quot; への参照をローカルに配置します配列にではなく、変数t。

ループ変数が配列/リスト要素自体のエイリアスのように機能する他の言語(Perlなど)とは対照的です。

コードは、コンパイラによって次のように書き直されます。

ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)

for (final Iterator <String> i = arr.iterator(); i.hasNext();) {
    String t;

    t = i.next();
    t = " some other value "; // just changes where t is pointing
}

希望することを行うには、次のようにforループを記述する必要があります。

for (final ListIterator<String> i = arr.iterator(); i.hasNext();) {
     final String t;

     t = i.next();
     i.set("some other value");
}

Iteratorにはsetメソッドがありません。ListIteratorのみにあります。

基本的に、リストarrから文字列tを削除します。 arr.remove(t)を実行するだけで完了です。 しかし同じリストを繰り返し処理している間はできません。この方法でリストを変更しようとすると、例外が発生します。

2つのオプションがあります:

  1. リストのクローンを作成し、クローンを反復処理し、元のリストから「特定の」文字列を削除します
  2. 削除候補のリストを作成し、そのリストにすべての「特定の」文字列を追加し、元のリストを反復処理した後、ごみ箱を反復処理して、ここで収集したすべてを元のリストから削除します。

オプション1は簡単です。クローンは次のように作成できます。

List<String> clone = new ArrayList<String>(arr);

Javaでオブジェクト/参照がどのように機能するかを誤解しているようです。これは、言語を効果的に使用するための基本です。ただし、ここのこのコードは必要なことを行う必要があります(説明がないことをおapび申し上げます):

ArrayList<String> arr = new ArrayList<String>();
//... fill with some values (doesn't really matter)

for(int i = 0; i < arr.size(); i++)
{
  arr.set(i, " some other value "); // change the contents of the array
}

for(String t : arr)
{
  System.out.println(t); 
}

これは不変または可変に関係しないと思います。

 t = " some other value "; //hoping this would change the actual array

tは、実際のオブジェクトへの参照を保持しません。 Javaはarraylistから値をコピーし、その値をtに入れて、配列リストの値が影響しないようにします。

HTH

これはよく回答されています。まだここに私の提案があります。ループ内のvar tはそこにのみ表示されます。ループの外側では見えません。 String でない場合は、 t.set()を実行できます。

プレーンな文字列ではなく、 StringBuffer を使用します。これにより、中の文字列は変更可能です。

文字列は不変です。 StringBuilder / Bufferのような可変型がある場合は、繰り返しで文字列を変更できます。参照があります。覚えておいてください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top