Java易错知识点(1)

来源:互联网 发布:mac图片导出到硬盘 编辑:程序博客网 时间:2024/05/24 05:49

Java易错知识点(1) - 关于ArrayList移除元素后剩下的元素会立即重排

原创 2014年10月20日 15:14:35

帮一个网友解答问题时,发现这样一个易错知识点,现总结如下:


1、易错点:

ArrayList移除元素后,剩下的元素会立即重排,他的 size() 也会立即减小,在循环过程中容易出错。(拓展:延伸到所有的集合是否可行)


2、易错点分析:

在for循环遍历ArrayList时,在循环中移除元素后,集合的size()会立即减1

剩下的元素也会重新排列,被移除元素后面元素的下标会发生变化,即后面的元素小标会减1

此时在for循环中的第二个参数 i < list.size() 就不是原来集合的大小了,而是比上一次循环小1

而循环变量 i 的值还是正常递增

如果继续遍历集合,就容易漏掉某个元素


3、实例分析:

此实例的目的是:去除集合中带有#字符的url

(1)错误版本:

[java] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;">import java.util.ArrayList;  
  2.   
  3. public class GouLv {  
  4.     public static void main(String[] args) throws Exception {  
  5.         ArrayList<String> urls = new ArrayList<String>();  
  6.         urls.add("http://www.baidu.com");  
  7.         urls.add("http:/#/www.baidu.com");  
  8.         urls.add("http://www#.zxitb.com");  
  9.         urls.add("http://www.zxitb.com");  
  10.               
  11.         int index;  
  12.         for (int i = 0; i < urls.size(); i++) {  
  13.             index = -1;  
  14.             String url = urls.get(i);  
  15.             index = url.indexOf('#');  
  16.             if(index != -1){  
  17.                 urls.remove(url);  
  18.             }else {  
  19.                 System.out.println(url);  
  20.             }  
  21.         }  
  22.           
  23.         for (int i = 0; i < urls.size(); i++) {  
  24.             System.out.println("去除#后的url : " + urls.get(i));          
  25.         }  
  26.     }  
  27. }  
  28.   
  29. -----------------------------------------------  
  30. 输出结果为:  
  31. http://www.baidu.com  
  32. http://www.zxitb.com  
  33. 去除#后的url : http://www.baidu.com  
  34. 去除#后的url : http://www#.zxitb.com  
  35. 去除#后的url : http://www.zxitb.com  
  36.   
  37. ------------------------------------------------  
  38. 拓展:  
  39. 如果map中的元素这样放  
  40. urls.add("http://www.baidu.com");  
  41. urls.add("http:/#/www.baidu.com");  
  42. urls.add("http://www.zxitb.com");  
  43. urls.add("http://www#.zxitb.com");  
  44. 那结果为  
  45. http://www.baidu.com  
  46. http://www.zxitb.com  
  47. 去除#后的url : http://www.baidu.com  
  48. 去除#后的url : http://www.zxitb.com  
  49. 感觉上时达到了目的,其实不然</span>  

(2)错误分析版本:

