Java 为什么在我的条件为真时跳过我的if循环?

Java 为什么在我的条件为真时跳过我的if循环?,java,Java,我正在编写一个小程序,在其中我添加了一个字符串的ArrayList,我有一个方法,可以删除以S结尾的每个字符串,它可以很好地处理4个元素,但似乎跳过了一个 最小可复制示例: import java.util.ArrayList; public class sList { public static void main(String [] args) { ArrayList<String> sList=new ArrayList<String>();

我正在编写一个小程序,在其中我添加了一个字符串的ArrayList,我有一个方法,可以删除以S结尾的每个字符串,它可以很好地处理4个元素,但似乎跳过了一个

最小可复制示例:

import java.util.ArrayList;
public class sList {
    public static void main(String [] args) {

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

    sList.add("leaf");
    sList.add("leaves");
    sList.add("box");
    sList.add("boxes");
    sList.add("phones");
    sList.add("phone");
    method m=new methods(); 
System.out.println(m.removePlurals(sList));

}
}

\\ that is my main method 

import java.util.ArrayList;

public class method {

ArrayList<String> removePlurals(ArrayList<String> s) {

        for (int i = 0; i < s.size(); i++) {
            char c = s.get(i).charAt(s.get(i).length() - 1);
            if (c == 's') {
                s.remove(i);
            }

        }
        return s;
    }

}
import java.util.ArrayList;
公共类滑动列表{
公共静态void main(字符串[]args){
ArrayList sList=新的ArrayList();
添加(“叶”);
添加(“叶子”);
单张。添加(“方框”);
列表。添加(“方框”);
添加(“电话”);
sList.add(“电话”);
方法m=新方法();
System.out.println(m.removePlurals(sList));
}
}
\\这是我的主要方法
导入java.util.ArrayList;
公共类方法{
ArrayList removePlurals(ArrayList s){
对于(int i=0;i
我得到的是一个输出:[叶子,盒子,电话,电话]所以它跳过了“电话”
有什么帮助吗?

这是因为当您删除列表中的一项时,列表大小小于开始时的大小,并且当计数器增加时,指向下一个元素(跳过一个)。
您可以通过另一种方式循环列表来解决此问题,如下所示:

 ArrayList<String> removePlurals(ArrayList<String> s) {

        for (int i = s.size()-1; i >= 0; i--) {
            char c = s.get(i).charAt(s.get(i).length() - 1);
            if (c == 's') {
                s.remove(i);
            }

        }
        return s;
    }

}
ArrayList移除复数(ArrayList s){
对于(int i=s.size()-1;i>=0;i--){
charc=s.get(i).charAt(s.get(i).length()-1);
如果(c='s'){
s、 删除(i);
}
}
返回s;
}
}

这是因为当您删除列表中的一项时,列表大小小于开始时的大小,并且当计数器增加时,指向下一个元素(跳过一个)。
您可以通过另一种方式循环列表来解决此问题,如下所示:

 ArrayList<String> removePlurals(ArrayList<String> s) {

        for (int i = s.size()-1; i >= 0; i--) {
            char c = s.get(i).charAt(s.get(i).length() - 1);
            if (c == 's') {
                s.remove(i);
            }

        }
        return s;
    }

}
ArrayList移除复数(ArrayList s){
对于(int i=s.size()-1;i>=0;i--){
charc=s.get(i).charAt(s.get(i).length()-1);
如果(c='s'){
s、 删除(i);
}
}
返回s;
}
}

想想从列表中删除“框”后会发生什么。“手机”指数下降1。如果它最初是列表中的第n项,那么它现在是列表中的第(n-1)项,不是吗?所以现在“电话”在列表中的位置与“盒子”原来的位置相同。另一方面,
i
增加1

现在您应该看到问题了,要检查“phones”,i
应该保持不变,因为删除“box”后,“phones”的索引减少了1

解决方案,只需从列表的末尾循环到开头,就不会出现以下问题:

for (int i = s.size() - 1; i >= 0; i--) {
    char c = s.get(i).charAt(s.get(i).length() - 1);
    if (c == 's') {
        s.remove(i);
    }

}

想想当你从列表中删除“盒子”后会发生什么。“手机”指数下降1。如果它最初是列表中的第n项,那么它现在是列表中的第(n-1)项,不是吗?所以现在“电话”在列表中的位置与“盒子”原来的位置相同。另一方面,
i
增加1

现在您应该看到问题了,要检查“phones”,i应该保持不变,因为删除“box”后,“phones”的索引减少了1

解决方案,只需从列表的末尾循环到开头,就不会出现以下问题:

for (int i = s.size() - 1; i >= 0; i--) {
    char c = s.get(i).charAt(s.get(i).length() - 1);
    if (c == 's') {
        s.remove(i);
    }

}

这是因为您正在迭代的列表正在同一循环中更新。所以,当您在上一次迭代中删除一个元素时,它的索引正在更新,循环根本不会拾取该元素。因此,解决方案应该是:

1)创建新列表并返回:

