黑马程序员技术交流社区

标题: 【石家庄校区】集合的回顾与迭代器使用 [打印本页]

作者: 1597854328    时间: 2019-1-22 15:22
标题: 【石家庄校区】集合的回顾与迭代器使用

1.1.1 集合的创建
创建集合的常用格式在此说明一下:
A:导包:import java.util.ArrayList;
B:创建对象:与其他普通的引用数据类型创建方式完全相同,但是要指定容器中存储的数据类型:
ArrayList<要存储元素的数据类型> 变量名 = new ArrayList<要存储元素的数据类型>();
集合中存储的元素,只能为<>括号中指定的数据类型元素;
“<要存储元素的数据类型>”中的数据类型必须是引用数据类型,不能是基本数据类型;
下面给出8种基本数据类型所对应的引用数据类型表示形式:

1.1.2 集合的常用方法
方法声明
功能描述
boolean addObject obj
将指定元素obj追加到集合的末尾
Object getint index
返回集合中指定位置上的元素
int size()
返回集合中的元素个数

1.1.3 案例代码一:
[Java] 纯文本查看 复制代码
package com.itheima01;
import java.util.ArrayList;

/*
* 持有数据:
*                 单一数据,可以定义对应类型的变量直接持有
*                 多个数据,可以使用数组的方式记录,通过索引访问数据
*                 又在面向对象的基础上,可以使用集合的方式记录,最开始最常用ArrayList,该集合类同样可以通过索引访问数据
*
* 集合的基本使用:
*                 1创建集合对象
*                 2向集合中添加元素
*                 3从集合中获取元素/其他信息(集合的长度)
*/
[Java] 纯文本查看 复制代码
public class Demo01ArrayList {

        public static void main(String[] args) {

                //创建集合对象
                ArrayList<Integer> list = new ArrayList<Integer>();
                //向集合中添加元素
                list.add(10);
                list.add(100);
                list.add(2000);
                //从集合中获取元素/其他信息(集合的长度)
                Integer integer = list.get(2);
                System.out.println(integer);

                int size = list.size();
                System.out.println(size);
                System.out.println("===============================");
                //遍历集合
                for (int i = 0; i < list.size(); i++) {
                        //通过索引依次获取集合中每一个元素
                        Integer thisNumber = list.get(i);
                        //打印每个元素
                        System.out.println(thisNumber);
                }
        }
}
1.2 迭代器
eclipse使用时,可以配合文档注释,导出对类的说明文档,从而供其他人阅读学习与使用。
通过使用文档注释,将类或者方法进行注释用@简单标注基本信息。如@author 作者、@version代码版本、@param方法参数、@return方法返回值等。
1.2.1 迭代器概述
java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。
我们要取出这些集合中的元素,可通过一种通用的获取方式来完成。
Collection集合元素的通用获取方式:在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
集合中把这种取元素的方式描述在Iterator接口中。Iterator接口的常用方法如下:
hasNext()方法:用来判断集合中是否有下一个元素可以迭代。如果返回true,说明可以迭代。
next()方法:用来返回迭代的下一个元素,并把指针向后移动一位。
1.2.1.1 案例代码二:
package com.itheima01;
import java.util.ArrayList;
import java.util.Iterator;

/*
* java当中不止ArrayList一个集合,java提供了众多的集合.
*
* 不同的容器完成不同方式的数据存储.
* 不同集合的特点不同,ArrayList有序且可重复且带索引的集合.但是有的集合不带索引.所以如果使用其他集合,可能无法通过get+索引的方式获取元素
*
* 所有集合的通用获取元素方法并不是通过索引获取,而是通过迭代器获取.
* 迭代器:iterator
*/
[Java] 纯文本查看 复制代码
public class Demo02iterator {

        public static void main(String[] args) {

                //创建集合对象
                ArrayList<Integer> list = new ArrayList<Integer>();

                //向集合中添加元素
                list.add(10);
                list.add(100);
                list.add(2000);

                //获取该集合的迭代器
                Iterator<Integer> iterator = list.iterator();

                //使用迭代器的方法,迭代集合(遍历集合)
                while(iterator.hasNext()) {
                        //获取集合中元素
                        Integer thisNumber = iterator.next();
                        System.out.println(thisNumber);
                }
        }

}

1.2.2 迭代器迭代原理1.2.2.1 案例代码:
[Java] 纯文本查看 复制代码
package com.itheima01;

import java.util.ArrayList;
import java.util.Iterator;

/*
* 集合用来持有数据,所有常用集合都具备了可迭代功能iterator方法,该方法用于迭代集合,该方法才是最为通用的集合迭代方法。
*
* 迭代器:集合迭代(集合遍历)的工具
*
* 集合的获取迭代器方法
* public Iterator<E> iterator()  获取某个集合的迭代器实例对象
*
* Iterator:迭代器接口
*                 boolean hasNext()  判断集合中是否有下一个元素   不移动元素指针
*                 E next()  获取集合中下一个元素    移动指针,指向下一个元素
*/
[Java] 纯文本查看 复制代码
public class Demo03iterator {

        public static void main(String[] args) {

                //创建集合对象
                ArrayList<Integer> list = new ArrayList<Integer>();

                //向集合中添加元素
                list.add(10);
                list.add(100);
                list.add(2000);

                //调用集合的iterator方法,返回迭代器对象
                Iterator<Integer> itr = list.iterator();

                //混合使用hasNext与next方法,循环获取元素
                while(itr.hasNext()) {
                        //如果有元素,就获取元素
                        Integer thisNumber = itr.next();
                        System.out.println(thisNumber);
                }

        }

}
迭代集合元素图解:

