泛型以及通配符<?>

泛型(规定集合中存取数据的类型)

泛型的概念

泛型的好处:

创建集合对象,不使用泛型

好处:集合不使用泛型,默认的类型就是object类型,可以存储任意类型的数据

弊端:不安全,会引发异常

创建集合对象,使用泛型

好处:

1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型

2.把运行期异常(代码运行之后抛出异常),提升到编译期(写代码的时候)

弊端:泛型是什么类型,只能存储什么类型的数据

定义和使用含泛型的类
package commonclass;

public class TestGeneric01 {
    public static void main(String[] args) {
        //不写泛型,默认泛型为object类型
        GenericClass genericClass01 = new GenericClass();
        genericClass01.setName("object对象");
        Object name = genericClass01.getName();//object类型
        System.out.println(name);

        //在创建对象时,泛型使用Integer类型,
        GenericClass<Integer> genericClass02 = new GenericClass<>();
        genericClass02.setName(1);//自动装箱
        System.out.println(genericClass02.getName());//自动拆箱

        //在创建对象时,泛型使用String类型
        GenericClass<String> genericClass03 = new GenericClass<>();
        genericClass03.setName("张三");
        System.out.println(genericClass03.getName());
    }
}
/*定义一个含有泛型的类
* 泛型是一个未知的数据类型,只有在创建对象是才被确定,所有当我们不确定使用什么数据类型时,可以使用泛型
* 泛型可以接收任何引用数据类型,不能接收基本数据类型(需要用到其包装类)
* 在创建对象的时候,才能确定泛型的数据类型*/
class GenericClass<E> {
    private E name;

    public E getName() {
        return name;
    }

    public void setName(E name) {
        this.name = name;
    }
}
定义和使用含泛型的方法
package commonclass;

public class TestGenericMethod01 {
    public static void main(String[] args) {
        GenericMethod01 genericMethod01 = new GenericMethod01();
        //传递什么类型,泛型就是什么类型
        genericMethod01.printE(1);
        genericMethod01.printE("hello");
    }
}
/*定义含有泛型的方法:泛型定义在修饰符和返回值之间
* 格式:
* 修饰符 <泛型> 返回值 方法名(参数列表(使用泛型)){
* 方法体;
* }
* 含有泛型的方法,在调用方法的时候确定泛型的数据类型
* 传递什么参数,泛型就是什么类型*/
class GenericMethod01{
    public <E> void printE(E e){
        System.out.println(e);
    }
}
泛型接口的定义和使用
package commonclass;
//定义含有泛型的接口
public interface GenericIterface<E> {
    public abstract void method(E e);
}
package commonclass;
//含有泛型的接口的两种使用方式
//第一种:定义接口的实现类,实现其接口,并指定接口的泛型
public class GenericIterfaceImpl implements GenericIterface<String>{
    @Override
    public void method(String s) {
        System.out.println(s);
    }
}

class Test01{
    public static void main(String[] args) {
        GenericIterfaceImpl genericIterface = new GenericIterfaceImpl();
        genericIterface.method("哈哈哈哈");
    }
}
package commonclass;
//含有泛型的接口的第二种使用方式:接口使用什么泛型,类就使用什么泛型,类跟着接口走
//就相当于创建了一个含有泛型的类,创建对象时确定泛型
//注意:类名和接口名后都要加泛型格式
public class GenericIterfaceImpl2<E> implements GenericIterface<E>{

    @Override
    public void method(E e) {
        System.out.println(e);
    }
}

class Test2{
    public static void main(String[] args) {
        GenericIterfaceImpl2<String> genericIterfaceImpl2 = new GenericIterfaceImpl2<>();
        genericIterfaceImpl2.method("哈哈哈哈哈哈");
    }
}
泛型的通配符:<?>

?:代表任意类型的数据

使用方式:不能创建对象时使用,只能作为方法参数使用

package commonclass;

import java.util.ArrayList;

