java进阶——day02-1 Collection、泛型
Collection集合
集合概述
集合是java中提供的一种容器,可以用来存储多个数据。
集合和数组都是容器,他们之间的区别:
1.数组的长度是固定的,集合的长度是可变的
2.数组中存储的是同一类元素,数组存储基本数据类型值。而集合存储的是对象。而且对象的类型可以不一致。早开发中对象多的时候,使用集合进行存储。
集合框架
集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection 和 双列集合java.util.Map.
Collection集合:单列集合类的根接口,用于存储一系列符合某种规则的元素,java.util.List 和 java.util.Set是它的两个重要子接口
List接口:主要实现类有java.util.ArrayList 和 java.util.LinkedList
set接口:注意实现类有java.util.HashSet 和java.util.TreeSet

注意:集合本身是一个工具,放在java.util包中。在Collection接口定义着单列集合框架中具有共性的内容。且Collection不能直接创建对象
Collection常用功能
1.概述
Collection是所有单列集合的父接口,其中定义了单列集合(List和Set)通用的方法,这些方法用于操作所有的单列集合。
2.方法

3.方法使用
package day03; import java.util.ArrayList; import java.util.Collection; public class day03_1 { //Collection操作单列集合的方法 public static void main(String[] args) { //使用多态形式 创建集合对象 Collection<String> collStr = new ArrayList<String>(); //方法1---添加对象 ((ArrayList<String>) collStr).add("马冬梅"); ((ArrayList<String>) collStr).add("晓晓"); ((ArrayList<String>) collStr).add("夏洛"); System.out.println(collStr);//[马冬梅, 晓晓, 夏洛] //方法2---判断当前集合是否存在指定对象 System.out.println("马冬梅 是否存在集合?:"+collStr.contains("马冬梅"));//true //方法3---删除在集合中的指定元素 System.out.println("删除 晓晓:"+((ArrayList<String>) collStr).remove("晓晓"));//true System.out.println("晓晓 是否还存在于集合中?:"+collStr.contains("晓晓"));//false //方法4---查看集合有多少个元素 System.out.println("集合中共存在:"+collStr.size()+" 个元素"); //方法5---将集合 转换俄日Object数组 Object[] objects = collStr.toArray(); for (int i = 0; i < objects.length; i++) { System.out.println(objects[i]); } //方法6---清空集合 collStr.clear(); System.out.println(collStr);//[] //方法7---判断集合是否为空 System.out.println(collStr.isEmpty());//true } }
注意:这些方法在单列集合是通用的
Iterator迭代器
Iterator接口
1、作用:遍历Collection集合
public Itterator iterator:获取集合对应的迭代器,用来遍历集合中的元素。
2、迭代:
即Collection集合元素通用获取方式。在取元素之前要判断集合中有没有元素(isEmpty方法),如果有就把元素取出来,继续判断取出,直到取出集合中的所有元素。
3、迭代器使用步骤:
1.使用集合中的方法iterator(),获取迭代器的实现类对象,使用Iterator接口接收(多态)
2.使用Iterator接口中的方法hasNext(),判断还有没有下一个元素
3.使用Iterator接口中的next()方法取出集合中的下一个元素
4、使用
package day03; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class day03_2 { //迭代器的使用 public static void main(String[] args) { //创建集合 Collection<String> collStr = new ArrayList<>(); //添加元素 ((ArrayList<String>) collStr).add("张一山"); ((ArrayList<String>) collStr).add("杨紫"); ((ArrayList<String>) collStr).add("宋丹丹"); //调用 集合中的iterator()方法 用Iterator对象接收 Iterator<String> it = collStr.iterator(); //遍历 while (it.hasNext()){ //取出元素 String s = it.next(); System.out.println(s); } /** * 张一山 * 杨紫 * 宋丹丹 */ } }
5、注意
在进行集合元素取出时,如果集合中没有元素了,还继续使用迭代器的next方法,将会 发生没有集合元素异常 错误
迭代器的原理

在调用next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素。
当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并返回
再次调用next方法时,迭代器索引会指向第二个元素并返回.......
以此类推,直到hasNext方法返回false,表示到达集合的末尾,终止对集合的遍历
增强for
1、概述:
增强for循环(for each),是JDK1.5后出的高级for循环,专门用来遍历数组和集合。它的内部原理其实是一个迭代器。所以在遍历过程中,不能对集合的元素进行增删操作。
2、格式:
for(元素的数据类型 变量:Collection集合 或 数组){
方法体}
3、例如
package day03; import java.util.ArrayList; import java.util.Collection; public class day03_3 { public static void main(String[] args) { Collection<String> collStr = new ArrayList<>(); ((ArrayList<String>) collStr).add("何炅"); ((ArrayList<String>) collStr).add("谢娜"); ((ArrayList<String>) collStr).add("吴昕"); //遍历集合 for (String str: collStr ) { System.out.println(str); } } }
package day03; public class day03_4 { public static void main(String[] args) { int[] arr = {1,3,5,7,9}; //遍历数组 for(int i : arr){ System.out.println(i); } } }
4、注意
for each循环必须有被遍历的目标。目标只能是Collection集合 或 数组
泛型
泛型概念
Collection集合可以存储各种类型的对象,但实际上通常Collection集合只存储同一类型的对象,例如字符串对象(JDK5前存储其他类型会报错)。
所以在JDK5以后,新增了泛型(Generic)语法,使在设计API时可以指定类或方法支持泛型
泛型:是一种未知的数据类型,当我们不知道用什么类型的时候,就使用泛型。
泛型可以看做一个变量 用来接收数据
泛型的定义和使用
1、对比
1.不使用泛型
package day03; import java.util.ArrayList; import java.util.Iterator; public class day03_5 { public static void main(String[] args) { //创建不使用泛型的集合 ArrayList arr = new ArrayList(); //添加数据 不使用泛型 集合默认类型为Object类型,可以存储任何数据类型 //添加字符串类型数据 arr.add("hello"); //添加int类型 arr.add(1); System.out.println(arr); //[hello, 1] //通过迭代器遍历 Iterator it = arr.iterator(); while (it.hasNext()){ //取出元素 接收也是Object 并使用String的length属性 查看长度 Object obj = it.next(); System.out.print(obj+" ");//hello 1 //将Object向下转型 转为String型 String str = (String)obj; System.out.println(str.length()); //输出会报出java.lang.ClassCastException异常 不能把Integer类型转为字符串 } } }
优点:
集合不使用泛型,默认类型为object类型,可以存储任意类型数据
缺点:
不安全,会引发异常
2.使用泛型
package day03; import java.util.ArrayList; import java.util.Iterator; public class day03_6 { public static void main(String[] args) { ArrayList<String> arr = new ArrayList<>(); //指定类型 String类 arr.add("胡一菲"); arr.add("曾小贤"); arr.add("吕小布"); // arr.add(1) 当添加不同类型时 会报错 //使用迭代器遍历 Iterator<String> iterator = arr.iterator(); while (iterator.hasNext()){ //创建String对象接收 String str = iterator.next(); System.out.print(str+" "); System.out.println(str.length()); } } }
优点:
1、避免了类型转换的麻烦,存储什么类型,取出的就是什么类型
2、把运行期间的异常,提升到编译期(写代码时就会抛出错误)
缺点:
泛型是什么类型,就只能存什么类型
2、定义和使用含有泛型的类
定义格式:
修饰符 class 类名<代表泛型的变量>{}
例如:
ArrayList集合
package day03; /** * 定义一个含有泛型的类 模拟ArrayList集合 * */ public class GenericClass<E>{ private E name; private E age; public E getName() { return name; } public E getAge() { return age; } public void setName(E name) { this.name = name; } public void setAge(E age) { this.age = age; } }
package day03; public class GC_demo { public static void main(String[] args) { //变量E现在指定为 String类型 GenericClass<String> gcC = new GenericClass<>(); //只能传递String类型的数据 gcC.setName("海鸥"); gcC.setAge("18"); System.out.println(gcC.getName()+"---"+gcC.getAge());//海鸥---18 //变量E指定为 Integer类型 GenericClass<Integer> gcC2 =new GenericClass<>(); //只能传递Integer类型的数据 gcC2.setName(23); gcC2.setAge(18); } }
变量E在定义的时候是没有指定类型的,在这里代表未知的一种数据类型,未来传递什么类型就是什么类型
3、含有泛型的方法
定义格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){};
例如:
package day03; //此处的MVP 在这里代表未知的数据类型 public class MyGeneric<MVP> { private MVP mvp; public MVP getMvp() { return mvp; } public void setMvp(MVP mvp) { this.mvp = mvp; } //定义含有泛型的方法 public <MVP> void show(MVP mvp){ System.out.println(mvp.getClass()); } public <MVP> MVP show2(MVP mvp){ return mvp; } }
package day03; public class UseMyGc { public static void main(String[] args) { //创建泛型 指定String类型 MyGeneric<String> mvp = new MyGeneric<>(); mvp.setMvp("this is Generic Class!!!"); System.out.println(mvp.getMvp()); //调用含有泛型的方法 mvp.show("abc");//class java.lang.String } }
4、含泛型的接口
定义格式:
修饰符 interface 接口名<代表泛型的变量>{}
例如:
package day03; //定义泛型接口 public interface InterfaceGerneric<E> { //添加抽象方法 public abstract void add(E a); }
package day03; //定义泛型接口的 实现类 public class implements_IGC<E> implements InterfaceGerneric<E>{ //重写抽象方法 @Override public void add(E a) { System.out.println("您添加的内容为:"+a); } }
package day03; //测试泛型接口 public class Inter_imp_Gc { public static void main(String[] args) { //指定为String类型 implements_IGC<String> test = new implements_IGC<>(); test.add("字符串测试"); //指定为Integer类型 implements_IGC<Integer> test2 =new implements_IGC<>(); test2.add(1); } }
使用格式:
1.定义类或者接口时 就确定泛型

此时,泛型E的值为String类型
2、定义时不确定泛型,直到创建对象时,确定泛型的类型

确定泛型

集合综合练习
练习说明:
按照斗地主的规则,完成洗牌发牌的动作。 具体规则:
使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。
案例分析:
准备牌:
牌可以设计为一个ArrayList,每个字符串为一张牌。 每张牌由花色数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。 牌由Collections类的shuffle方法进行随机排序。
发牌
将每个人以及底牌设计为ArrayList,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。
看牌
直接打印每个集合。
实现:
package day03; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; public class Poker { public static void main(String[] args) { //准备牌操作 //创建牌盒 用来存储牌面 ArrayList<String> pokerBox = new ArrayList<>(); //创建存储花色集合 ArrayList<String> colors = new ArrayList<>(); //创建存储数字的集合 为什么用String型? 因为有JQKA ArrayList<String> numbers = new ArrayList<>(); //添加花色 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"); //创建牌 拼接牌 //一个花色 然后跟每个数字 进行拼接 for(String color:colors){ //color每个花色 //遍历numbers集合 for(String number:numbers){ //结合 String card = color+number; pokerBox.add(card); } } //添加大小王 pokerBox.add("小☺"); pokerBox.add("大☠"); //洗牌 Collections.shuffle(pokerBox); //发牌 //创建三个玩家 以及底牌集合 ArrayList<String> player1 = new ArrayList<>(); ArrayList<String> player2 = new ArrayList<>(); ArrayList<String> player3 = new ArrayList<>(); ArrayList<String> dipai = new ArrayList<>(); //遍历牌盒 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);//玩家1 }else if(i%3==1){ player2.add(card);//玩家2 }else { player3.add(card); } } } System.out.println("张三"+player1+" "+player1.size()); System.out.println("李四"+player2+" "+player2.size()); System.out.println("王五"+player3+" "+player3.size()); System.out.println(dipai+" "+dipai.size()); } }

浙公网安备 33010602011771号