1.2.3 迭代器迭代自定义数据类型
A:定义一个Person,里面有姓名和年龄属性,生成对应的getter/setter方法以及满参构造,空参构造
B:定义一个测试类,在测试类中定义一个集合,集合中存储三个Person对象,这三个人的属性分别为
  Jack,18岁
  Rose,16岁
  Trump,62岁
C:最终遍历该集合,分别打印出这三个人的姓名和年龄
并且统计出三个人的总年龄打印在控制台上

1.2.3.1 案例代码四:
[Java] 纯文本查看 复制代码
package com.itheima01;

/*
* 人类:
*                 年龄      姓名
*/
public class Person {

        private String name;
        private int age;

        public Person() {
                super();
        }

        public Person(String name, int age) {
                super();
                this.name = name;
                this.age = age;
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

}


package com.itheima01;

import java.util.ArrayList;
import java.util.Iterator;

/*
* 使用集合存储多个Person对象,将该集合中的所有Person对象的年龄相加,求得总年龄
*/
[Java] 纯文本查看 复制代码
public class Demo04 {

        public static void main(String[] args) {

                //创建集合对象
                ArrayList<Person> list = new ArrayList<Person>();
                //向集合中添加元素
                Person p = new Person("Jack",18);
                Person p2 = new Person("Rose",16);
                Person p3 = new Person("Trump",62);

                list.add(p);
                list.add(p2);
                list.add(p3);
                //调用集合的iterator方法,返回迭代器对象
                Iterator<Person> itr = list.iterator();

                //定义变量,记录年龄综合
                int sum = 0;

                //混合使用hasNext与next方法,循环获取元素
                while(itr.hasNext()) {
                        //如果有元素,就获取元素
                        Person thisP = itr.next();
                        System.out.println(thisP.getAge()+"岁的"+thisP.getName());
                        //年龄累加
                        sum += thisP.getAge();
                }

                //查看总年龄
                System.out.println(sum);
        }

}

1.2.4 并发修改异常
在前一个迭代器迭代自定义数据类型的基础上,添加新的需求:
使用集合存储多个Person对象,当遇到16岁的人时,就添加一个90岁的人
1.2.4.1 案例代码五:
   
[Java] 纯文本查看 复制代码
 package com.itheima01;

/*
* 人类:
*                 年龄      姓名
*/
public class Person {

        private String name;
        private int age;

        public Person() {
                super();
        }

        public Person(String name, int age) {
                super();
                this.name = name;
                this.age = age;
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

}


package com.itheima01;

import java.util.ArrayList;
import java.util.Iterator;

/*
*  使用集合存储多个Person对象,当遇到16岁的人时,就添加一个90岁的人
*  
*  该例中可能会产生并发修改异常:迭代器所认为的集合状态与集合真正的状态不统一了!就会出现该异常.
*/
[Java] 纯文本查看 复制代码
public class Demo05ConcurrentModificationException {

        public static void main(String[] args) {
                //创建集合对象
                ArrayList<Person> list = new ArrayList<Person>();
                //向集合中添加元素
                Person p = new Person("Jack",18);
                Person p2 = new Person("Rose",16);
                Person p3 = new Person("Trump",62);
                Person p4 = new Person("Obama",56);
                Person p5 = new Person("Castro",90);

                list.add(p);
                list.add(p2);
                list.add(p3);
                list.add(p4);
                //调用集合的iterator方法,返回迭代器对象
                Iterator<Person> itr = list.iterator();

                //混合使用hasNext与next方法,循环获取元素
                while(itr.hasNext()) {
                        //如果有元素,就获取元素
                        Person thisP = itr.next();
                        //判断年龄是否为16岁
                        if(thisP.getAge() == 16) {
                                //如果存在16岁的人,就加入90岁的卡斯特罗
                                list.add(p5);
                        }
                }

        }

}
运行上述代码发生了错误 java.util.ConcurrentModificationException这是什么原因呢?
在迭代过程中,使用了集合的方法对元素进行操作。导致迭代器并不知道集合中的变化,容易引发数据的不确定性。
解决并发修改异常,重新获取迭代器
1.2.4.2 案例代码六:
[Java] 纯文本查看 复制代码
package com.itheima01;
import java.util.ArrayList;
import java.util.Iterator;

/*
*  使用集合存储多个Person对象,当遇到16岁的人时,就添加一个90岁的人
*  
*  该例中可能会产生并发修改异常:迭代器所认为的集合状态与集合真正的状态不统一了!就会出现该异常.
*/
[Java] 纯文本查看 复制代码
public class Demo05ConcurrentModificationException {

        public static void main(String[] args) {
                //创建集合对象
                ArrayList<Person> list = new ArrayList<Person>();
                //向集合中添加元素
                Person p = new Person("Jack",18);
                Person p2 = new Person("Rose",16);
                Person p3 = new Person("Trump",62);
                Person p4 = new Person("Obama",56);
                Person p5 = new Person("Castro",90);

                list.add(p);
                list.add(p2);
                list.add(p3);
                list.add(p4);
                //调用集合的iterator方法,返回迭代器对象
                Iterator<Person> itr = list.iterator();

                //混合使用hasNext与next方法,循环获取元素
                while(itr.hasNext()) {
                        //如果有元素,就获取元素
                        Person thisP = itr.next();
                        //判断年龄是否为16岁
                        if(thisP.getAge() == 16) {
                                //如果存在16岁的人,就加入90岁的卡斯特罗
                                list.add(p5);
                                //当集合加入了一个元素后,就不要再使用迭代器操作元素了
                                break;
                        }
                }

                //重新打印集合结果
                Iterator<Person> itr2 = list.iterator();

                while (itr2.hasNext()) {
                        Person person = (Person) itr2.next();
                        System.out.println(person.getAge()+"岁的"+person.getName());
                }
        }

}






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