Collection、泛型

本文详细介绍了Java集合框架中的Collection接口及其子接口List和Set,包括它们的特点和常用实现类。此外,还深入讨论了迭代器Iterator的使用方法和实现原理。文章进一步讲解了JDK1.5引入的泛型概念,以及使用泛型的好处,如编译时类型检查和避免类型转换。最后,通过一个斗地主游戏案例展示了如何应用集合和泛型进行洗牌、发牌等操作。
摘要由CSDN通过智能技术生成
day02 Collection 、泛型】
主要内容
Collection 集合
迭代器
增强 for
第⼀章 Collection 集合
1.1 集合概述
在前⾯基础班我们已经学习过并使⽤过集合 ArrayList , 那么集合到底是什么呢 ?
集合 :集合是 java 中提供的⼀种容器,可以⽤来存储多个数据。
集合和数组既然都是容器,它们有啥区别呢?
数组的⻓度是固定的。集合的⻓度是可变的。
数组中存储的是同⼀类型的元素,可以存储基本数据类型值。集合存储的都是对象。⽽且对象的类
型可以不⼀致。在开发中⼀般当对象多的时候,使⽤集合进⾏存储。
1.2 集合框架
JAVASE 提供了满⾜各种需求的 API ,在使⽤这些 API 前,先了解其继承与接⼝操作架构,才能了解何时采
⽤哪个类,以及类之间如何彼此合作,从⽽达到灵活应⽤。
集合按照其存储结构可以分为两⼤类,分别是单列集合 java.util.Collection 和双列集
java.util.Map ,今天我们主要学习 Collection 集合,在 day04 时讲解 Map 集合。
Collection :单列集合类的根接⼝,⽤于存储⼀系列符合某种规则的元素,它有两个重要的⼦接
⼝,分别是 java.util.List java.util.Set 。其中, List 的特点是元素有序、元素可重
复。 Set 的特点是元素⽆序,⽽且不可重复。 List 接⼝的主要实现类有 java.util.ArrayList
java.util.LinkedList Set 接⼝的主要实现类有 java.util.HashSet
java.util.TreeSet
从上⾯的描述可以看出 JDK 中提供了丰富的集合类库,为了便于初学者进⾏系统地学习,接下来通过⼀
张图来描述整个集合类的继承体系。 集合本身是⼀个⼯具,它存放在 java.util 包中。在 Collection 接⼝定义着单列集合框架中最最共性的
内容。
1.3 Collection 常⽤功能
Collection 是所有单列集合的⽗接⼝,因此在 Collection 中定义了单列集合 (List Set) 通⽤的⼀些⽅法,
这些⽅法可⽤于操作所有的单列集合。⽅法如下:
public boolean add(E e) 把给定的对象添加到当前集合中 。
public void clear() : 清空集合中所有的元素。
public boolean remove(E e) : 把给定的对象在当前集合中删除。
public boolean contains(E e) : 判断当前集合中是否包含给定的对象。
public boolean isEmpty() : 判断当前集合是否为空。
public int size() : 返回集合中元素的个数。
public Object[] toArray() : 把集合中的元素,存储到数组中。
⽅法演示:
import java . util . ArrayList ;
import java . util . Collection ;
public class Demo1Collection {
public static void main ( String [] args ) {
// 创建集合对象
// 使⽤多态形式
Collection < String > coll = new ArrayList < String > ();
// 使⽤⽅法
// 添加功能 boolean add(String s)
coll . add ( " ⼩李⼴ " ); tips: 有关 Collection 中的⽅法可不⽌上⾯这些,其他⽅法可以⾃⾏查看 API 学习。
第⼆章 Iterator 迭代器
2.1 Iterator 接⼝
在程序开发中,经常需要遍历集合中的所有元素。针对这种需求, JDK 专⻔提供了⼀个接⼝
java.util.Iterator Iterator 接⼝也是 Java 集合中的⼀员,但它与 Collection Map 接⼝有所
不同, Collection 接⼝与 Map 接⼝主要⽤于存储元素,⽽ Iterator 主要⽤于迭代访问(即遍
历) Collection 中的元素,因此 Iterator 对象也被称为迭代器。
想要遍历 Collection 集合,那么就要获取该集合迭代器完成迭代操作,下⾯介绍⼀下获取迭代器的⽅
法:
public Iterator iterator() : 获取集合对应的迭代器,⽤来遍历集合中的元素的。
下⾯介绍⼀下迭代的概念:
迭代 :即 Collection 集合元素的通⽤获取⽅式。在取元素之前先要判断集合中有没有元素,如果
有,就把这个元素取出来,继续在判断,如果还有就再取出出来。⼀直把集合中的所有元素全部取
coll . add ( " 扫地僧 " );
coll . add ( " ⽯破天 " );
System . out . println ( coll );
// boolean contains(E e) 判断 o 是否在集合中存在
System . out . println ( " 判断 扫地僧 是否在集合中 " + coll . contains ( " 扫地僧 " ));
//boolean remove(E e) 删除在集合中的 o 元素
System . out . println ( " 删除⽯破天: " + coll . remove ( " ⽯破天 " ));
System . out . println ( " 操作之后集合中元素 :" + coll );
// size() 集合中有⼏个元素
System . out . println ( " 集合中有 " + coll . size () + " 个元素 " );
// Object[] toArray() 转换成⼀个 Object 数组
Object [] objects = coll . toArray ();
// 遍历数组
for ( int i = 0 ; i < objects . length ; i ++ ) {
System . out . println ( objects [ i ]);
}
// void clear() 清空集合
coll . clear ();
System . out . println ( " 集合中内容为: " + coll );
// boolean isEmpty() 判断是否为空
System . out . println ( coll . isEmpty ());
}
} 出。这种取出⽅式专业术语称为迭代。
Iterator 接⼝的常⽤⽅法如下:
public E next() : 返回迭代的下⼀个元素。
public boolean hasNext() : 如果仍有元素可以迭代,则返回 true
接下来我们通过案例学习如何使⽤ Iterator 迭代集合中元素:
tips: :在进⾏集合元素取出时,如果集合中已经没有元素了,还继续使⽤迭代器的 next ⽅法,将
会发⽣ java.util.NoSuchElementException 没有集合元素的错误。
2.2 迭代器的实现原理
我们在之前案例已经完成了 Iterator 遍历集合的整个过程。当遍历集合时,⾸先通过调⽤ t 集合的
iterator() ⽅法获得迭代器对象,然后使⽤ hashNext() ⽅法判断集合中是否存在下⼀个元素,如果存在,
则调⽤ next() ⽅法将元素取出,否则说明已到达了集合末尾,停⽌遍历元素。
Iterator 迭代器对象在遍历集合时,内部采⽤指针的⽅式来跟踪集合中的元素,为了让初学者能更好地
理解迭代器的⼯作原理,接下来通过⼀个图例来演示 Iterator 对象迭代元素的过程:
public class IteratorDemo {
public static void main ( String [] args ) {
// 使⽤多态⽅式 创建对象
Collection < String > coll = new ArrayList < String > ();
// 添加元素到集合
coll . add ( " 串串星⼈ " );
coll . add ( " 吐槽星⼈ " );
coll . add ( " 汪星⼈ " );
// 遍历
// 使⽤迭代器 遍历 每个集合对象都有⾃⼰的迭代器
Iterator < String > it = coll . iterator ();
// 泛型指的是 迭代出 元素的数据类型
while ( it . hasNext ()){ // 判断是否有迭代元素
String s = it . next (); // 获取迭代出的元素
System . out . println ( s );
}
}
} 在调⽤ Iterator next ⽅法之前,迭代器的索引位于第⼀个元素之前,不指向任何元素,当第⼀次调⽤
迭代器的 next ⽅法后,迭代器的索引会向后移动⼀位,指向第⼀个元素并将该元素返回,当再次调⽤
next ⽅法时,迭代器的索引会指向第⼆个元素并将该元素返回,依此类推,直到 hasNext ⽅法返回
false ,表示到达了集合的末尾,终⽌对元素的遍历。
2.3 增强 for
增强 for 循环 ( 也称 for each 循环 ) JDK1.5 以后出来的⼀个⾼级 for 循环,专⻔⽤来遍历数组和集合的。它
的内部原理其实是个 Iterator 迭代器,所以在遍历的过程中,不能对集合中的元素进⾏增删操作。
格式:
它⽤于遍历 Collection 和数组。通常只进⾏遍历元素,不要在遍历的过程中对集合元素进⾏增删操作。
练习 1 :遍历数组
for ( 元素的数据类型 变量 : Collection 集合 or 数组 ){
// 写操作代码
} 练习 2: 遍历集合
tips: for 循环必须有被遍历的⽬标。⽬标只能是 Collection 或者是数组。新式 for 仅仅作为遍历操
作出现。
第三章 泛型
3.1 泛型概述
在前⾯学习集合时,我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们
都会被提升成 Object 类型。当我们在取出每⼀个对象,并且进⾏相应的操作,这时必须采⽤类型转换。
⼤家观察下⾯代码:
public class NBForDemo1 {
public static void main ( String [] args ) {
int [] arr = { 3 , 5 , 6 , 87 };
// 使⽤增强 for 遍历数组
for ( int a : arr ){ //a 代表数组中的每个元素
System . out . println ( a );
}
}
}
public class NBFor {
public static void main ( String [] args ) {
Collection < String > coll = new ArrayList < String > ();
coll . add ( " ⼩河神 " );
coll . add ( " ⽼河神 " );
coll . add ( " 神婆 " );
// 使⽤增强 for 遍历
for ( String s : coll ){ // 接收变量 s 代表 代表被遍历到的集合元素
System . out . println ( s );
}
}
}
public class GenericDemo {
public static void main ( String [] args ) {
Collection coll = new ArrayList ();
coll . add ( "abc" );
coll . add ( "itcast" );
coll . add ( 5 ); // 由于集合没有做任何限定,任何类型都可以给其中存放
Iterator it = coll . iterator ();
while ( it . hasNext ()){
// 需要打印每个字符串的⻓度 , 就要把迭代出来的对象转成 String 类型
String str = ( String ) it . next (); 程序在运⾏时发⽣了问题 java.lang.ClassCastException
为什么会发⽣类型转换异常呢?
我们来分析下:由于集合中什么类型的元素都可以存储。导致取出时强转引发运⾏时
ClassCastException
怎么来解决这个问题呢?
Collection 虽然可以存储各种对象,但实际上通常 Collection 只存储同⼀类型对象。例如都是存储字符串
对象。因此在 JDK5 之后,新增了 泛型 ( Generic ) 语法,让你在设计 API 时可以指定类或⽅法⽀持泛型,这
样我们使⽤ API 的时候也变得更为简洁,并得到了编译时期的语法检查。
泛型 :可以在类或⽅法中预⽀地使⽤未知的类型。
tips: ⼀般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为 Object
类型。
3.2 使⽤泛型的好处
上⼀节只是讲解了泛型的引⼊,那么泛型带来了哪些好处呢?
将运⾏时期的 ClassCastException ,转移到了编译时期变成了编译失败。
避免了类型强转的麻烦。
通过我们如下代码体验⼀下:
tips: 泛型是数据类型的⼀部分,我们将类名与泛型合并⼀起看做数据类型。
第四章 集合综合案例
System . out . println ( str . length ());
}
}
}
public class GenericDemo2 {
public static void main ( String [] args ) {
Collection < String > list = new ArrayList < String > ();
list . add ( "abc" );
list . add ( "itcast" );
// list.add(5);// 当集合明确类型后,存放类型不⼀致就会编译报错
// 集合已经明确具体存放的元素类型,那么在使⽤迭代器的时候,迭代器也同样会知道具体遍
历元素类型
Iterator < String > it = list . iterator ();
while ( it . hasNext ()){
String str = it . next ();
// 当使⽤ Iterator<String> 控制元素类型后,就不需要强转了。获取到的元素直接就是
String 类型
System . out . println ( str . length ());
}
}
} 第四章 集合综合案例
4.1 案例介绍
按照⽃地主的规则,完成洗牌发牌的动作。
具体规则:
使⽤ 54 张牌打乱顺序 , 三个玩家参与游戏,三⼈交替摸牌,每⼈ 17 张牌,最后三张留作底牌。
4.2 案例分析
准备牌:
牌可以设计为⼀个 ArrayList, 每个字符串为⼀张牌。
每张牌由花⾊数字两部分组成,我们可以使⽤花⾊集合与数字集合嵌套迭代完成每张牌的组装。
牌由 Collections 类的 shuffle ⽅法进⾏随机排序。
发牌
将每个⼈以及底牌设计为 ArrayList, 将最后 3 张牌直接存放于底牌,剩余牌通过对 3 取模依次发牌。
看牌
直接打印每个集合。
4.3 代码实现
import java . util . ArrayList ;
import java . util . Collections ;
public class Poker {
public static void main ( String [] args ) {
/*
* 1: 准备牌操作
*/
//1.1 创建牌盒 将来存储牌⾯的
ArrayList < String > pokerBox = new ArrayList < String > ();
//1.2 创建花⾊集合
ArrayList < String > colors = new ArrayList < String > ();
//1.3 创建数字集合
ArrayList < String > numbers = new ArrayList < String > ();
//1.4 分别给花⾊ 以及 数字集合添加元素
colors . add ( " " );
colors . add ( " " );
colors . add ( " " );
colors . add ( " " );
for ( int i = 2 ; i <= 10 ; i ++ ){ numbers . add ( i + "" );
}
numbers . add ( "J" );
numbers . add ( "Q" );
numbers . add ( "K" );
numbers . add ( "A" );
//1.5 创造牌 拼接牌操作
// 拿出每⼀个花⾊ 然后跟每⼀个数字 进⾏结合 存储到牌盒中
for ( String color : colors ) {
//color 每⼀个花⾊
// 遍历数字集合
for ( String number : numbers ){
// 结合
String card = color + number ;
// 存储到牌盒中
pokerBox . add ( card );
}
}
//1.6 ⼤王⼩王
pokerBox . add ( " " );
pokerBox . add ( "
" );
// System.out.println(pokerBox);
// 洗牌 是不是就是将 牌盒中 牌的索引打乱
// Collections ⼯具类 都是 静态⽅法
// shuffer ⽅法
/*
* static void shuffle(List<?> list)
* 使⽤默认随机源对指定列表进⾏置换。
*/
//2: 洗牌
Collections . shuffle ( pokerBox );
//3 发牌
//3.1 创建 三个 玩家集合 创建⼀个底牌集合
ArrayList < String > player1 = new ArrayList < String > ();
ArrayList < String > player2 = new ArrayList < String > ();
ArrayList < String > player3 = new ArrayList < String > ();
ArrayList < String > dipai = new ArrayList < String > ();
// 遍历 牌盒 必须知道索引
for ( int i = 0 ; i < pokerBox . size (); i ++ ){
// 获取 牌⾯
String card = pokerBox . get ( i );
// 留出三张底牌 存到 底牌集合中
if ( i >= 51 ){ // 存到底牌集合中
dipai . add ( card );
} else {
// 玩家 1 %3 ==0 if ( i % 3 == 0 ){
player1 . add ( card );
} else if ( i % 3 == 1 ){ // 玩家 2
player2 . add ( card );
} else { // 玩家 3
player3 . add ( card );
}
}
}
// 看看
System . out . println ( " 令狐冲: " + player1 );
System . out . println ( " ⽥伯光: " + player2 );
System . out . println ( " 绿⽵翁: " + player3 );
System . out . println ( " 底牌: " + dipai );
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值