A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 殷婷婷 中级黑马   /  2013-10-8 21:04  /  1901 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 殷婷婷 于 2013-10-10 10:59 编辑

main函数中
ArrayList al = new ArrayList();
al.add(“----1”);
al.add(“----2”);
Iterator it = al.iterator();
while(it.hasNext())
{
       Objectobj = it.next();
       if(obj.equals(“----1”))
              it.remove();//我不明白的是此时----1已经被删掉了,obj此时怎么还会指向----1并输出呢?迭代器到底是怎么个原理?
   System.out.println(obj);
}
结果是:
----1
----2


评分

参与人数 1技术分 +1 收起 理由
黄文伯 + 1 如果将代码放在代码区内更便于交流,分数也.

查看全部评分

10 个回复

倒序浏览
落木萧萧 来自手机 高级黑马 2013-10-8 23:24:09
沙发
尝试着回答一下,可能是这样的,iterator里有个计数器,当你remove的时候这个计数器不会马上减一,因为程序迭代器要保证迭代过程中集合的完整性,所以再次执行next方法时,才会把那个计数器减一,也可以理解成“真正的”remove.所以输出的时候还是那个list。刚才说了,迭代的时候要保证完整性,所以绝对不能在remove后再remove或者add.爪机无力,纯手打,没
回复 使用道具 举报
落木萧萧 来自手机 高级黑马 2013-10-8 23:25:00
藤椅
没法组织语言,抱歉
回复 使用道具 举报
我来回答一下,~ 亲 , 你删的是容器里面的吧,~  但是你删除之前 已经把这个对象NEW出来给呢OBJ  

OBJ 和容器是没有联系的   明白呢吗 不懂在问
回复 使用道具 举报
你好,请问能说再详细点吗?为什么Obj和容器是没有关系的?迭代器到底是什么啊?
回复 使用道具 举报
迭代器(Iterator)

  迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

  Java中的Iterator功能比较简单,并且只能单向移动:

  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

  (2) 使用next()获得序列中的下一个元素。

  (3) 使用hasNext()检查序列中是否还有元素。

  (4) 使用remove()将迭代器新返回的元素删除。

  Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

迭代器应用:
list l = new ArrayList();
l.add("aa");
l.add("bb");
l.add("cc");
for (Iterator iter = l.iterator(); iter.hasNext();) {
  String str = (String)iter.next();
  System.out.println(str);
}
/*迭代器用于while循环
Iterator iter = l.iterator();
while(iter.hasNext()){
  String str = (String) iter.next();
  System.out.println(str);
}
*/
回复 使用道具 举报
你的答案我在百度上看过了。However,Thanks.
回复 使用道具 举报
张慧 中级黑马 2013-10-9 13:59:51
8#
这里的迭代器,你可以先看下ArrayList的源码,在ArrayList里有个私有成员:
private transient Object[] elementData;
这个是用来存集合中对象的。

ArrayList继承了AbstractList,在AbstractList里有个内部类 private class Itr implements Iterator<E> ;
这个就是迭代器。

it.remove();//我不明白的是此时----1已经被删掉了,obj此时怎么还会指向----1并输出呢?迭代器到底是怎么个原理?
其实在调用迭代器在调用自己的remove()方法的内部是调用了AbstractList的remove(int index)方法。至于这个index的值是怎么获得的,看源码后就知道,值是lastRet,这个是Itr (迭代器)中用来保存最后一个位置的下标。因为ArrayList继承了AbstractList,所以,在这里就要看一下ArrayList源码中的remove(index)方法,原代码:
  1. E oldValue = (E) elementData[index];

  2.         int numMoved = size - index - 1;
  3.         if (numMoved > 0)
  4.             System.arraycopy(elementData, index+1, elementData, index,
  5.                              numMoved);
  6.         elementData[--size] = null; // Let gc do its work

  7.         return oldValue;
  8.     }
复制代码
可以看出,他是将elementData中index位置之后的对象都向前移动,最后在让最后一个对象指向null.

即使是这样,但感觉被删除的对象,是没有立刻从对内存中释放的,他会再保留一段时间。

Objectobj = it.next();这里是将一个obj引用指向了那个地址。
当 System.out.println(obj)时,即使你感觉删除了那个对象,其实在内存中仍然存在,一段时间内,会有GC(垃圾回收机制)去检查,如果无用就会真正从内存中删除。

(其实就是引用去指向其他地址了,单这不代表那个地址就不存在了)


评分

参与人数 1技术分 +1 收起 理由
黄文伯 + 1 赞一个!

查看全部评分

回复 使用道具 举报
kmter 中级黑马 2013-10-9 23:02:45
9#
本帖最后由 kmter 于 2013-10-9 23:04 编辑

Object obj = it.next();
这里是将对象的引用即对象在内存中的首地址传递给了obj

it.remove();
这句话只是将当前的迭代元素的引用从集合中删除了,注意,删除的只是对象的引用,并非对象本身

System.out.println(obj);
由于obj任然指向内存中"----1”这个字符串,GC是不会将其回收的,故会出现你那样的疑问。

张慧已经分析了remove的源代码,希望可以帮到你理解这个问题。
回复 使用道具 举报
IT_JM 中级黑马 2013-10-9 23:28:35
10#
容器里面存储的是这些对象的哈希值,也就是地址,remove()只是删除了存在集合容器中的地址,但是这个对象还在内存中,没有被删除呢,而且你又把这个对象给了Object,相当于父类指向子类对象了,不就是多态嘛。

再给你打个比喻:你有一个很多东西,突然有一天有一个东西你不喜欢了或者不想要了,你把它送给了别人(当然是能用的,不是坏的,哈哈~),是不是别人拿着这个东西也能用啊。你这个送的过程就相当于那个remove()
回复 使用道具 举报
kmter 发表于 2013-10-9 23:02
Object obj = it.next();
这里是将对象的引用即对象在内存中的首地址传递给了obj

谢谢,懂了哦:handshake
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马