集合常用的3种遍历方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了集合常用的3种遍历方式相关的知识,希望对你有一定的参考价值。

参考技术A

1 迭代器 Iterator

运行结果

说明上面例子中for和while不能使用同一个iterator对象,因为在while循环中iterator已经返回最后一个元素,指针指向的下一个元素为空了,即hasNext()返回值为false,不能用该迭代器的hasNext()作为for循环的判断条件。

2 转换为Object[]进行遍历

运行结果

3 使用增强for(foreach)实现遍历

运行结果

`注意·
增强for有个缺点,如果集合或者数组为null,会报空指针异常(NullPointerException),在调用增强for时最好先做判断。通过反编译可以看到增强for是用iterator的for循环实现的,是iterator的替代,iterator也有这种空指针异常的问题。

4说明

运行结果,集合元素内容不变

*4.2 并行修改异常ConcurrentModificationException
4.2.1 迭代器和foreach(增强for)遍历的循环中,不能出现集合对象本身调用方法更改集合内容,否则运行会报错 java.util.ConcurrentModificationException(并修改异常)
原因是--迭代器和foreach都是依赖集合而存在的,如果集合更改了,迭代器和增强for都不知道,所以就报并行修改异常。

运行结果

4.2.2 解决办法
A 使用普通for循环,在循环中根据判断集合对内容进行修改
B 使用迭代器对集合内容进行修改,Iterator接口中没有该方法,它的子类ListIterator接口中提供add()
详情请参考: https://www.jianshu.com/p/94b12cceb6c7 中(二、3.3)
4.3 一个集合对象的迭代器循环中多次使用next(),会出现java.util.NoSuchElementException异常。

运行结果

4.4 迭代器的remove()能删除next()返回的元素,这也算是更改了集合的内容,不能用元素的值在进行迭代进行解释,遗留

运行结果

JAVA集合01_Collection接口概述常用方法集合和数组互转3种遍历方式

文章目录

①. Collection接口概述

  • ①. 单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
  1. JDK不提供此接口的任何直接实现,它提供更具体的子接口 (如 Set 和 List)实现
  2. set:元素无序、不可重复的集合 - 类似高中集合
  3. List:元素有序,可重复的集合 - "动态"数组
  4. Map接口:具有映射关系"key-value"对的集合 - - 类似于高中的函数 y=f(x)(x1,y1)(x2,y2)
    Collection接口继承树,虚线是实现,实线是继承


  • ②. 为什么集合使用什么样的泛型,迭代器就用什么泛型 ?
	List<String>list=new ArrayList<>();
	public interface List<E> extends Collection<E> 
		
	
	//Collection继承了Iterable
	public interface Collection<E> extends Iterable<E> 
	    Iterator<E> iterator();
	
  • ③. 迭代器用什么泛型,next()方法就用什么泛型

②. Collection常用方法

  • ①. boolean add(E e):添加元素(注意这里的E是泛型类型)

  • ②. boolean addAll(Collection<? extends E> c):将形成中包含的c所有元素添加到当前集合中(向下限定, 固定上边界)

  • ③. boolean remove(Object obj):从集合中移除指定的元素[ 重写了equals方法]**

  • ④. void clear():清除集合中的元素

  • ⑤. boolean contains(Object o):判断集合中是否存在指定的元素[ 重写了equals方法]

  • ⑥. boolean isEmpty():判断集合是否为空

  • ⑦. int size():集合的长度,也就是集合中元素的个数

  • ⑧. Iteratoriterator( ):`返回一个Iterator接口,实现类的对象,进而实现集合的遍历

  • ⑨. equal(Object obj):判断两个集合中所有元素是否完全相同

  • 将数组转成集合: Collection coll1 = Arrays.asList(1, 2, 3);

  • 将集合转成数组: Object [ ] obj=coll1.toArray();

       //创建集合对象
        Collection<String> c = new ArrayList<String>();

        //boolean add(E e):添加元素
//        System.out.println(c.add("hello"));
//        System.out.println(c.add("world"));
//        System.out.println(c.add("world"));
        c.add("hello");
        c.add("world");
        c.add("java");

        //boolean remove(Object o):从集合中移除指定的元素
//        System.out.println(c.remove("world"));
//        System.out.println(c.remove("javaee"));

        //void clear():清空集合中的元素
//        c.clear();

        //boolean contains(Object o):判断集合中是否存在指定的元素
//        System.out.println(c.contains("world"));
//        System.out.println(c.contains("javaee"));

        //boolean isEmpty():判断集合是否为空
//        System.out.println(c.isEmpty());

        //int size():集合的长度,也就是集合中元素的个数
        System.out.println(c.size());


        //输出集合对象
        System.out.println(c);

