程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

Java中list集合遍历

发布于2023-02-19 09:51     阅读(313)     评论(0)     点赞(1)     收藏(0)


目录

遍历的3种方式

方式1:迭代器循环

Iterator迭代器

功能:

注意事项:

方法:

ListIterator迭代器

功能:

注意:

方法:

方式2:增强for循环

方式3:普通for循环


遍历的3种方式

        1,迭代器循环

        2,增强for循环

        3,普通for循环

方式1:迭代器循环

迭代器创建后,最好立即使用,不然之后对集合进行的增删改操作会导致迭代器遍历报错

原因:

        1,系统创建迭代器时,会初始化 字段  expectedModCount = modCount,迭代器遍历获取字段时,next()会先对该字段进行校验

        2, 对集合进行的  任何增删 操作都会导致  modCount++,从而在迭代器遍历时,在expectedModCount == modCount  中返回false,导致报错

  1. private class Itr implements Iterator<E> {
  2. int cursor; // index of next element to return
  3. int lastRet = -1; // index of last element returned; -1 if no such
  4. int expectedModCount = modCount; //初始化 expectedModCount 字段
  5. public E next() {
  6. //获取下个元素时 , 会先对字段 expectedModCount == modCount 进行校验
  7. checkForComodification();
  8. ....
  9. }
  10. final void checkForComodification() {
  11. if (modCount != expectedModCount) // 不相等,会报错
  12. throw new ConcurrentModificationException();
  13. }
  14. }

Iterator迭代器

功能:

        1,单向遍历

        2,遍历过程中,不能增加和修改元素

        3,遍历过程中,只能使用  Iterator提供的remove()  删除元素,不能使用Collection.remove()  删除元素

注意事项:

           删除元素前,需要先调用next(),否则会报错

           因为remove()中,更新 lastRet=-1,而要调用remove(),会先校验lastRet<0,抛异常

范例:

  1. Collection<Student> c = new ArrayList<Student>();
  2. Student s1 = new Student("zhang", 12);
  3. Student s2 = new Student("lsii", 23);
  4. Student s3 = new Student("wangwu", 24);
  5. Student s4 = new Student("zhoaliu", 24);
  6. c.add(s1);
  7. c.add(s2);
  8. c.add(s3);
  9. c.add(s4);
  10. Iterator<Student> itStu = c.iterator();
  11. while (itStu.hasNext()) {
  12. Student s = itStu.next();
  13. if (s.getName() == "lisi") {
  14. // c.remove(s1); 会报错
  15. itStu.remove(); //删除遍历得到的元素
  16. }
  17. System.out.println(s);
  18. }
  19. System.out.println(c);

方法:

        hasNext()        是否还有下一个元素:通过cursor字段,判断是否到达集合边界

        next()               先让游标后移一位,再返回索引元素

        remove()          删除元素

  1. public E next() {
  2. checkForComodification();
  3. int i = cursor;
  4. ...
  5. Object[] elementData = ArrayList.this.elementData;
  6. ...
  7. cursor = i + 1;
  8. return (E) elementData[lastRet = i];
  9. }
  10. //不能直接调用,remove前需要调用next(),因为本方法中 lastRet字段
  11. public void remove() {
  12. if (lastRet < 0)
  13. throw new IllegalStateException();
  14. checkForComodification();
  15. try {
  16. ArrayList.this.remove(lastRet);
  17. cursor = lastRet;
  18. lastRet = -1; //更新 lastRet
  19. expectedModCount = modCount; //执行完 remove后,更新 expectedModCount
  20. } catch (IndexOutOfBoundsException ex) {
  21. throw new ConcurrentModificationException();
  22. }
  23. }

ListIterator迭代器

描述:        弥补了Iterator迭代过程中,不能增加元素

功能:

        1,双向遍历

        2,遍历过程中,可以使用迭代器方法,增删改集合元素

注意:

        1,删除元素前,必须调用next(),否则会报错

           因为remove()中,更新 lastRet=-1,而要调用remove(),会先校验lastRet<0,抛异常

        2,下面代码中,如果没有调用next(),只是单纯的add(), 会导致死循环,直到内存溢出,引发错误

                解决方案:       

                     add()  和 next()  一起使用

范例:

  1. ArrayList<Student> c = new ArrayList<Student>();
  2. Student s1 = new Student("zhang", 12);
  3. Student s2 = new Student("lsii", 23);
  4. Student s3 = new Student("wangwu", 24);
  5. Student s4 = new Student("zhoaliu", 24);
  6. c.add(s1);
  7. c.add(s2);
  8. c.add(s3);
  9. c.add(s4);
  10. ListIterator<Student> listIterator = c.listIterator();
  11. while(listIterator.hasNext()){
  12. listIterator.add(s3);
  13. // listIterator.remove(); //直接删除会报错,需要先获取,再删除,
  14. //因为remove()后,更新 lastRet=-1
  15. Student next = listIterator.next();
  16. System.out.println(next);
  17. }

方法:

        hasNext()        是否还有下一个元素:通过cursor字段,判断是否到达集合边界

                                继承自Iterator

        next()               返回下一个元素,继承自Iterator

        hasPrevious     是否还有上一个元素

        previous()        返回上一个元素

        add ()            增加元素

        remove()          删除元素,继承自Iterator

  1. private class ListItr extends Itr implements ListIterator<E> {
  2. ListItr(int index) {
  3. super();
  4. cursor = index;
  5. }
  6. public boolean hasPrevious() {
  7. return cursor != 0;
  8. }
  9. public E previous() {
  10. checkForComodification();
  11. int i = cursor - 1;
  12. ...
  13. Object[] elementData = ArrayList.this.elementData;
  14. ...
  15. cursor = i;
  16. return (E) elementData[lastRet = i];
  17. }
  18. public void add(E e) {
  19. checkForComodification();
  20. try {
  21. int i = cursor;
  22. ArrayList.this.add(i, e);
  23. cursor = i + 1;
  24. lastRet = -1; //更新 lastRet
  25. expectedModCount = modCount; //执行完add后,更新 expectedModCount
  26. } catch (IndexOutOfBoundsException ex) {
  27. throw new ConcurrentModificationException();
  28. }
  29. }

方式2:增强for循环

  1. Collection<String> strC = new ArrayList<String>();
  2. strC.add("fa");
  3. strC.add("");
  4. strC.add("");
  5. strC.add("");
  6. strC.add("ffdasfa");
  7. for (String s : strC) {
  8. System.out.println(s);
  9. }

底层实现:

        增强for循环,运行的时候,编译器为其生成1个Iterator迭代器,调用iterator的hasNext(),next()方法进行遍历

缺点: 和iterator迭代器一样,只读

        1,只能单向遍历

        2,遍历时,不能 向集合中 增加和修改元素,不能删除元素

方式3:普通for循环

优势:可以在 遍历集合的同时,对集合元素进行增删改



所属网站分类: 技术文章 > 博客

作者:听说你没有见过我

链接:http://www.javaheidong.com/blog/article/642089/ead3ecf3a80e6092b66f/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

1 0
收藏该文
已收藏

评论内容:(最多支持255个字符)