【问题标题】:For Loop is skipping every other line while searching ArrayListFor Loop 在搜索 ArrayList 时每隔一行跳过
【发布时间】:2016-05-16 04:16:50
【问题描述】:

我有一个从 10 到 100 的连续整数的数组列表。我生成一个随机数(比如 50),然后我想删除所有在 10 的位置上具有“5”的数字 - 50 到 59 的所有整数.

public static void updateMyGuess() {

 ArrayList<Integer> possibles = new ArrayList <Integer>();

 for (int i = 10; i < 100; i++) {
   possibles.add(i); 
    }

 int guess = 50; //my guess is generated by another method. Not listed here
 int tens = guess / 10 % 10;
 int x;

 for ( int i = 0; i < possibles.size(); i++) {
   x = possibles.get(i);
   if (x / 10 % 10 == tens) {
     possibles.remove(i);
 } 
}

由于某种原因,这只会从 50 年代的 ArrayList 中删除所有其他值:50、52、54... 58。这是为什么呢?我可以改变什么来让它摆脱所有 50 年代?

【问题讨论】:

  • 要么使用迭代器(最好的方法),要么向后搜索列表(最简单的 hack)。

标签: java for-loop arraylist


【解决方案1】:

在 java 8 中,ArrayList 也有一个 remove if 方法。
for more examples on how to use removeIf

ArrayList<Integer> possibles = new ArrayList<Integer>();
    for (int i = 10; i < 100; i++) {
        possibles.add(i);
    }

    System.out.println(possibles);
    int guess = 50; // my guess is generated by another method. Not listed
            // here
    int tens = guess / 10 % 10;
    int x;
    // removes all the elements for which removeIf returns true
    possibles.removeIf(new Predicate<Integer>() {
        @Override
        public boolean test(Integer arg0) {
             return arg0 / 10 % 10 == tens;
        }
    });

    System.out.println(possibles);

【讨论】:

    【解决方案2】:

    使用@nlloyd 建议的Iterator 是一个更好的解决方案。

    但是,在某些情况下(无论出于何种原因)您可能无法使用 Iterator(例如,您正在使用不提供迭代器的语言或库)。简单的解决方案是反向迭代:

    for ( int i = possibles.size()-1; i >= 0; i--) {
    

    如果您要立即再次删除项目,为什么需要首先将项目添加到列表中,这一点尚不清楚:

     ArrayList<Integer> possibles = new ArrayList <Integer>();
     int guess = 50; //my guess is generated by another method. Not listed here
     int tens = guess / 10 % 10;
    
     for (int x = 10; x < 100; x++) {
       if (x / 10 % 10 != tens) {
         possibles.add(x);
       } 
     }
    

    【讨论】:

      【解决方案3】:

      正如 Jim 所提到的,您在遍历列表时会改变列表,从而有效地跳过项目。

      使用迭代器而不是 for 循环。迭代器用于在您遍历列表时删除元素。

      Iterator<Integer> iter = possibilities.iterator()
      while (iter.hasNext()) {
         x = iter.next();
         if (x / 10 % 10 == tens) {
           iter.remove();
         }
      }
      

      【讨论】:

        【解决方案4】:

        删除[i] 处的元素后,[i+1] 处的元素(以及之后的所有元素)向上移动一个空格。旧的[i+1] 现在占据了[i] 的元素,所以当i 递增时,您会跳过向上移动的元素。

        【讨论】:

          猜你喜欢
          • 2016-10-02
          • 2019-09-19
          • 1970-01-01
          • 2015-10-31
          • 1970-01-01
          • 1970-01-01
          • 2011-11-04
          • 1970-01-01
          • 2019-04-01
          相关资源
          最近更新 更多