Artery-tips-ループの中でのListの要素の削除 ( プログラム )

package jp.avaj.lib.algo;

import java.util.ArrayList;

import java.util.List;

import jp.avaj.lib.test.L;

/**

 *  Artery-tips-ループの中でのListの要素の削除

 *

 *  タイトルのようにループの中で要素を削除するには、ちょいと工夫がいる

 *  工夫と言っても大したことではないが、知らないと立ち往生することになる

 *  想像だが、これでバグった人はいるはず....

 *

 *  解答のポイントは、削除する要素を記録したListやSetを作成してループの外で削除するようにすること

 *

 *  削除する要素を含まないList,Set,Mapを新規に作成するという方法がある

 *  しかしタイトルの趣旨とは異なるので、ここで示した方法を解答としておく

 *

 */

public class Tips0015 {

  public static void main(String[] args) {

    //

    //

    L.p("Listの中からBが先頭にある要素を削除する");

    L.p("「素直な」解答");

    List<String> list = createList();

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

      String str = list.get(i);

      if (str.startsWith("B")) {

        list.remove(i);

      }

    }

    // 結果はB1が削除できない

    // 理由はB0を削除した時にインデックスが進んでしまうため

    // B0のインデックスだったところにB1が入るから

    L.p(ArObj.toString(list));

    //

    L.p("それならば「ループのインデックスをデクリメントすればよい」はず");

    list = createList();

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

      String str = list.get(i);

      if (str.startsWith("B")) {

        list.remove(i);

        i--;  // インデックスを戻す

      }

    }

    // これはうまくいく...⇒ しかしあまり「よくない解答」

    L.p(ArObj.toString(list));

    //

    L.p("削除する要素を記録しておいて、後で削除する");

    List<Integer> yoteiList = new ArrayList<Integer>();

    list = createList();

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

      String str = list.get(i);

      if (str.startsWith("B")) {

        // 注意、インデックスは大きい方からいれておく必要がある

        // 小さい方から削除すると、後の順番が変わってしまうため

        yoteiList.add(0,i);

      }

    }

    // 削除する要素が分かったので、これから削除する

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

      int index = yoteiList.get(i);

      list.remove(index);

    }

    // これはうまくいく..

    // しかし「ループの中で削除」という競技ルールに違反..

    L.p(ArObj.toString(list));

    //

  }

  private static List<String> createList() {

    List<String> strList = new ArrayList<String>();

    strList.add("A0");

    strList.add("A1");

    strList.add("A2");

    strList.add("B0");

    strList.add("B1");

    strList.add("B2");

    strList.add("C0");

    strList.add("C1");

    strList.add("C2");

    return strList;

  }

}

//-結果------------------------------------------------

Listの中からBが先頭にある要素を削除する

「素直な」解答

[A0, A1, A2, B1, C0, C1, C2]

それならば「ループのインデックスをデクリメントすればよい」はず

[A0, A1, A2, C0, C1, C2]

削除する要素を記録しておいて、後で削除する

[A0, A1, A2, C0, C1, C2]

//-----------------------------------------------------

//・目次 - Artery-Tips

//  https://blogs.yahoo.co.jp/artery2020/41563143.html

//・目次 - Java入門

//  http://blogs.yahoo.co.jp/artery2020/39975776.html

//・目次 - ビジネスパーソンの常識と非常識

//  http://blogs.yahoo.co.jp/artery2020/39728331.html

//・目次 - 論理・発想・思考についての考察と鍛え方

//  http://blogs.yahoo.co.jp/artery2020/39657784.html

//-----------------------------------------------------