public class TestGeneric02 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);

        ArrayList<String> arrayList1 = new ArrayList<>();
        arrayList1.add("abc");
        arrayList1.add("abc");
        arrayList1.add("abc");

        printArrayList(arrayList);
        printArrayList(arrayList1);
    }
    /*定义一个方法,能够打印任意数据类型的arrayList集合
    * 由于不知道arrayList集合里面的数据类型,可以用通配符来接收数据
    * 注意:泛型没有继承关系的*/
    public static void printArrayList(ArrayList<?> arrayList){//如果写成ArrayList<object> ,调用方法时会出错,泛型没有继承关系的
        for (Object o : arrayList) {
            System.out.println(o);
        }
    }
}
通配符的高级使用---受限泛型
package commonclass;

import java.util.ArrayList;
import java.util.Collection;

/*
* 泛型的上限限定:<? extends E> 代表泛型只能使用其子类/本身
* 泛型的下限限定:<? super E> 代表泛型只能使用其父类/本身
* */
public class TestGeneric03 {
    public static void main(String[] args) {
        Collection<Integer> list1 = new ArrayList<>();
        Collection<String> list2 = new ArrayList<>();
        Collection<Number> list3 = new ArrayList<>();
        Collection<Object> list4 = new ArrayList<>();

        getElement1(list1);
        getElement1(list2);//报错
        getElement1(list3);
        getElement1(list4);//报错


        getElement2(list1);//报错
        getElement2(list2);//报错
        getElement2(list3);
        getElement2(list4);
    }
    /*继承关系
    * Integer extends Number extends Object
    * String extends Object*/
    //泛型的上限限定:<? extends E> 代表泛型只能使用其子类/本身
    public static void getElement1(Collection<? extends Number> collection){}
    //泛型的下限限定:<? super E> 代表泛型只能使用其父类/本身
    public static void getElement2(Collection<? super Number> collection){}
}
练习:斗地主综合案例

分析:

package commonclass;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

//模仿斗地主发牌
public class PracticeAll {
    public static void main(String[] args) {
        //准备54张牌
        Collection<String> arrayList = new ArrayList<>();
        arrayList.add("♠");
        arrayList.add("♥");
        arrayList.add("♣");
        arrayList.add("♦");
        Collection<String> arrayList2 = new ArrayList<>();
        for (int i = 2; i <= 10; i++) {
            arrayList2.add(Integer.toString(i));
        }
        arrayList2.add("J");
        arrayList2.add("Q");
        arrayList2.add("K");
        arrayList2.add("A");

        ArrayList<String> list = new ArrayList<>();//54张牌集合

        for (String al2 : arrayList2) {
            for (String al1 : arrayList) {
                list.add(al1+al2);
            }
        }
        list.add("joker");
        list.add("JOKER");
        //输出检查54张牌
        for (String s : list) {
            System.out.print(s+"\t");
        }
        System.out.println();
        //将54张牌打乱
        Collections.shuffle(list);
        //输出检查54张牌
        for (String s : list) {
            System.out.print(s+"\t");
        }
        System.out.println();


        //准备四个集合,容纳三个人的牌和底牌
        ArrayList<String> a1 = new ArrayList<>();
        ArrayList<String> a2 = new ArrayList<>();
        ArrayList<String> a3 = new ArrayList<>();
        ArrayList<String> bottom = new ArrayList<>();

        //依次每人发一张牌,留下最后三张牌,插底
        for (int i = 0; i < list.size(); i++) {
            if (i >=  51) {
                bottom.add(list.get(i));
                continue;
            }
            if (i % 3 == 0){
                a1.add(list.get(i));
                continue;
            }
            if (i % 3 == 1){
                a2.add(list.get(i));
                continue;
            }
            if (i % 3 == 2){
                a3.add(list.get(i));
                continue;
            }
        }

        //对每个人手中的牌进行排序,按花色类型(这儿还可以优化,先按牌大小,再按花色排序)
        Collections.sort(a1);
        Collections.sort(a2);
        Collections.sort(a3);
        Collections.sort(bottom);

        //查看三个人手中的牌,插底的牌
        System.out.println("第一个人手中的牌:");
        for (String s : a1) {
            System.out.print(s+"\t");
        }
        System.out.println();

        System.out.println("第二个人手中的牌:");
        for (String s : a2) {
            System.out.print(s+"\t");
        }
        System.out.println();

        System.out.println("第三个人手中的牌:");
        for (String s : a3) {
            System.out.print(s+"\t");
        }
        System.out.println();

        System.out.println("插底的三张牌:");
        for (String s : bottom) {
            System.out.print(s+"\t");
        }
    }
}