[java] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;">import java.util.ArrayList;  
  2.   
  3. public class GouLv {  
  4.     public static void main(String[] args) throws Exception {  
  5.         ArrayList<String> urls = new ArrayList<String>();  
  6.         urls.add("http://www.baidu.com");  
  7.         urls.add("http:/#/www.baidu.com");  
  8.         urls.add("http://www#.zxitb.com");  
  9.         urls.add("http://www.zxitb.com");  
  10.               
  11.         int index;  
  12.         for (int i = 0; i < urls.size(); i++) {  
  13.             index = -1;  
  14.             System.out.println("循环次数===========" + (i+1));  
  15.             String url = urls.get(i);  
  16.             index = url.indexOf('#');  
  17.             if(index != -1){  
  18.                 System.out.println("有#的url: " + url);  
  19.                 urls.remove(url);  
  20.                   
  21.                 System.out.println("移除元素后urls的size: " + urls.size());  
  22.                 for(int j = 0; j < urls.size(); j++){ //移除元素后打印urls中的元素  
  23.                     System.out.println("移除元素后urls中下标为【  " + j + " 】的元素" + urls.get(j));  
  24.                 }  
  25.             }else {  
  26.                 System.out.println("没有#的url: " + url);  
  27.             }  
  28.               
  29.             System.out.println("urls的大小: " + urls.size() + "=====下一次循环i的值将会为: " + (i+1));  
  30.         }  
  31.           
  32.         for (int i = 0; i < urls.size(); i++) { //打印最终结果  
  33.             System.out.println("去除#后的url : " + urls.get(i));          
  34.         }  
  35.     }  
  36.       
  37. }  
  38.   
  39. ------------------------------------------------------------  
  40. 结果:  
  41. 循环次数===========1  
  42. 没有#的url: http://www.baidu.com  
  43. urls的大小: 4=====下一次循环i的值将会为: 1  
  44. 循环次数===========2  
  45. 有#的url: http:/#/www.baidu.com  
  46. 移除元素后urls的size: 3  
  47. 移除元素后urls中下标为【  0  】的元素http://www.baidu.com  
  48. 移除元素后urls中下标为【  1  】的元素http://www#.zxitb.com  
  49. 移除元素后urls中下标为【  2  】的元素http://www.zxitb.com  
  50. urls的大小: 3=====下一次循环i的值将会为: 2  
  51. 循环次数===========3  
  52. 没有#的url: http://www.zxitb.com  
  53. urls的大小: 3=====下一次循环i的值将会为: 3  
  54. 去除#后的url : http://www.baidu.com  
  55. 去除#后的url : http://www#.zxitb.com  
  56. 去除#后的url : http://www.zxitb.com</span>  

分析:

此时第一次循环的是http://www.baidu.com,第二次循环的是http:/#/www.baidu.com

由于第二次循环移除了元素,所以size()减1就是3,剩下的元素也重新排列。而此时 i 为2,就是循环的新集合中的http://www.zxitb.com(第三次循环)

此时符合条件,循环结束

跳过了http://www#.zxitb.com的循环


更改思路:

移除元素后,修改循环中的第二个参数或者第三个参数。此时我在移除元素后把循环变量 i 的值减1

 

(3)正确版本:

[java] view plain copy
  1. <span style="font-family:KaiTi_GB2312;font-size:18px;">import java.util.ArrayList;  
  2.   
  3. public class GouLv {  
  4.     public static void main(String[] args) throws Exception {  
  5.         ArrayList<String> urls = new ArrayList<String>();  
  6.         urls.add("http://www.baidu.com");  
  7.         urls.add("http:/#/www.baidu.com");  
  8.         urls.add("http://www#.zxitb.com");  
  9.         urls.add("http://www.zxitb.com");  
  10.               
  11.         int index;  
  12.         for (int i = 0; i < urls.size(); i++) {  
  13.             index = -1;  
  14.             String url = urls.get(i);  
  15.             index = url.indexOf('#');  
  16.             if(index != -1){  
  17.                 System.out.println("有#的url: " + url);  
  18.                 urls.remove(url);  
  19.                 i-- ;  
  20.             }else {  
  21.                 System.out.println("没有#的url: " + url);  
  22.             }  
  23.         }  
  24.           
  25.         for (int i = 0; i < urls.size(); i++) { //打印最终结果  
  26.             System.out.println("去除#后的url : " + urls.get(i));          
  27.         }  
  28.     }  
  29.       
  30. }  
  31.   
  32. ---------------------------------------------------------  
  33. 结果:  
  34. 没有#的url: http://www.baidu.com  
  35. 有#的url: http:/#/www.baidu.com  
  36. 有#的url: http://www#.zxitb.com  
  37. 没有#的url: http://www.zxitb.com  
  38. 去除#后的url : http://www.baidu.com  
  39. 去除#后的url : http://www.zxitb.com</span>  

OK ! 问题解决!


原创粉丝点击