集合【迭代器、增强for、泛型】

java.util.Collection接口
是集合的最顶层的接口,定义了集合共性的方法
接口无法直接创建对象,使用多态的方式创建对象
Collection<集合中的数据类型(泛型)> coll = new ArrayList<集合中的数据类型(泛型)>();

迭代器
集合中存储数据的方式(数据类型)不一样,取出集合中元素的方式也不同,java给我们提供了一种公共的取出元素的方式,叫迭代器
描述迭代器的接口:java.util.Iterator

接口中的抽象方法:
boolean hasNext() 如果仍有元素可以迭代,则返回 true。 判断集合中还有没有元素,有返回true,没有返回false
E next() 返回迭代的下一个元素。 取出集合中的下一个元素

迭代器是一个接口,需要找到迭代器的实现类,迭代器的实现类是每个集合的内部类
在Collection接口中有一个方法: iterator方法返回的就是迭代器
Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。
ArrayList集合实现了Collection接口,重写iterator方法,方法的返回值就是迭代器的实现类对象

注意:我们只需要知道iterator方法返回的而是迭代器的实现类就行了,不需要关注返回的是哪个实现类对象,这种变成方式叫做面向接口编程

迭代器的使用步骤:
1.创建集合对象,往集合中添加元素
2.使用集合中的方法iterator获取迭代器的实现类对象,使用Iterator接口接收(多态)
3.使用iterator中的方法hasNext和next方法进行迭代,取出集合中的元素

 1 public static void main(String[] args) {
 2         //1.创建集合对象,往集合中添加元素
 3         //Collection<String> coll = new ArrayList<String>();
 4         Collection<String> coll = new HashSet<String>();
 5         coll.add("姚明");
 6         coll.add("乔丹");
 7         coll.add("詹姆斯");
 8         coll.add("科比");
 9         coll.add("艾弗森");
10         //2.使用集合中的方法iterator获取迭代器的实现类对象,使用Iterator接口接收(多态)
11         //集合中的数据类型是什么,迭代器的数据类型就是什么,跟着集合走
12         Iterator<String> it = coll.iterator();
13         //3.使用iterator中的方法hasNext和next方法进行迭代,取出集合中的元素
14         //boolean hasNext() 如果仍有元素可以迭代,则返回 true。
15         /*boolean b = it.hasNext();
16         System.out.println(b);
17         //E(String) next() 返回迭代的下一个元素。
18         String s = it.next();
19         System.out.println(s);
20
21         b = it.hasNext();
22         System.out.println(b);
23         s = it.next();
24         System.out.println(s);
25
26         b = it.hasNext();
27         System.out.println(b);
28         s = it.next();
29         System.out.println(s);
30
31         b = it.hasNext();
32         System.out.println(b);
33         s = it.next();
34         System.out.println(s);
35
36         b = it.hasNext();
37         System.out.println(b);
38         s = it.next();
39         System.out.println(s);
40
41         b = it.hasNext();
42         System.out.println(b);//false,没有元素了
43         s = it.next();//没有元素了,在取就报NoSuchElementException没有元素异常
44         System.out.println(s);*/
45
46         /*
47          * 发现以上迭代的过程是一个重复的过程,可以使用循环优化
48          * 我们不知道集合中有多少元素,所以可以使用while循环
49          * while循环的结束条件:hasNext();返回false
50          */
51         while(it.hasNext()){
52             String s = it.next();
53             System.out.println(s);
54         }
55         System.out.println("-------------------");
56         /*
57          * for循环方式迭代器,使用不多
58          */
59         /*for(Iterator<String> it2 = coll.iterator();it2.hasNext();){
60             String s = it2.next();//取出元素,移动指针到下一位
61             System.out.println(s);
62         }*/
63     }

并发修改异常
在迭代的过程中,对集合的长度进行了修改,就会发生并发修改异常
遍历的过程中,集合的长度进行了修改,但是迭代器并不知道,就会产生ConcurrentModificationException

解决方法:
1.迭代就是迭代,不要对集合进行修改
2.使用迭代器Iterator的子接口ListIterator中的方法add/remove,让迭代器自己增加往集合中增加元素/移除元素
这样迭代器本身知道了集合的变化,就不会产生并发修改异常了