加强版:可对看牌进行排序

package commonclass;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
//斗地主发牌,改进版,在看牌时,可对牌进行排序
public class PracticeAll02 {
    public static void main(String[] args) {
        //准备54张牌
        ArrayList<Poker> pokerAll = new ArrayList<>();
        String[] types = {"♠","♥","♣","♦"};
        String[] nums ={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        for (String type : types) {
            for (int i = 0; i < nums.length; i++) {
                pokerAll.add(new Poker(type,nums[i],i));
            }
        }
        pokerAll.add(new Poker("□","joker",13));
        pokerAll.add(new Poker("■","JOKER",14));
        System.out.println(pokerAll);

        //打乱54张牌
        Collections.shuffle(pokerAll);
        System.out.println(pokerAll);

        //准备四个集合,放三个玩家的牌和底牌
        ArrayList<Poker> p1 = new ArrayList<>();
        ArrayList<Poker> p2 = new ArrayList<>();
        ArrayList<Poker> p3 = new ArrayList<>();
        ArrayList<Poker> bottom = new ArrayList<>();
        ArrayList[] arrayLists = {p1,p2,p3,bottom};

        //开始发牌
        for (int i = 0; i < pokerAll.size(); i++) {
            if (i >= 51){
                bottom.add(pokerAll.get(i));
            }else if (i % 3 == 0){
                p1.add(pokerAll.get(i));
            }else if (i % 3 == 1){
                p2.add(pokerAll.get(i));
            }else if (i % 3 == 2){
                p3.add(pokerAll.get(i));
            }
        }
        //对玩家手中的牌进行排序
        for (ArrayList list : arrayLists) {
            Collections.sort(list, new Comparator<Poker>() {
                @Override
                public int compare(Poker o1, Poker o2) {
                    int result = o2.getWeight() - o1.getWeight();//先按权重
                    if (result == 0){
                        result = o1.getType().hashCode() - o2.getType().hashCode();//再根据花色
                    }
                    return result;
                }
            });

        }

        //查看每位玩家的牌和底牌,优化
        for (int i = 0; i < arrayLists.length; i++) {
            if (i == arrayLists.length - 1){
                System.out.println("底牌为:");
            }else {
                System.out.println("第"+(i+1)+"位玩家手中的牌:");
            }
            Iterator iterator = arrayLists[i].iterator();
            while (iterator.hasNext()){
                Poker poker = (Poker) iterator.next();
                System.out.print(poker.getType()+poker.getNum()+"\t");
            }
            System.out.println();
        }
       /* System.out.println("第一位玩家手中的牌:");
        for (Poker poker : p1) {
            System.out.print(poker.getType()+poker.getNum()+"\t");
        }
        System.out.println();
        System.out.println("第二位玩家手中的牌:");
        for (Poker poker : p2) {
            System.out.print(poker.getType()+poker.getNum()+"\t");
        }
        System.out.println();
        System.out.println("第三位玩家手中的牌:");
        for (Poker poker : p3) {
            System.out.print(poker.getType()+poker.getNum()+"\t");
        }
        System.out.println();
        System.out.println("底牌为:");
        for (Poker poker : bottom) {
            System.out.print(poker.getType()+poker.getNum()+"\t");
        }
*/
    }
}

class Poker{
    private String type;
    private String num;
    private int weight;

    public Poker() {
    }

    public Poker(String type, String num, int weight) {
        this.type = type;
        this.num = num;
        this.weight = weight;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getNum() {
        return num;
    }

    public void setNum(String num) {
        this.num = num;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "Poker{" +
                "type='" + type + '\'' +
                ", num='" + num + '\'' +
                ", weight=" + weight +
                '}';
    }
}
posted @ 2020-08-10 19:05  DannyBoy~  阅读(973)  评论(0编辑  收藏  举报