Java重点--泛型
Posted 几分醉意.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java重点--泛型相关的知识,希望对你有一定的参考价值。
文章目录
💖泛型的概念
泛型是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型,泛型也可以看做是一个变量,用来接收数据类型。
E e:Element元素
T t:Type 类型
✨使用泛型的好处与弊端
众所周知,凡是都有两面性,首先我们来谈谈不使用泛型的好处与坏处。
创建集合对象,不使用泛型
好处:
集合不使用泛型,默认的类型是Object类型,可以存储任意类型数据。
坏处:
不安全,会引发异常。
举例说明
private static void show01()
ArrayList list = new ArrayList();
list.add("abc");
list.add(3);
//使用迭代器遍历list集合
//获取迭代器
Iterator it = list.iterator();
//使用迭代器中的方法hasNext和next遍历集合
while (it.hasNext())
//存的时候是Object类型,取出的时候也是Object
Object obj = it.next();
System.out.println(obj);
//目前没问题
//想要使用String类特有的方法,length获取字符串长度;不能使用 多态 Object obj = "abc";
// 不能使用子类特有的方法 需要向下转型
// String s = (String)obj; //数字不能转换字符串 引发异常
// System.out.println(s.length());
那么我们接下来在来谈谈使用泛型的好处与坏处。
创建集合对象,使用泛型
好处:
1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
2.把运行期异常(代码运行之后会抛出的异常),提升到了编译器(写代码的时候会报错)
弊端:
泛型是什么类型,只能存储什么类型的数据
举例说明
private static void show02()
ArrayList<String> list = new ArrayList<>();
list.add("abc");
//使用迭代器遍历list集合
Iterator<String> it = list.iterator();
while (it.hasNext())
String next = it.next();
System.out.println(next+"->"+next.length()); //abc->3
✨定义和使用含有泛型的类
定义一个含有泛型的类,模拟ArrayList集合
泛型是一个未知的数据类型,当我们不确定什么什么数据类型的时候,可以使用泛型泛型可以接收任意的数据类型,可以使用Integer,String,Student…创建对象的时候确定泛型的数据类型
好处 :类型不写死,创建对象泛型是什么类型,类中泛型就是什么类型
首先定义一个含有泛型的类
public class 含有泛型的类 <E>
private E name;
public E getName()
return name;
public void setName(E name)
this.name = name;
//所有使用数据类型的时候,都使用了泛型E
接着就可以在主方法中使用它了
public class 主方法
public static void main(String[] args)
//不写泛型默认Object类型
含有泛型的类<Object> aa = new 含有泛型的类<>();
aa.setName("字符串");
Object name = aa.getName();
System.out.println(name);
// 创建含有泛型的类对象,泛型使用Intergr
// 创建对象的时候,确定泛型类型
含有泛型的类<Integer> aa1 = new 含有泛型的类();
aa1.setName(21);
Integer name1 = aa1.getName();
System.out.println(name1);
// 创建含有泛型的类对象,泛型使用String
含有泛型的类<String> aa2 = new 含有泛型的类();
aa2.setName("字符串");
String name2 = aa2.getName();
System.out.println(name2);
✨定义和使用含有泛型的方法
定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间
格式:
修饰符<泛型> 返回值类型 方法名(参数列表(使用泛型))方法体;
含有泛型的方法,在调用方法的时候确定泛型的数据类型,传递什么类型的参数,泛型就是什么类型。
举例说明
定义含有泛型的方法
public class 泛型方法
//定义一个含有泛型的方法
// M那个写什么都行
public <M> void method01(M m)
System.out.println(m);
//定义一个含有泛型的静态方法
public static <S> void method02(S s)
System.out.println(s);
使用含有泛型的方法
public class 主方法
public static void main(String[] args)
// 创建泛型方法对象
泛型方法 aa = new 泛型方法();
/*
调用含有泛型的方法method01
传递什么类型,泛型就是什么类型
*/
aa.method01(1);
aa.method01("爱睡觉");
aa.method01(3.3);
aa.method01(true);
aa.method02("静态方法,不建议创建对象使用");
// 静态方法,通过类名.方法名(参数) 可以直接使用
泛型方法.method02(33); //它也可以传递任意数据类型
✨定义和使用含有泛型的接口
含有泛型的接口,第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型。例如:
Scanner类实现了Iterator接口,并指定接口的泛型为String,所以重写的next方法默认就是String
public final class Scanner implements Iterator<String>
public String next()
含有泛型接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,实现类跟着接口走,就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型。
那么接下来我们就举例演示一下
首先定义含有泛型的接口
public interface 接口 <I>
public abstract void method(I i);
第一种使用方式
public class 实现类1 implements 接口<String> //实现类指定泛型类型
@Override
public void method(String s)
System.out.println(s);
第二种使用方式
public class 实现类2<I> implements 接口<I> //接口使用什么泛型 实现类就使用什么泛型
@Override
public void method(I i)
System.out.println(i);
测试含有泛型的接口
public class 主方法
public static void main(String[] args)
//创建实现类1对象
实现类1 aa =new 实现类1();
aa.method("字符串");
//创建实现类2对象 创建对象的时候,指定什么泛型 就是什么泛型
实现类2<Integer> bb =new 实现类2();
bb.method(22);
实现类2<Double> cc =new 实现类2();
cc.method(2.2);
// 跟定义含有泛型的类是一样的
✨泛型的通配符
举例说明
public class 泛型的通配符
public static void main(String[] args)
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
ArrayList<String> list2 = new ArrayList<>();
list2.add("a");
list2.add("b");
aa(list1);
aa(list2);
// ArrayList<?> list3 = new ArrayList<>(?); 定义的时候不能用通配符,作为参数传递的时候可以用
/*
第一一个方法,能遍历所有类型的ArrayList集合
这时候我们不知道ArrayList集合使用什么数据类型,可以使用泛型通配符“?” 来接收数据类型
注意:
泛型没有继承概念的 里面不能写Object
*/
public static void aa(ArrayList<?> list) // ArrayList<?> list作为参数传递,使用通配符
//使用迭代器 遍历集合
Iterator<?> it = list.iterator();
while (it.hasNext())
Object obj = it.next(); // 取出类型是Object类型,只要Object才能接收任意类型
System.out.println(obj);
✨通配符的高级使用–受限泛型
泛型的上限限定:? extends E 代表使用的泛型只能是E类型的子类/本身
泛型的下限定:? super E 代表使用的泛型只能是E类型的父类/本身
✨斗地主小案例
按照斗地主的规则,完成洗牌发牌动作。
具体规则: 使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸排,每人17张牌,最后留三张作底牌
代码实战
public class 斗地主案例
public static void main(String[] args)
//1. 准备54张牌,存储到一个集合中
//创建集合
ArrayList<String> list = new ArrayList();
// 定义一个数组,用来存储花色
String [] aa = "♠","♥","♣","♦";
// 定义一个数组,用来存储序号
String [] bb = "2","A","K","Q","J","10","9","8","7","6","5","4","3";
//把大小王加入到集合中
list.add("大王");
list.add("小王");
// 循环嵌套遍历两个数组,组装52张牌
for (String s : aa)
for (String s1 : bb)
// System.out.println(s+s1);
list.add(s+s1);
// System.out.println(list);
//2. 洗牌
// 使用集合工具类Collections的方法
//static void shuffle(List<?> list) 使用指定的随机源对指定列表进行置换,
// 会随机打乱集合中的元素顺序
Collections.shuffle(list);
//3.发牌
//定义四个集合存储三个玩家的牌和底牌
ArrayList<String> aa1 = new ArrayList<>(); //玩家1
ArrayList<String> aa2 = new ArrayList<>();//玩家2
ArrayList<String> aa3 = new ArrayList<>();//玩家3
ArrayList<String> aa4 = new ArrayList<>();//底牌
//
for (int i = 0; i < list.size(); i++)
//获取每一张牌
String s = list.get(i);
//轮流发牌
if (i>=51)
//给底牌发牌
aa4.add(s);
else if (i%3==0)
//给玩家1发牌
aa1.add(s);
else if (i%3==1)
//给玩家2发牌
aa2.add(s);
else if (i%3==2)
//给玩家3发牌
aa3.add(s);
// 看牌
System.out.println("张三"+aa1);
System.out.println("李四"+aa2);
System.out.println("麻子"+aa3);
System.out.println("底牌"+aa4);
输出结果
以上是关于Java重点--泛型的主要内容,如果未能解决你的问题,请参考以下文章