Java12-泛型

https://www.nowcoder.com/tutorial/94/ae05554a3ad84e42b6f9fc4d52859dc4

https://how2j.cn/frontroute
https://how2j.cn/k/generic/generic-generic/373.html

1 集合泛型

1.1 泛型的便利

不用泛型:

	public static void main(String[] args) {    
        ArrayList heros = new ArrayList();
         
        heros.add(new APHero());
        heros.add(new ADHero());
         
        APHero apHero =  (APHero) heros.get(0);
        ADHero adHero =  (ADHero) heros.get(1);
         
        ADHero adHero2 =  (ADHero) heros.get(0);
    }

ADHero adHero2 = (ADHero) heros.get(0); 就会报错

使用泛型:

public static void main(String[] args) {
        ArrayList<APHero> heros = new ArrayList<APHero>();
         
        //只有APHero可以放进去    
        heros.add(new APHero());
         
        //ADHero甚至放不进去
        //heros.add(new ADHero());
         
        //获取的时候也不需要进行转型,因为取出来一定是APHero
        APHero apHero =  heros.get(0);
    }

1.2 子类对象

public static void main(String[] args) {
        ArrayList<Hero> heros = new ArrayList<Hero>();
         
        //只有作为 Hero 的子类可以放进去     
        heros.add(new APHero());
        heros.add(new ADHero());
         
        //和 Hero 无关的类型 Item 放不进去
        //heros.add(new Item());
    }

1.3 简写

public static void main(String[] args) {
        ArrayList<Hero> heros = new ArrayList<Hero>();
        //后面可以只用<>
        ArrayList<Hero> heros2 = new ArrayList<>();         
    }

1.4 练习

设计集合,可以放整数,也可以放浮点数,但不能放字符串

package16个程序_泛型.a1_集合泛型.练习;

import java.util.ArrayList;
import java.util.List;

public class test {
    public static void main(String[] args) {
        List<Number> list = new ArrayList<>();
        list.add(1);
        list.add(12.2);
//        list.add("12");
        System.out.println(list);
    }
}

2 泛型的类

比较【不能泛型】和【泛型】的好处

2.1 不能泛型

package16个程序_泛型.a2_泛型的类.s1_比较.不可泛型;

public class Hero {
    String name;
    float hp; //血量
    float armor; //护甲
    int moveSprrd; //速度

    public Hero(String name){
        this.name = name;
    }
}
package16个程序_泛型.a2_泛型的类.s1_比较.不可泛型;

// 物品
public class Item {
    String name;
    int price;

    public Item(String name){
        this.name = name;
    }
}
package16个程序_泛型.a2_泛型的类.s1_比较.不可泛型;

import java.util.LinkedList;

public class HeroStack {
    LinkedList<Hero> heros = new LinkedList<>();

    //进栈
    public void push(Hero hero){
        heros.addLast(hero);
    }

    //出栈
    public Hero pull(){
        return heros.removeLast();
    }

    //获取栈顶元素
    public Hero peek(){
        return heros.getLast();
    }

    public static void main(String[] args) {
        HeroStack stack = new HeroStack();
        for (int i = 0;i < 10; i++){
            Hero h = new Hero("hero " + i);
            System.out.println("进栈: " + h.name);
            stack.push(h);
        }

        System.out.println("\n出栈:");
        for (int i = 0; i < 10; i++){
            Hero h = stack.pull();
            System.out.println(h.name);
        }
    }
}

package16个程序_泛型.a2_泛型的类.s1_比较.不可泛型;

import java.util.LinkedList;

public class ItemStack {
    LinkedList<Item> items = new LinkedList<>();
    public void push(Item item){
        items.addLast(item);
    }

    //出栈
    public Item pull(){
        return items.removeLast();
    }

    //取栈顶元素
    public Item peek(){
        return items.getLast();
    }

    public static void main(String[] args) {
        ItemStack stack = new ItemStack();
        for (int i = 0;i < 10; i++){
            Item item = new Item("item " + i);
            System.out.println("进栈: " + item.name);
            stack.push(item);
        }

        System.out.println("\n出栈:");
        for (int i = 0; i < 10; i++){
            Item item = stack.pull();
            System.out.println(item.name);
        }
    }
}

2.2 可以泛型

package16个程序_泛型.a2_泛型的类.s1_比较.可以泛型;