ArrayList<String> removePlurals(final ArrayList<String> s) {

    final ArrayList<String> updatedList = new ArrayList<String>();

    for (int i = 0; i < s.size(); i++) {
      final char c = s.get(i).charAt(s.get(i).length() - 1);
      if (c != 's') {
        updatedList.add(s.get(i));
      }

    }
    return updatedList;
  }
ArrayList<String> removePlurals(final ArrayList<String> s) {

        final Iterator<String> itr = s.iterator();
        while (itr.hasNext()) {
        final String x = itr.next();
        if (x.charAt(x.length() - 1) == 's') {
           itr.remove();
        }
        }
        return s;  
      }
ArrayList移除复数(最终ArrayList s){
最终ArrayList updatedList=新ArrayList();
对于(int i=0;i
2)使用迭代器:

ArrayList<String> removePlurals(final ArrayList<String> s) {

    final ArrayList<String> updatedList = new ArrayList<String>();

    for (int i = 0; i < s.size(); i++) {
      final char c = s.get(i).charAt(s.get(i).length() - 1);
      if (c != 's') {
        updatedList.add(s.get(i));
      }

    }
    return updatedList;
  }
ArrayList<String> removePlurals(final ArrayList<String> s) {

        final Iterator<String> itr = s.iterator();
        while (itr.hasNext()) {
        final String x = itr.next();
        if (x.charAt(x.length() - 1) == 's') {
           itr.remove();
        }
        }
        return s;  
      }
ArrayList移除复数(最终ArrayList s){
最终迭代器itr=s.Iterator();
while(itr.hasNext()){
最后一个字符串x=itr.next();
如果(x.charAt(x.length()-1)='s'){
itr.remove();
}
}
返回s;
}

发生这种情况是因为您正在迭代的列表正在同一循环中更新。所以,当您在上一次迭代中删除一个元素时,它的索引正在更新,循环根本不会拾取该元素。因此,解决方案应该是:

1)创建新列表并返回:

ArrayList<String> removePlurals(final ArrayList<String> s) {

    final ArrayList<String> updatedList = new ArrayList<String>();

    for (int i = 0; i < s.size(); i++) {
      final char c = s.get(i).charAt(s.get(i).length() - 1);
      if (c != 's') {
        updatedList.add(s.get(i));
      }

    }
    return updatedList;
  }
ArrayList<String> removePlurals(final ArrayList<String> s) {

        final Iterator<String> itr = s.iterator();
        while (itr.hasNext()) {
        final String x = itr.next();
        if (x.charAt(x.length() - 1) == 's') {
           itr.remove();
        }
        }
        return s;  
      }
ArrayList移除复数(最终ArrayList s){
最终ArrayList updatedList=新ArrayList();
对于(int i=0;i
2)使用迭代器:

ArrayList<String> removePlurals(final ArrayList<String> s) {

    final ArrayList<String> updatedList = new ArrayList<String>();

    for (int i = 0; i < s.size(); i++) {
      final char c = s.get(i).charAt(s.get(i).length() - 1);
      if (c != 's') {
        updatedList.add(s.get(i));
      }

    }
    return updatedList;
  }
ArrayList<String> removePlurals(final ArrayList<String> s) {

        final Iterator<String> itr = s.iterator();
        while (itr.hasNext()) {
        final String x = itr.next();
        if (x.charAt(x.length() - 1) == 's') {
           itr.remove();
        }
        }
        return s;  
      }
ArrayList移除复数(最终ArrayList s){
最终迭代器itr=s.Iterator();
while(itr.hasNext()){
最后一个字符串x=itr.next();
如果(x.charAt(x.length()-1)='s'){
itr.remove();
}
}
返回s;
}

除了问题中报告的问题之外:您还有一个问题,即从
数组列表的中间一次删除一个元素是非常低效的,因为您一直在
之间移动所有元素(i+1)
并将列表的末尾按一个位置移动,然后再对其中的大多数位置移动一次

性能不应该是您首先关心的问题-缓慢、正确的代码总是比快速、错误的代码好-但您应该牢记一些值得避免的问题:在这种情况下,它是从
数组列表的中间重复删除的

更好的解决办法是不要不断改变要素,