java学习(八)-集合与泛型

1、装箱和拆箱

在这里插入图片描述
在这里插入图片描述

2、封装类的使用1,是作为泛型的类型参数传入
  • ArrayList类型的声明是正确的。ArrayList声明是错误的。因为泛型的规则是你只能指定类和接口类型。后面那种声明方法无法通过编译
3、集合
  • ArrayList:
  • LinkedList:针对经常插入或者删除中奖元素所涉及的高效率集合
  • HashMap:存取较高效,是用成对的key/value的形式来保存和取出
  • LinkedHashMap:类似HashMap。但可记住元素插入的顺序,也可以设定成依照元素上次存取的先后来排序
  • TreeSet:以有序状态保持并可放在重复,当往集合中存储元素的时候,会花一定的时间去找合适的 位置(即是排序),如果是对顺序没有要求的,用ArrayList集合更高效
  • HashSet:防止重复的集合,可快速查找相符的元素
4、泛型,泛型接口:list、map、set等
  • 泛型意味着更好的类型安全性。运用泛型,你可以创建类型安全更好的集合,让问题尽可能的在编译阶段就能抓到,而不会是在执行期间才被发现;若不是泛型的集合,则编译器会很乐意接受你不同类型的对象放在同一个集合中。
  • 泛型的使用1:创建被泛型化类的实例new ArrayList<Song>()
  • 泛型的使用2:声明与指定泛型类型的变量List<Song> songList = new ArrayList<Song>()
  • 泛型的使用3:声明或调用取用泛型类型的方法void foo(List<Song> list)、x.foo(songList)
  • 泛型接口:List、Map、Set
4.1、泛型的好处

泛型的好处是在编译的时候检查类型安全并且所有的强制转换都是自动和隐式的,提高代码的重用率。

  • 类型安全,主要目标是提高 Java 程序的类型安全。
  • 消除强制类型转换。
5、一些常用说法
  • ArrayList也可以通过指定位置的方式在集合中添加元素。但是这种会比较慢。
  • Collections.sort(stringList)会把stringList中的String依照字母排序。但是若Collections.sort(songList),songList是一个对象类型的集合,此时是不允许编译通过的。Collections的sort方法定义为public static <T extends Comparable<? super T.> void sort(List<T> list),这个说明sort只能接口Comparable对象的list,而Song不是Comparable的子型,所以无法进行排序,编译不通过。
6、comparable与comparator
  • 调用单一参数的sort(List o)方法代表有list元素的compareTo()方法来决定顺序,因此元素必须实现Comparable的接口
  • 调用sort(List o, Comparator c)方法代表不会调用list元素的compareTo()的方法,而会调用Comparaotr的compare()方法,这意味着list元素不需要实现Comparable接口
    注意:不是所有的类都需要实现Comparable接口的,会让人误解。
7、对象的等价
7.1、set将两个对象视为重复:
  • x.equals(y)返回true
  • x的hashCode与y的hashCode相等;满足这两个条件,视为重复对象
7.2、相等性
  • 引用相等性,使用==来比较变量的字节组合。如果引用到相同的对象,字节组合会一样
  • 对象相等性:(x.equals(y)) && (x.hashCode() == y.hashCode())(对象必须覆盖过object的hashCode方法,不然因为大部分的java版本是依据内存位置来计算hashCode方法返回的序号值,一般都会不一样。所以需要重写,,才能确保两个对象有相同的hashCode);
  • x.equals(y)返回true,则x.hashCode()==y.hashCode()等值
  • x.hashCode()==y.hashCode()等值,但是 x.equals(y)不一定会返回true;由于hash算法有可能会发生碰撞,不同的值可能会返回相同的hashCode值。
8、TreeSet的元素是有序列表,必须有方法来排序。
  • 集合中的元素必须是有实现Comparable的类型,通过实现它的compareTo的方法进行排序
  • 使用重载,调用Comparator参数的构造器来创建TreeSet。通过compator的实现类的compare方法进行排序
9、参数化类型
  • 普通的参数化类型,可以支持参数化的向上转型,即父类引用指向子类的实例对象
public void go5(){
        Animal animal = new Animal();
        Dog dog = new Dog();
        takeAnimals5(dog);//向上转型,把子类的对象直接赋给父类的引用,成功的
        takeAnimals6(animal);//会报错,编译不通过
        takeAnimals6((Dog) animal);
    }

    public void takeAnimals5(Animal animal){
    }

    public void takeAnimals6(Dog dog){

    }
  • 数组类型的参数化传递
    数组类型校验是在允许阶段,编译会通过
public void go(){
        Animal[] animals = {new Dog(),new Cat(),new Dog()};
        Dog[] dogs = {new Dog(),new Dog(),new Dog()};
        takeAnimals(animals);
        takeAnimals(dogs);
    }

    public void takeAnimals(Animal[] animals){
        for (Animal a:animals){
            a.eat();
        }

    }
public void go3(){
        Dog[] dogs = {new Dog(),new Dog(),new Dog()};
        takeAnimals3(dogs);
    }

    public void takeAnimals3(Animal[] animals){
        //编译通过,但是执行会报错,因为数组的类型校验是运行期间,不允许往dog类型的数组里添加Cat类型的对象
        animals[0] = new Cat();

    }
  • 集合参数类型的传递,只能是一一对应的关系
    集合类型的参数校验是在编译阶段就进行校验
public void go2(){
        ArrayList<Animal> animals = new ArrayList<Animal>();
        animals.add(new Dog());
        animals.add(new Cat());
        animals.add(new Dog());

        ArrayList<Dog> dogs = new ArrayList<Dog>();
        dogs.add(new Dog());
        dogs.add(new Dog());

        takeAnimals2(animals);
        //编译报错,由于集合的类型校验,是在编译期间。集合参数化,只能是一一对应的关系。
        takeAnimals2(dogs);//编译不通过
        takeAnimals4(animals);//编译不通过
        takeAnimals4(dogs);
        takeAnimals7(animals);
        takeAnimals7(dogs);
    }

    public void takeAnimals2(ArrayList<Animal> animals){
        for (Animal a:animals){
            a.eat();
        }
    }
    public void takeAnimals4(ArrayList<Dog> dogs){
        for (Dog a:dogs){
            a.eat();
        }
    }
    //采用万能字符实现多态化集合参数类型的校验
    public void takeAnimals7(ArrayList<? extends Animal> animals){
        for (Animal a:animals){
            a.eat();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值