java基础-Java集合框架-集合元素的遍历-Iterator迭代器

14 篇文章 0 订阅
本文详细介绍了Java集合框架中元素的遍历方式,重点讲解了迭代器Iterator的使用,包括其hasNext()和next()方法,以及如何在遍历时删除元素。还探讨了增强for循环(foreach)的实现原理和注意事项,展示了错误的迭代器使用示例,并提供了使用示例代码。
摘要由CSDN通过智能技术生成

Java集合框架-集合元素的遍历

  1. 集合元素的遍历操作,使用迭代器Iterator接口
  • Iterator对象称为迭代器(设计模式的一种),主要用于遍历Collection集合中的元素。

  • GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中的各个元素,而又不需要暴露该对象的内部细节。迭代器模式,就是为容器而生。

  • Collection接口继承了java.lang.Iterable接口,改接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了iterator接口的对象

    • package java.lang;
      
      import java.util.Iterator;
      
      /** Implementing this interface allows an object to be the target of
       *  the "foreach" statement.
       * @since 1.5
       */
      public interface Iterable<T> {
      
          /**
           * Returns an iterator over a set of elements of type T.
           * 
           * @return an Iterator.
           */
          Iterator<T> iterator();
      }
      
      public interface Collection<E> extends Iterable<E> {
      	
          /**
           * Returns an iterator over the elements in this collection.  There are no
           * guarantees concerning the order in which the elements are returned
           * (unless this collection is an instance of some class that provides a
           * guarantee).
           *
           * @return an <tt>Iterator</tt> over the elements in this collection
           */
          Iterator<E> iterator();
      }
      
  • Iterator仅用于遍历集合,Iterator本身并不提供承装对象的能力。如果需要创建Iterator对象,则必须有一个被迭代的集合。

  • 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前

  1. 迭代器Iterator
  • 迭代器的抽象方法

    • 方法说明
      hasNext()判断当前节点是否还有子节点,true为有,false为没有
      next()返回迭代器中的下一个元素

在这里插入图片描述

  • 在调用iterator.next()方法之前必须调用iterator.hasNext()进行检测。若不调用,且下一条无记录,直接调用iterator.next()则会抛出异常NoSuchElementException()

  • 迭代器的使用:

    • package com.jl.java.base.collection;
      
      import org.junit.Test;
      
      import java.util.ArrayList;
      import java.util.Collection;
      import java.util.Iterator;
      
      /**
       * @author jiangl
       * @version 1.0
       * @date 2021/4/22 10:27
       */
      public class IteratorTest {
          @Test
          public void test1(){
              Collection collection = new ArrayList();
              collection.add(1);
              collection.add("dfadfas");
              collection.add(false);
              collection.add(new String("fdasdf"));
      
              Iterator iterator = collection.iterator();
              System.out.println(iterator.next());
              System.out.println(iterator.next());
              System.out.println(iterator.next());
              System.out.println(iterator.next());
              //报异常:NoSuchElementException
      //        System.out.println(iterator.next());
      
              Iterator iterator1 = collection.iterator();
              for(;iterator1.hasNext();){
                  System.out.println(iterator1.next());
              }
      
      
              Iterator iterator2 = collection.iterator();
              while(iterator2.hasNext()){
                  System.out.println(iterator2.next());
              }
          }
      }
      
  1. 迭代器执行原理
  • 如图:
    在这里插入图片描述
  1. 迭代器的错误使用
  • 例子:

    • //二次下移
      Iterator iterator3 = collection.iterator();
      while(iterator3.next() != null){
          System.out.println(iterator3.next());
      }
      
      //每次都会创建新的迭代器
      while(collection.iterator().hasNext()){
          System.out.println(collection.iterator().next());
      }
      
  1. 迭代器的remove()方法
  • Iterator内部定义了一个remove()方法,可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove()。(此方法有线程安全问题,会触发fast-fail机制)

  • 注意:

    • Iterator可以删除集合中的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法
    • 如果还未调用next()或在一次次调用next方法之后已经调用了remove方法,再调用remove都会报错IllegalStateException
  • @Test
    public void test4(){
        Collection collection = new ArrayList();
        collection.add(1);
        collection.add("dfadfas");
        collection.add(false);
        collection.add(new String("fdasdf"));
    
        System.out.println(collection);
        Iterator iterator = collection.iterator();
        while(iterator.hasNext()){
            if(iterator.next().equals("dfadfas")){
                iterator.remove();
            }
        }
        System.out.println(collection);
    }
    
  1. 使用foreach(增强for循环)循环遍历集合
  • Java5.0提供了foreach循环迭代方法Collection和数组

  • 遍历操作不需要获取Collection或数组的长度,无需使用索引访问元素。

  • 遍历集合的底层调用Iterator完成操作

  • foreach还可以用来遍历数组

  • 使用方法: for(集合或数组元素的类型 局部变量 : 集合或数组对象)

    • @Test
      public void test5(){
          Collection collection = new ArrayList();
          collection.add(1);
          collection.add("dfadfas");
          collection.add(false);
          collection.add(new String("fdasdf"));
      
          System.out.println(collection);
          //for(数组元素的类型 局部变量 : 集合对象)
          for (Object o: collection){
      
              System.out.println(collection);
          }
      }
      
    • 编译后:(仍使用的是迭代器)

      • @Test
        public void test5() {
            Collection collection = new ArrayList();
            collection.add(1);
            collection.add("dfadfas");
            collection.add(false);
            collection.add(new String("fdasdf"));
            System.out.println(collection);
            Iterator i$ = collection.iterator();
        
            while(i$.hasNext()) {
                Object o = i$.next();
                System.out.println(collection);
            }
        
        }
        
  • 增强for需要注意的问题:

    • 在foreach中,对局部变量进行赋值,不会改变原集合或数组对象内的元素内容。因为foreach是将元素取出传递给了局部变量。

    • 测试代码:

    • @Test
      public void test6(){
          Collection<MyObject> collection = new ArrayList();
          collection.add(new MyObject("123",1));
          collection.add(new MyObject("1223",1));
          collection.add(new MyObject("1223",1));
      
          System.out.println(collection);
          for (MyObject o: collection){
              o = new MyObject("1",1);
          }
          System.out.println(collection);
      }
      
      class MyObject{
          private String name;
          private int age;
      
          public MyObject(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "MyObject{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
    • 结果:

      • [MyObject{name=‘123’, age=1}, MyObject{name=‘1223’, age=1}, MyObject{name=‘1223’, age=1}]
        [MyObject{name=‘123’, age=1}, MyObject{name=‘1223’, age=1}, MyObject{name=‘1223’, age=1}]
    • 从编译后的class文件看:

      • @Test
        public void test6() {
            Collection<MyObject> collection = new ArrayList();
            collection.add(new MyObject("123", 1));
            collection.add(new MyObject("1223", 1));
            collection.add(new MyObject("1223", 1));
            System.out.println(collection);
            Iterator i$ = collection.iterator();
        
            while(i$.hasNext()) {
                MyObject o = (MyObject)i$.next();
                new MyObject("1", 1);
            }
        
            System.out.println(collection);
        }
        
      • foreach步骤是先将iterator.next()对象取出,赋值给MyObject o

      • 在创建了一个新对象new MyObject(“1”,1)

      • 并没有修改原集合中的内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值