void add(E e) 将指定的元素插入列表(可选操作)。
void remove() 从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。

 1  public static void main(String[] args) {
 2         ArrayList<String> list = new ArrayList<String>();
 3
 4         list.add(null);
 5         list.add("abc1");
 6         list.add("abc2");
 7         list.add("abc3");
 8         list.add("abc4");
 9
10         /*
11          * 使用迭代器遍历集合
12          */
13         //获取迭代器
14         Iterator<String> it = list.iterator();
15         //使用while遍历集合
16         while(it.hasNext()){
17             String s = it.next();
18
19             /*
20              * 判断集合中有没有"abc3"这个元素
21              * 如果有,增加一个元素"itcast"
22              * 编程技巧:使用equals判断的时候,要把已知的变量写在前边,未知的写在后边,防止空指针异常
23              */
24             //if(s.equals("abc3")){
25             if("abc3".equals(s)){
26                 //1.迭代就是迭代,不要对集合进行修改
27                 //list.add("itcast");
28             }
29
30             System.out.println(s);
31         }
32
33         System.out.println("------------------");
34
35         /*
36          * 2.使用迭代器Iterator的子接口ListIterator中的方法add/remove,让迭代器自己增加往集合中增加元素/移除元素
37          */
38         ListIterator<String> listIt = list.listIterator();
39         while(listIt.hasNext()){
40             String s = listIt.next();
41             if("abc3".equals(s)){
42                 listIt.add("itcast");
43             }
44             System.out.println(s);
45         }
46         System.out.println(list);
47     }

增强for
内部是一个迭代器,简化了迭代的代码,使遍历更加简单

Collection接口继承Iterable,所以Collection接口的所有实现类都可以是用增强for

注意:增强for是JDK1.5之后出现的

格式:
for(数据类型(集合/数组的数据类型) 变量名 : 集合名/数组名){
  syso(变量名);
}

Java中的泛型
就是数据类型,在创建对象的时候确定

Java中的泛型是一个伪泛型:在编译的时候有(写代码.java中),运行的时候(.class)没有
随机数:伪随机数

泛型的好处:
1.避免强转,可以直接使用元素特有的方法
2.把运行期的异常,转换编译期异常(编译失败)

定义含有泛型的类
模仿ArrayList集合
public class ArrayList<E>{}
E:是一个未知的数据类型,可能是Integer,可能是String,可能Person
创建类对象的时候确定数据类型

