【JavaSE 八】泛型

八、泛型

集合中的泛型

​ 不适用泛型,容器里默认放的类型为Object,所有类型都可以放,但是在取出时需要强制转换

​ 使用泛型后,不仅可以放置该泛型类型的数据,还可以放置其子类的数据。

​ 设计这个类的时候,在类的声明上,加上一个,表示该类支持泛型,在实例化是指定泛型类型。

通配符

​ ? extends T 不能add对象,只能get对象,而且get到的对象类型为T

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

class Fruit { }
class Apple extends Fruit { }
class Banana{ }

public class txt {
    public static void main(String[] args){
        List<Fruit> list = new ArrayList<Fruit>();//它可以add自身或子类对象
        list.add(new Fruit());//自身
        list.add(new Apple());//子类
        list.add(new Banana());//其他不相关类  报错

        List<Fruit> list1 = new ArrayList<Banana>();//报错--不同泛型的容器不能相互引用,除非使用通配符

        List<? extends Fruit> list2 = new ArrayList<Banana>();//报错--不是子类不能引用

        List<? extends Fruit> list3 = new ArrayList<Apple>();//是子类可以引用
        list3.add(new Fruit());//报错--不能add任何东西
        Fruit fruit = list3.get(0);//可以get,返回的类型为Fruit
    }
}

​ ? super T

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

class Fruit { }
class Apple extends Fruit { }
class RedApple extends Apple{}
class Banana{ }

public class txt {
    public static void main(String[] args){
        List<? super Apple> list1 = new ArrayList<Fruit>();//是父类可以引用
        list1.add(new Apple());//可以放自身
        list1.add(new RedApple());//可以放子类
        Object object = list1.get(0);//取出对象类型是Object,但这样的话, 元素的类型信息就全部丢失
        
        

        List<? super Apple> list3 = new ArrayList<Banana>();//报错--不是父类不能引用

    }
}

​ 泛型通配符?

​ 泛型通配符? 代表任意泛型

​ 既然?代表任意泛型,那么换句话说,这个容器什么泛型都有可能

​ 所以只能以Object的形式取出来
​ 并且不能往里面放对象,因为不知道到底是一个什么泛型的容器

​ 总结:

​ 如果希望只取出,不插入,就使用? extends Hero

​ 如果希望只插入,不取出,就使用? super Hero
​ 如果希望,又能插入,又能取出,就不要用通配符?

泛型转型

​ 根据面向对象学习的知识,子类转父类 是一定可以成功的

​ 那么子类泛型转父类泛型能成功吗?答案肯定是失败的

练习

1)练习-泛型

​ 根据数字类的知识,设计一个集合,这个集合里即可以放整数,也可以放浮点数,但是不能放字符串

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

public class Exercise {
    public static void main(String[] args) {
        List<Number> list =new ArrayList<>();
        list.add(123);
        list.add(1.23f);
        list.add("123")//报错
    }
}

2)练习-支持泛型的二叉树

​ 把二叉树中的Node类,改造成支持泛型

public class PersonNode<T> {
   private PersonNode<T> leftNode;
   private PersonNode<T> rightNode;
   private T value;

    public void add(T t ){
        if(this.value == null){
           this.value = t;
        }else {
            if((Integer)this.value > (Integer) t){
                if(this.leftNode == null){
                    this.leftNode = new PersonNode<T>();
                }
                this.leftNode.add(t);
            }else {
                if(this.rightNode == null){
                    this.rightNode = new PersonNode<T>();
                }
                this.rightNode.add(t);
            }
        }
    }

    public PersonNode<T> getLeftNode() {
        return leftNode;
    }

    public PersonNode<T> getRightNode() {
        return rightNode;
    }

    public T getP() {
        return value;
    }
}

3)练习- extends

​ 如代码所示,为了遍历不同泛型的3种集合,需要设计3个方法

​ 借助? extends, 把代码减肥到只是用一种方法

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

class Fruit { }
class Apple extends Fruit { }
class Banana extends Fruit{ }


public class Exercise {
    public static void main(String[] args) {
        List<Fruit> list =new ArrayList<>();
        List<Apple> list1 =new ArrayList<>();
        List<Banana> list2 =new ArrayList<>();
        list.add(new Fruit());
        list1.add(new Apple());
        list2.add(new Banana());
        traversal(list);
        traversal(list1);
        traversal(list2);
    }
    public static void traversal(List<? extends Fruit> list){
        for (Fruit f : list) {
            System.out.println(f);
        }
    }
}

4)练习-二叉树

​ 把练习-支持泛型的二叉树改造成 支持泛型 ,并在比较的时候使用compare方法

public class PersonNode<T extends Comparable> {
   private PersonNode<T> leftNode;
   private PersonNode<T> rightNode;
   private T value;

    public void add(T t ){
        if(this.value == null){
           this.value = t;
        }else {

            if(this.value.compareTo(t) > 0){
                if(this.leftNode == null){
                    this.leftNode = new PersonNode<T>();
                }
                this.leftNode.add(t);
            }else {
                if(this.rightNode == null){
                    this.rightNode = new PersonNode<T>();
                }
                this.rightNode.add(t);
            }
        }
    }

    public PersonNode<T> getLeftNode() {
        return leftNode;
    }

    public PersonNode<T> getRightNode() {
        return rightNode;
    }

    public T getP() {
        return value;
    }
}

5)练习-父类泛型能否转换为子类泛型?

​ 那么父类泛型又能否转换成子类泛型? 为什么?

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

class Fruit { }
class Apple extends Fruit { }
class Banana extends Fruit{ }


public class Exercise {
    public static void main(String[] args) {
        List<Fruit> list =new ArrayList<>();
        List<Apple> list1 =new ArrayList<>();
        List<Banana> list2 =new ArrayList<>();
        /***
         * 假设允许转型
         *      list指向了list2容器
         *      由于list泛型为Fruit,所以可以放Apple
         *      这样就导致一个Banana容器放置了一个Apple
         *      不符合逻辑
         */
        list = list2;//子类泛型转父类失败
        /***
         * 假设允许转型
         *      list2指向了list容器
         *      当list2需要出去对象时,容器里面放的都是Fruit
         *      把Banana的类型指向Fruit的类型是不和逻辑的
         */
        list2 = list;//父类泛型转子类失败

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值