泛型的含义
在类或方法中预支地使用未知的类型。
在接口或方法中预支地使用未知的类型。
注意事项:
一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
泛型的好处:
- 将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
- 避免了类型强转的麻烦。
举例:
好处体现之处:
- 当集合明确类型后,存放类型不一致就会编译报错
- 集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型
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());
}
}
}
泛型的类
定义一个含有泛型二点类,模拟Arraylist集合
泛型是一个未知的数据类型,当我们不确定什么数据类型的时候,可以使用泛型
泛型可以接收任意的数据类型,可以使用Integer,String,Student等
创建对象的时候确定泛型的数据类型
##含有泛型的类
含有泛型的类
package cn.itcast.day02.demo03;
public class GenericClass<E> {
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
package cn.itcast.day02.demo03;
public class GenericDemo {
public static void main(String[] args) {
//不写泛型默认为Object类型
GenericClass gc=new GenericClass();
gc.setName("默认为Object类");
Object obj=gc.getName();
System.out.println(obj);
//创建类对象,泛型使用Integer
GenericClass<Integer> gc2=new GenericClass<>();
gc2.setName(123);
Integer i=gc2.getName();
System.out.println(i);
//创建类对象,泛型使用String
GenericClass<String> gc3=new GenericClass<>();
gc3.setName("我喜欢你");
String str=gc3.getName();
System.out.println(str);
}
}
默认为Object类
123
我喜欢你
泛型的方法
定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间
格式:
修饰符<泛型>返回值类型 方法名(参数类型【谁用泛型】){
//方法体
}
含有泛型的方法,在调用方法的时候确定数据类型
传递什么类型的参数,泛型就是什么类型
类中泛型方法
package cn.itcast.day02.demo03;
public class GenericMethod {
//普通方法
public <M> void method1(M m) {
System.out.println(m);
}
//静态方法
public static <S> void staticmethod(S s){
System.out.println(s);
}
}
package cn.itcast.day02.demo03;
import java.lang.reflect.Method;
public class GenericMethodDemo {
public static void main(String[] args) {
GenericMethod me=new GenericMethod();
me.method1("我喜欢你");
me.method1(123);
me.method1(6.20);
me.method1(true);
//两种方法,类名.方法名来调用
GenericMethod.staticmethod("静态,我喜欢你");
GenericMethod.staticmethod(2.30);
GenericMethod.staticmethod(789);
GenericMethod.staticmethod(false);
}
}
我喜欢你
123
6.2
true
静态,我喜欢你
2.3
789
false
泛型的接口
定义格式:
修饰符 interface接口名<代表泛型的变量> { }
例如,
public interface MyGenericInterface<E>{
public abstract void add(E e);
public abstract E getE();
}
使用格式:
1、定义类时确定泛型的类型
例如
package cn.itcast.day02.demo03;
public interface genericInterface <I>{
public abstract void method(I i);
}
package cn.itcast.day02.demo03;
//含有泛型的接口,第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型
public class genericinterfaceimpl implements genericInterface<String>{
@Override
public void method(String s) {
System.out.println(s);
}
}
此时,泛型E的值就是String类型。
2、始终不确定泛型的类型,直到创建对象时,确定泛型的类型
例如
package cn.itcast.day02.demo03;
//含有泛型的接口第二种使用方式:含有的泛型的接口使用什么类型,实现类就是用什么类型
//相当于定义了一个泛型的类
public class genericinterfaceimpl2<I> implements genericInterface<I> {
@Override
public void method(I i) {
System.out.println(i);
}
}
package cn.itcast.day02.demo03;
public class genericinterfacedemo {
public static void main(String[] args) {
//在创建实现类的时候,确定了类型
genericinterfaceimpl im=new genericinterfaceimpl();
im.method("我喜欢你");
//实现类和接口都是泛型,在创建对象的时候指定类型
genericinterfaceimpl2<Integer> in=new genericinterfaceimpl2<>();
in.method(123);
genericinterfaceimpl2<String> in1=new genericinterfaceimpl2<>();
in1.method("真好");
}
}
```java
我喜欢你
123
真好
泛型通配符
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
通配符基本使用
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。
此时只能接受数据,不能往该集合中存储数据。
package cn.itcast.day02.demo03;
import java.util.ArrayList;
import java.util.Iterator;
public class tongpeifudemo {
public static void main(String[] args) {
ArrayList<Integer> list1=new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
ArrayList<String> list2=new ArrayList<>();
list2.add("我");
list2.add("喜欢");
list2.add("你");
printf(list1);
printf(list2);
}
public static void printf(ArrayList<?> list){
//用迭代器去遍历集合
Iterator<?> it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
tips:泛型不存在继承关系 Collection list = new ArrayList();这种是错误的。
通配符高级使用----受限泛型
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。
泛型的上限:
- 格式:
类型名称 <? extends 类 > 对象名称 - 意义:
只能接收该类型及其子类
泛型的下限:
- 格式:
类型名称 <? super 类 > 对象名称 - 意义:
只能接收该类型及其父类型
比如:现已知Object类,String 类,Number类,Integer类,其中Number是Integer的父类
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement(list1);
getElement(list2);//报错
getElement(list3);
getElement(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}
斗地主实例
package cn.itcast.day02.demo04;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class Doudizhu {
public static void main(String[] args) {
ArrayList<String> puke=new ArrayList<>();
String[] color={"♠","♦","♥","♣"};
String[] list={"2","A","K","Q","J","10","9","8","7","6","5","4","3",};
for(String str1:list)
{
for(String str2:color)
{
puke.add(str2+str1);
}
}
puke.add("大王");
puke.add("小王");
System.out.println(puke);
//2.洗牌使用Collection中的方法
// static void shuffle(List<?> list)
Collections.shuffle(puke);
//3.发牌
//定义四个集合
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 < puke.size(); i++) {
String p= puke.get(i);
if(i>=51){
dipai.add(p);
}
else if(i%3==0){
player1.add(p);
}
else if(i%3==1){
player2.add(p);
}
else if(i%3==2){
player3.add(p);
}
}
System.out.println(player1);
System.out.println(player2);
System.out.println(player3);
System.out.println(dipai);
}
}
```java
[♠2, ♦2, ♥2, ♣2, ♠A, ♦A, ♥A, ♣A, ♠K, ♦K, ♥K, ♣K, ♠Q, ♦Q, ♥Q, ♣Q, ♠J, ♦J, ♥J, ♣J, ♠10, ♦10, ♥10, ♣10, ♠9, ♦9, ♥9, ♣9, ♠8, ♦8, ♥8, ♣8, ♠7, ♦7, ♥7, ♣7, ♠6, ♦6, ♥6, ♣6, ♠5, ♦5, ♥5, ♣5, ♠4, ♦4, ♥4, ♣4, ♠3, ♦3, ♥3, ♣3, 大王, 小王]
[♦4, ♣J, ♥7, ♣3, ♥10, ♥9, ♦3, ♣10, ♣Q, ♣K, ♥K, ♣A, ♠7, ♣2, ♣4, ♥6, ♣9]
[♠2, ♦A, ♦10, ♠A, ♣6, ♠K, ♦8, ♥Q, ♠10, ♠9, ♠J, ♦7, ♣7, ♦J, ♦Q, ♥A, ♥J]
[♦K, ♦2, ♠Q, ♦5, ♣8, 小王, ♥8, ♥2, ♥4, ♠5, ♠4, 大王, ♥3, ♠3, ♣5, ♠8, ♦9]
[♥5, ♦6, ♠6]

package cn.itcast.day02.demo04;
import cn.itcast.day01.demo3.Array;
import java.util.*;
public class OrderDoudizhu {
public static void main(String[] args) {
//1.准备牌
//创建一个Map集合,存储牌的索引和组装好的牌
HashMap<Integer,String> poker=new HashMap<>();
//创建一个牌的索引
ArrayList<Integer> pokerindex=new ArrayList<>();
//定义两个集合,存储花色和牌的序号
List<String> color=List.of("♠","♦","♥","♣");
List<String> number=List.of("2","A","K","Q","J","10","9","8","7","6","5","4","3");
int index=0;
poker.put(index,"大王");
pokerindex.add(index);
index++;
poker.put(index,"小王");
pokerindex.add(index);
index++;
for(String n:number){
for(String c:color){
poker.put(index,c+n);
pokerindex.add(index);
index++;
}
}
System.out.println(poker);
System.out.println(pokerindex);
//2.洗牌
Collections.shuffle(pokerindex);
System.out.println(pokerindex);
//3.发牌
ArrayList<Integer> player1=new ArrayList<>();
ArrayList<Integer> player2=new ArrayList<>();
ArrayList<Integer> player3=new ArrayList<>();
ArrayList<Integer> dipai=new ArrayList<>();
for(Integer in=0;in<pokerindex.size();in++)
{Integer i=pokerindex.get(in);
if(in>=51){
dipai.add(i);
}
else if(in%3==0){
player1.add(i);
}
else if(in%3==1){
player2.add(i);
}
else if(in%3==2){
player3.add(i);
}
}
System.out.println(player1);
System.out.println(player2);
System.out.println(player3);
System.out.println(dipai);
//4.排序
Collections.sort(player1);
Collections.sort(player2);
Collections.sort(player3);
Collections.sort(dipai);
//5.看牌
lookpoker("玩家1:",poker,player1);
lookpoker("玩家2:",poker,player2);
lookpoker("玩家3:",poker,player3);
lookpoker("底牌:",poker,dipai);
}
public static void lookpoker(String name, HashMap<Integer,String> poker,ArrayList<Integer> pokerindex)
{
System.out.print(name);
for(Integer key:pokerindex){
String value=poker.get(key);
System.out.print(value+" ");}
System.out.println();
}
}
{0=大王, 1=小王, 2=♠2, 3=♦2, 4=♥2, 5=♣2, 6=♠A, 7=♦A, 8=♥A, 9=♣A, 10=♠K, 11=♦K, 12=♥K, 13=♣K, 14=♠Q, 15=♦Q, 16=♥Q, 17=♣Q, 18=♠J, 19=♦J, 20=♥J, 21=♣J, 22=♠10, 23=♦10, 24=♥10, 25=♣10, 26=♠9, 27=♦9, 28=♥9, 29=♣9, 30=♠8, 31=♦8, 32=♥8, 33=♣8, 34=♠7, 35=♦7, 36=♥7, 37=♣7, 38=♠6, 39=♦6, 40=♥6, 41=♣6, 42=♠5, 43=♦5, 44=♥5, 45=♣5, 46=♠4, 47=♦4, 48=♥4, 49=♣4, 50=♠3, 51=♦3, 52=♥3, 53=♣3}
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53]
[2, 15, 9, 34, 5, 50, 44, 53, 11, 14, 35, 32, 36, 8, 39, 20, 51, 49, 22, 10, 43, 4, 27, 17, 6, 48, 26, 31, 40, 1, 38, 52, 3, 21, 25, 33, 37, 19, 45, 29, 0, 23, 13, 7, 24, 47, 42, 12, 46, 41, 30, 18, 28, 16]
[2, 34, 44, 14, 36, 20, 22, 4, 6, 31, 38, 21, 37, 29, 13, 47, 46]
[15, 5, 53, 35, 8, 51, 10, 27, 48, 40, 52, 25, 19, 0, 7, 42, 41]
[9, 50, 11, 32, 39, 49, 43, 17, 26, 1, 3, 33, 45, 23, 24, 12, 30]
[18, 28, 16]
玩家1:♠2 ♥2 ♠A ♣K ♠Q ♥J ♣J ♠10 ♣9 ♦8 ♠7 ♥7 ♣7 ♠6 ♥5 ♠4 ♦4
玩家2:大王 ♣2 ♦A ♥A ♠K ♦Q ♦J ♣10 ♦9 ♦7 ♥6 ♣6 ♠5 ♥4 ♦3 ♥3 ♣3
玩家3:小王 ♦2 ♣A ♦K ♥K ♣Q ♦10 ♥10 ♠9 ♠8 ♥8 ♣8 ♦6 ♦5 ♣5 ♣4 ♠3
底牌:♥Q ♠J ♥9