黑马程序员技术交流社区

标题: 关于LinkedList存储自定义对象并遍历时出现的疑问 [打印本页]

作者: 朱盛文    时间: 2013-3-18 22:35
标题: 关于LinkedList存储自定义对象并遍历时出现的疑问
本帖最后由 朱盛文 于 2013-3-18 23:05 编辑
  1. package cn.itcast_Test;

  2. import java.util.Iterator;
  3. import java.util.LinkedList;

  4. import cn.itcast.Student;             //已知定义了一个Student类,具有name和age两个属性

  5. /*
  6. * 需求:LinkedList存储自定义对象并遍历输出(加入泛型)
  7. */
  8. public class LinkedListTest {
  9.         public static void main(String[] args) {
  10.                 // 创建集合对象
  11.                 LinkedList<Student> link = new LinkedList<Student>();

  12.                 // 创建元素对象
  13.                 Student s1 = new Student("zhangsan", 22);
  14.                 Student s2 = new Student("lisi", 24);
  15.                 Student s3 = new Student("wangwu", 25);               

  16.                 // 添加元素
  17.                 link.addLast(s1);
  18.                 link.addLast(s2);
  19.                 link.addLast(s3);        

  20.                 // 遍历
  21.                 // 方式1
  22.                 Iterator<Student> it = link.iterator();
  23.                 while (it.hasNext()) {
  24.                         Student s = it.next();
  25.                         System.out.println(s.getName() + "***" + s.getAge());
  26.                 }

  27.                 System.out.println("***************************");

  28.                 // 方式2
  29.                 for (int x = 0; x < link.size(); x++) {
  30.                         Student s = link.remove(x);
  31.                         System.out.println(s.getName() + "***" + s.getAge());
  32.                 }

  33.         }
  34. }
复制代码
运行结果如下:
zhangsan***22
lisi***24
wangwu***25
***************************
zhangsan***22
wangwu***25

方式2的结果为什么会变成这样?想不通……
作者: 夏晓彤    时间: 2013-3-18 22:44
本帖最后由 夏晓彤 于 2013-3-18 22:45 编辑

LinkedListTest的emove方法是打印并删除,
for (int x = 0; x < link.size(); x++) {
                        Student s = link.remove(x);
                        System.out.println(s.getName() + "***" + s.getAge());
当x=0时,执行到  Student s = link.remove(x);,
s=s1,并且把s1从集合中删除,这时候 link中就没有s1了,link集合中第一个是s2,第二个是s3,这时候执行了x++,所以再循环时不是从link第一个元素开始取了直接取了s3,
你可以这么写for (int x = 0; x < link.size(); ) {
                        Student s = link.remove(x);
                        System.out.println(s.getName() + "***" + s.getAge());
把循环的x++语句去掉,这样结过就一样了
作者: 李易烜    时间: 2013-3-18 22:46
   Student s = link.remove(x);
上面语句执行后,这里的link就变了;所以是wangwu***25这个结果。

作者: 翁鹏    时间: 2013-3-18 22:54
好久没在论坛回答问题了 呵呵
你这个很简单,你可能没太注意。

该开始时集合中角标对应
zhangsan(0)   lisi(1)  wangwu(2)         第一次循环调用 remove(0)  集合中删除了zhangsan

此时集合中角标对应
lisi(0)   wangwu(1)     第二次调用remove(1)   集合中删除了wangwu

所以就是你的那个结果咯


作者: 张世钦    时间: 2013-3-18 23:00
涉及指针问题,你remove后集合中对象的角标就变了,
for (int x = 0; x < link.size(); x++) {
                        Student s = link.remove(x);
//移除后是获取了移除的对象;但是集合中只有两个对象了,lisi***24和wangwu***25 你下一次循环x=1,也就是第二个对象,当然打印wangwu***25
//所以在遍历集合时最好不要做增删操作,容易出现安全问题
                        System.out.println(s.getName() + "***" + s.getAge());
                }

作者: 朱盛文    时间: 2013-3-18 23:04
夏晓彤 发表于 2013-3-18 22:44
LinkedListTest的emove方法是打印并删除,
for (int x = 0; x < link.size(); x++) {
                    ...

明白了,谢谢哈




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2