public class Hero {
    String name;
    float hp; //血量
    float armor; //护甲
    int moveSprrd; //速度

    public Hero(String name){
        this.name = name;
    }
    public Hero() {
    }
}
package16个程序_泛型.a2_泛型的类.s1_比较.可以泛型;

// 物品
public class Item {
    String name;
    int price;

    public Item(String name){
        this.name = name;
    }
}
package16个程序_泛型.a2_泛型的类.s1_比较.可以泛型;

import java.util.LinkedList;

public class MyStack<T> {
    LinkedList<T> list = new LinkedList<>();
    int length = 0;

    //进栈
    public void push(T t){
        list.addLast(t);
        length++;
    }

    //出栈
    public T pull(){
        return list.removeLast();
    }

    //获取栈顶元素
    public T peek(){
        return list.getLast();
    }

    public static void main(String[] args) {
        MyStack<Hero> heroMyStack = new MyStack<>();
        System.out.println("进栈 heroMyStack :");
        heroMyStack.push(new Hero("hero " + 1));
        heroMyStack.push(new Hero("hero " + 2));
        System.out.println("出栈 :");
        for (int i = 0; i < heroMyStack.length; i++){
            System.out.println(heroMyStack.pull().name);
        }

        MyStack<Item> itemMyStack = new MyStack<>();
        System.out.println("\n进栈 itemMyStack :");
        itemMyStack.push(new Item("item " + 1));
        itemMyStack.push(new Item("item " + 2));
        System.out.println("出栈:");
        for (int i= 0; i < itemMyStack.length; i++){
            System.out.println(itemMyStack.pull().name);
        }
    }
}

2.3 练习

二叉树的 Node 改成泛型

package16个程序_泛型.a2_泛型的类.练习_二叉树;

public class Hero {
    String name;
    float hp; //血量
    float armor; //护甲
    int moveSprrd; //速度

    public Hero(String name){
        this.name = name;
    }
}
package16个程序_泛型.a2_泛型的类.练习_二叉树;

import15个程序_集合框架.a4_其他.s2_比较器.排序Comparable.Hero;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Node<T extends Comparable<T>> {
    public Node<T> left;
    public Node<T> right;
    public T value;

    //插入
    public void add(T e){
        if (value == null)
            value = e;
        else {
            if (e.compareTo(value) <= 0){
                if (left == null)left = new Node<>();
                left.add(e);
            } else{
                if (right == null)right = new Node<>();
                right.add(e);
            }
        }
    }

    public List<T> values(){
        List<T> list = new ArrayList<>();
        if (left != null){
            list.addAll(left.values());
        }
        list.add(value);
        if (right != null){
            list.addAll(right.values());
        }
        return list;
    }

    public static void main(String[] args) {
        Node<Integer> node = new Node<>();
        node.add(1);
        node.add(2);
        node.add(3);
        node.add(4);
        System.out.println("输出 Node<Integer> node :");
        System.out.println(node.values());

        Random r = new Random();
        Node<Hero> node1 = new Node<>();
        for (int i = 0; i < 5; i++){
            node1.add(new Hero("hero " + r.nextInt(100)));
        }
        System.out.println("\nNode<Hero> node1");
        System.out.println(node1.values());
    }
}

3 通配符

先总结:
只取 不插,用? extends Hero
只插 不取,用? super Hero
又能插入,又能取出,不要用通配符?

3.1 ? extends

ArrayList heroList<? extends Hero>:这是 Hero 泛型或其子类泛型

heroList 的泛型可能是Hero
heroList 的泛型可能是APHero
heroList 的泛型可能是ADHero

从 heroList 取出的对象,一定可以转成 Hero 的
但不能往里面放东西

3.2 ? super

ArrayList heroList<? super Hero>:这是 Hero 泛型或其父类泛型
heroList 的泛型可能是 Hero
heroList 的泛型可能是 Object

可以往里面插入 Hero 以 Hero 子类
但取元素有风险,因为不确定取出来是 Hero 还是 Object

3.3 泛型通配符 ?

? 代表任意泛型,这个容器什么泛型都有可能
只能以 Object 的取出来
不能往里放对象,因为不知道这是什么泛型的容器

3.4 练习1

如下代码所示,遍历不同泛型的 3 种集合,要设计 3 个方法
借助? extends, 把代码减到只用 1 种方法

package generic;
 
import java.util.ArrayList;
 
