Java的泛型【类,接口,方法】

泛型的含义

方法中预支地使用未知的类型。
接口方法中预支地使用未知的类型。
注意事项
一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为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:♠22 ♠A ♣K ♠Q ♥J ♣J ♠10987776544 
玩家2:大王 ♣2 ♦A ♥A ♠K ♦Q ♦J ♣10976654333 
玩家3:小王 ♦2 ♣A ♦K ♥K ♣Q ♦1010988865543 
底牌:♥Q ♠J ♥9 

版权声明:本文为m0_50837538原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。