③. 数组转换成集合

  • ①. 数组换成成集合,虽然不能增加或减少元素,但是可以用集合的思想操作数组,也就是说可以使用其他集合中的方法(除了增加和减少都能使用)

  • ②. 基本数据类型的数组转换成集合,会将整个数组当成一个对象转换

  • ③. 将数组转成集合,数组必须是引用数据类型

        String[]arr="a","b","c";
        List<String> list= Arrays.asList(arr);
        System.out.println(list);
        //list.add("d");//UnsupportedOperationException
        //System.out.println(list);
        int[]arr2=11,22,33,44,55;
        //List<int[]ar> listInt=Arrays.asList(arr2);
        List listInt=Arrays.asList(arr2);
        System.out.println(listInt);//输出的是地址值[[I@3578436e]
        //基本数据类型的数组转换成集合,会将整个数组当成一个对象转换
        Integer[]arr=11,22,33,44,55;
        List<Integer>list=Arrays.asList(arr);
        System.out.println(list);//[11, 22, 33, 44, 55]

④. 集合转换成数组

  • ①. 当集合转换数组时,数组的长度如果<=集合的size,转换后的数组长度等于集合的size

  • ②. 当集合转换数组时,数组的长度如果>=集合的size,分配的数组长度,就和你指定的长度一样[new String[10]]

         //谁大集合长度就等于谁
         ArrayList<String>list=new ArrayList<>();
         list.add("a");
         list.add("b");
         list.add("c");
         list.add("d");
     
         String[]str=list.toArray(new String[0]);
         for(String str2:str)
             System.out.println(str2);
         

⑤. 集合的遍历方式

  • ①. Iterator接口的概述
  1. Iterator对象称为迭代器(设计模式的一种),主要用于遍历Collection集合中的元素。
  2. Iterator仅用于遍历集合,Iterator 本身并不提供承装对象的能力。如果需要创建 Iterator 对象,则必须有一个被迭代的集合
  3. Iterator<E> iterator ():返回此集合中元素的迭代器,通过集合的iterator () 方法得到
  4. boolean hasNext():如果迭代具有更多的元素,则返回true
  5. E next():返回迭代中的下一个元素,并把指针向下移动一位
 //迭代器的原理及源码解析
 Iterator<String> iterator=coll.iterator();//是通过多肽的方式得到的Iterator的对象
  /*
        public Iterator<E> iterator() 
            return new ArrayList.Itr();
        
        private class Itr implements Iterator<E> 
           .......
        
         */

   while(iterator.hasNext())
             /*
               Iterator中的常用方法 :
               E next():返回迭代中的下一个元素
               boolean hasNext():如果迭代具有更多的元素,则返回true
             * */
             //System.out.println(iterator.next());
             String s=iterator.next();
             System.out.println(s);//String类实现了toString方法
         
  • ②. 增强for:简化数组和Collection集合遍历(它是JDK5 之后出现的,其内部原理就是一个Iterator迭代器)

   //使用增强for循环实现数组的便利遍历
  @Test
	public void test3() 
		String[]str=new String[]"aa","bb","cc";
		for(String s:str)
			System.out.println(s);
		
		
	
  • ③. 普通for循环
	for (int i = 0; i <list.size() ; i++) 
	    Student s=list.get(i);
	    System.out.println(s.getId()+" "+s.getName());
	 
  • ④. 三种迭代能否删除
  1. 普通for循环,可以删除,但是索引要 i- -
  2. 迭代器,可以删除,但是必须使用迭代器自身的remove方法,否则会出现并发修改异常
  3. 增强for循环不能删除
  public void fun1()
     ArrayList<String> list=new ArrayList<>();
     list.add("AAA");
     list.add("BBB");
     list.add("BBB");
     list.add("CCC");
     list.add("DDD");
     //1.普通for循环进行删除
      /*  for (int i = 0; i < list.size(); i++) 
            String str=list.get(i);
            if("BBB".equals(str))
                //两个BBB在一起的话,会留住一个BBB
                //两个BBB分割的话,两个都会删除
                //要想删除两个BBB必须使用i--,每次删除后,指针又回到原来的位置
                //list.remove(i);
                list.remove(i--);
            
        */
        //2.迭代器删除
       /* Iterator<String>it=list.iterator();
        while(it.hasNext())
            if("BBB".equals(it.next()))
                //ConcurrentModificationException
                //list.remove("BBB"):不能用集合的删除方法,因为迭代过程中如果集合修改会出现并发修改异常
                it.remove();
            

        */
     /*  for(Iterator<String>it2=list.iterator();it2.hasNext();)
           if("BBB".equals(it2.next()))
               //ConcurrentModificationException
               //list.remove("BBB"):不能用集合的删除方法,因为迭代过程中如果集合修改会出现并发修改异常
               it2.remove();
           
       */
       //3.增强for循环
        /*
         增强for循环不能删除,因为底层是一个iterator
        * */
        for(String str2:list)
            if("BBB".equals(str2))
                // list.remove("BBB");
            
        
        System.out.println(list);
    

以上是关于集合常用的3种遍历方式的主要内容,如果未能解决你的问题,请参考以下文章

Map集合的四种常用遍历方式整理

Arraylist 三种常用遍历

Java集合专题(超级详细)

常用集合类

java中map的常用遍历方法

Java map 详解 - 用法遍历排序常用API等