import charactor.ADHero;
import charactor.APHero;
import charactor.Hero;
 
public class TestGeneric {
 
    public static void iterate(ArrayList<Hero> list) {
        for (Hero hero : list) {
            System.out.println(hero.name);
        }
    }
 
    public static void iterateAP(ArrayList<APHero> list) {
        for (Hero hero : list) {
            System.out.println(hero.name);
        }
    }
 
    public static void iterateAD(ArrayList<ADHero> list) {
        for (Hero hero : list) {
            System.out.println(hero.name);
        }
    }
 
    public static void main(String[] args) {
        ArrayList<Hero> hs = new ArrayList<>();
        ArrayList<APHero> aphs = new ArrayList<>();
        ArrayList<ADHero> adhs = new ArrayList<>();
 
        iterate(hs);
        iterateAP(aphs);
        iterateAD(adhs);
    }
}

解答:

package16个程序_泛型.a3_通配符.练习;

import java.util.ArrayList;
import java.util.List;

public class test {
    public static void iterate(List<? extends Hero> list){
        System.out.println("遍历:");
        for (Hero hero:list){
            System.out.println(hero.name);
        }
        System.out.println();
    }

    public static void main(String[] args) {
        ArrayList<Hero> hs = new ArrayList<>();
        ArrayList<ADHero> adhs = new ArrayList<>();
        ArrayList<APHero> aphs = new ArrayList<>();

        hs.add(new Hero("hero 1"));
        hs.add(new Hero("hero 2"));

        adhs.add(new ADHero("adhero 1"));
        adhs.add(new ADHero("adhero 2"));

        aphs.add(new APHero("aphero 1"));
        aphs.add(new APHero("aphero 2"));

        iterate(hs);
        iterate(adhs);
        iterate(aphs);
    }
}

3.5 练习2

二叉树改造成 支持泛型 <T extends Comparable>
比较时,用 compare 方法

package16个程序_泛型.a3_通配符.练习2;

public class Hero implements Comparable<Hero> {
    String name;
    float hp; //血量
    float armor; //护甲
    int moveSprrd; //速度

    public Hero(String name){
        this.name = name;
    }

    @Override
    public int compareTo(Hero o) {
        if(hp > o.hp)
            return 1;
        else
            return -1;
    }
}
package16个程序_泛型.a3_通配符.练习2;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Node<T extends Comparable<T>> {
    public Node<T> left;
    public Node<T> right;
    public T value;

    //插入
    public void add(T e){
        if (value == null)
            value = e;
        else {
            if (e.compareTo(value) <= 0){
                if (left == null)left = new Node<>();
                left.add(e);
            } else{
                if (right == null)right = new Node<>();
                right.add(e);
            }
        }
    }

    //中序遍历
    public List<T> inOder(){
        List<T> list = new ArrayList<>();
        if (left != null){
            list.addAll(left.inOder());
        }
        list.add(value);
        if (right != null){
            list.addAll(right.inOder());
        }
        return list;
    }

    public static void main(String[] args) {
        Node<Integer> node = new Node<>();
        node.add(1);
        node.add(2);
        node.add(3);
        node.add(4);
        System.out.println("输出 Node<Integer> node :");
        System.out.println(node.inOder());

        Random r = new Random();
        Node<Hero> node1 = new Node<>();
        for (int i = 0; i < 5; i++){
            node1.add(new Hero("hero " + r.nextInt(100)));
        }
        System.out.println("\nNode<Hero> node1");
        for (Hero hero: node1.inOder()){
            System.out.println(hero.name);
        }
    }
}

4 泛型转型

4.1 对象转型 可行

子类转父类 = 父 = 子 = Hero h = new ADHero(); = 中国人 a = new 湖北人();

4.2 子类泛型 转 父类泛型 不可行

public static void main(String[] args) {
        ArrayList<Hero> heros = new ArrayList<>();
        ArrayList<ADHero> adHeroes = new ArrayList<>();
        heros = adHeroes;
    }

会报错!

假设转型成功
ArrayList<Hero> heros 可以放入 APHero
ArrayList<ADHero> adHeroes又当成 ArrayList<Hero> heros
相当于 ArrayList<ADHero> adHeroes 中放入了 APHero,矛盾!
子类泛型 转 父类泛型 不可行
父类泛型 转 子类泛型 不可行(同样)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1403034144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值