定义格式:
修饰符 class 类名<E>{

}

 1 public class GenericClass<E> {
 2     private E name;
 3
 4     public E getName() {
 5         return name;
 6     }
 7
 8     public void setName(E name) {
 9         this.name = name;
10     }
11
12     public void method(E e){
13         System.out.println(e);
14     }

定义含有泛型的接口
格式:
修饰符 interface 接口名<泛型>{
  抽象方法(参数<泛型>);
}

1  public interface GenericInterface<E> {
2     public abstract void method(E e);
3 }
 1 /*
 2  * 1.定义接口的实现类,不管泛型,接口泛型是怎么写的,实现类也怎么写
 3  *  public class ArrayList<E> implements List<E>{}
 4  *  创建实现类对象的时候确定泛型的数据类型
 5  */
 6 class GenericInterfaceImpl1<E> implements GenericInterface<E>{
 7
 8     @Override
 9     public void method(E e) {
10         System.out.println(e);
11     }
12 }

含有泛型的方法
不是类上定义的泛型,是方法自己定义的泛型
定义格式:在修饰符和返回值类型之间要定义泛型,才能使用
修饰符 <泛型> 返回值类型 方法名(参数<泛型>){
}
方法上的泛型,在调用方法的时候确定数据类型,传递的是什么类型的数据,泛型就是什么类型(和类上的泛型没有关系)

 1 public class GenericMethod<E> {
 2
 3     /*
 4      * 定义方法,使用类上的泛型
 5      */
 6     public void method(E e){
 7         System.out.println(e);
 8     }
 9
10     /*
11      * 定义一个含有泛型的方法
12      */
13     public <T> void function(T t){
14         System.out.println(t);
15     }

泛型的通配符:?,代表任意的数据类型

上限限定:? extends E代表只要是E类型的子类即可
下限限定:? super E代表只要是E类型的父类即可

ArrayList集合的构造方法
ArrayList(Collection<? extends E> c)
参数是一个集合,集合的数据类型有要求,只能是ArrayList泛型的子类或者是本身

ArrayList(Collection<? extends E> c)
参数是一个集合,集合的数据类型有要求,只能是ArrayList泛型的子类或者是本身

 1 /*
 2  * 斗地主案例:
 3  * 1.准备牌
 4  * 2.洗牌
 5  * 3.发牌
 6  * 4.看牌
 7  */
 8 public class DouDiZhu {
 9     public static void main(String[] args) {
10         //1.准备牌
11         //创建存储54张牌的集合
12         ArrayList<String> poker = new ArrayList<String>();
13         //存储大王小王
14         poker.add("大王");
15         poker.add("小王");
16         //存储52张牌
17         //创建序号的数组
18         String[] numbers = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
19         //创建花色数组
20         String[] colors = {"?","?","?","?"};
21         //嵌套遍历两个数组
22         for (String number : numbers) {
23             for (String color : colors) {
24                 //System.out.println(color+number);
25                 //把组合的牌放入到集合中
26                 poker.add(color+number);
27             }
28         }
29         //System.out.println(poker);
30
31         /*
32          * 2.洗牌
33          * 使用Collections中的方法
34          * static void shuffle(List<?> list)
35          */
36         Collections.shuffle(poker);
37         //System.out.println(poker);
38
39         /*
40          * 3.发牌
41          * 创建4个集合
42          * 遍历poker集合
43          * 使用poker集合的索引%3发牌
44          */
45         ArrayList<String> player01 = new ArrayList<String>();
46         ArrayList<String> player02 = new ArrayList<String>();
47         ArrayList<String> player03 = new ArrayList<String>();
48         ArrayList<String> diPai = new ArrayList<String>();
49         //遍历poker集合
50         for (int i = 0; i < poker.size(); i++) {
51             //获取牌
52             String s = poker.get(i);
53             //先判断索引是否为底牌的索引 51 52 53
54             if(i >=51){
55                 //给底牌发牌
56                 diPai.add(s);
57             }else if(i%3==0){
58                 //给玩家1发牌
59                 player01.add(s);
60             }else if(i%3==1){
61                 //给玩家1发牌
62                 player02.add(s);
63             }else if(i%3==2){
64                 //给玩家1发牌
65                 player03.add(s);
66             }
67         }
68         //4.看牌
69         System.out.println("刘德华:"+player01);
70         System.out.println("周润发:"+player02);
71         System.out.println("周星驰:"+player03);
72         System.out.println("底牌:"+diPai);
73     }
74 }
时间: 2024-10-20 21:00:19

集合【迭代器、增强for、泛型】的相关文章

Java基础——集合(三)——泛型、增强for、工具类

         接上篇,<Java基础--集合(二)--迭代器.Map集合> 六.泛型 (1)定义: 泛型是一种把明确类型的工作放在了创建对象或者调用方法时候才去明确的特殊的类型. (2)格式: <数据类型> ArrayList<String> aList=new ArrayList<String>(); <String> 即表示的是泛型 (3)好处:(掌握) A:解决了黄色警告线问题 B:把运行期间的转换异常给提前到了编译期间 C:优化了程序

java.基础、集合、枚举、泛型、

1.myeclipse的安装和使用 * eclipse:是一个免费的开发工具 * myeclipse:是一个收费的插件,破解myeclipse, ** 安装目录的要求: 不能有中文和空格 ** 安装完成之后,选择一个工作空间 ,这个工作空间不能有中文和空格 * 破解myeclipse ** 运行run.bat文件,但是运行之前,必须要安装jdk,通过配置环境变量 * myeclipse的使用 * 创建一个工程 - 类型 java project web project - 选择依赖的jdk,可以

黑马程序员——集合基础知识(泛型)

集合:泛型基础知识 泛型.(泛型就是类型参数化,默认的时object,虽然不用强制类型转换,这个就要你自己去写特性方法,比如compareto是string的特有方法吧,你可以写但是父类肯定调用不了) itnex t对象都是obj要使用对象的特性功能必须强.编译的时候没问题,因为都不知道你会传什么对象,你橙子也可以当作apple来传,设计的时候并不知道! 泛型作用.1.用于解决安全问题.运行时期出现的问题classcastexception转移到编译时期.2.迭代器里面的itnext()不用强转

上手并过渡到PHP7(5)——轻量级“集合”迭代器-Generator

轻量级“集合”迭代器-Generator泊学视频链接泊阅文档链接Generator是PHP 5.5加入的新语言特性.但是,它似乎并没有被很多PHP开发者广泛采用.因此,在我们了解PHP 7对Generator的改进之前,我们先通过一个简单却显而易见的例子来了解下Generator究竟为我们解决什么问题. 一千万个整数的数组 如果我们要“创建一个指定元素个数的数组”,怎么做呢?我们可能会不加思索的写下下面的代码: function makeRange($range) { $data = []; f

3.9 java基础总结集合①LIst②Set③Map④泛型⑤Collections

集合①LIst②Set③Map④泛型⑤Collections 一.List:有顺序,可重复实现类:1.ArrayList 广泛,适用于查询,增删不频繁的(类似数组,其长度可按需增大,增删效率慢)2.LinkedList 中间频繁增删的,查询效率低(双向链表,先进先出,不支持随机查找,必须重头开始查找,效率低)3.Vector 类似ArrayList,线程安全,性能低 二.Set:没有顺序,不可重复最多存一个null实现类:1.HashSet 速度快,不排序2.TreeSet 速度慢,内部排序,看

Java增强的泛型

尽管Java 8是2014年年初才发布的,而Java 9要等到2016年年中,但是目前有一些计划放到某个未来版本(希望是Java 10)中的特性已经合并了进来. 具体而言,有两个比较大的特性已经开始原型设计了,它们是增强的泛型(Enhanced Generics)和值类型(Value Types).有了增强的泛型,Java开发者可以编写像List<int>这样的代码,省去了对基本类型进行装箱的痛苦.新的泛型提案有些地方比较模糊(或者说微妙),需要细心处理,具体见Brian Goetz在最近的设

黑马程序员——Java集合工具类和泛型

Collections工具类和泛型 Collections和Collection Collections和Collection是不同的,Collections是工具类,用来操作集合的,而Collection是集合接口.Collections中有一系列的静态方法用来操作集合,但是不能更改集合内容.比如不能set()不能remove()元素,可以替换全部元素或者添加同一个元素. static List<String> list =Arrays .asList("one Two three

【JAVA集合】集合迭代器快速失败行为及CopyOnWriteArrayList

以下内容基于jdk1.7.0_79源码: 什么是集合迭代器快速失败行为 以ArrayList为例,在多线程并发情况下,如果有一个线程在修改ArrayList集合的结构(插入.移除...),而另一个线程正在用迭代器遍历读取集合中的元素,此时将抛出ConcurrentModificationException异常导致迭代遍历失败: ArrayList.Itr迭代器快速失败源码及例子 查看ArrayList的Itr迭代器源码,可以看到Itr为ArrayList的私有内部类,有一个expectedMod

对比两个同类型的泛型集合并返回差异泛型集合 ——两个List&lt;类名&gt;的比较

1: /// <summary> 2: /// 对比两个同类型的泛型集合并返回差异泛型集合 3: /// </summary> 4: /// <typeparam name="T">泛型类型</typeparam> 5: /// <param name="newModel">修改后的数据集合</param> 6: /// <param name="oldModel"&g

轻量级“集合”迭代器-Generator

Generator是PHP 5.5加入的新语言特性.但是,它似乎并没有被很多PHP开发者广泛采用.因此,在我们了解PHP 7对Generator的改进之前,我们先通过一个简单却显而易见的例子来了解下Generator究竟为我们解决什么问题. 一千万个整数的数组 如果我们要"创建一个指定元素个数的数组",怎么做呢?我们可能会不加思索的写下下面的代码: function makeRange($range) { $data = []; for ($i = 0; $i < $range;