欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java语言入门 (四)java 泛型与收集API(6)

程序员文章站 2022-05-23 15:31:59
...

1.0 java 泛型

1.1 泛型的使用

泛型的本质是参数化类型 也就是说什么类型是由你输入决定的,泛型可以用在类,接口,方法。分别叫做泛型类,

泛型接口,泛型方法,在我看来,类似C++里的模板

用法:<>之间定义形式类型参数

package aggregate;

public class FX <T>{
    private T a;

    public T getA() {
        return a;
    }

    public void setA(T a) {
        this.a = a;
    }

    public String toString(){
        return "这个参数的类型是"+a.getClass().getName()+"  "+"值为:"+a;
    }

    public static void main(String[] args) {
        FX<Integer> fx = new FX<Integer>();
        /**
            上面的代码还可以这么写
            FX fx = new FX();
            不指定泛型类型 由参数类型直接决定
        */
        fx.setA(10);
        System.out.println(fx);
    }
}

结果:
java语言入门 (四)java 泛型与收集API(6)

几点说明:

  1. 泛型的类型参数只能是类类型,包括自定义类型 也就是说FX< Integer> fx = new FX< Integer>(); <>里不能是int
  2. 泛0型的类型参数可以有多个例如 Map< K,V >
    类型参数说的是定义阶段
    参数类型说的是使用阶段
  3. 参数类型可以使用继承语句 表示限定参数的范围 例如 public class FX < T extends Number> //限定T的类型<=Number
  4. 泛型的参数类型还可以是通配符类型 例如ArrayList
/*
泛型的好处
    编译时确定类型,保证类型安全,避免类型转换异常。
    避免了强制类型转换。
    代码利于重用,增加通用性。

泛型的限制和规则
    泛型的类型参数只能是引用类型,不能使用值类型。
    泛型的类型参数可以有多个。
    泛型类不是真正存在的类,不能使用instanceof运算符。
    泛型类的类型参数不能用在静态申明。
    如果定义了泛型,不指定具体类型,泛型默认指定为Ojbect类型。
    泛型使用?作为类型通配符,表示未知类型,可以匹配任何类型。因为是未知,所以无法添加元素。
    类型通配符上限:<? extends T>,?代表是T类型本身或者是T的子类型。常用于泛型方法,避免类型转换。
    类型通配符下限。<? super T>,?代表T类型本身或者是T的父类型。
    除了通配符可以实现限制,类、接口和方法中定义的泛型参数也能限制上限和下限。

*/

//通配符的使用
package aggregate;

public class QQ {
    //因为不知道要传入泛型是什么,所以用通配符表示任何的类型  因为泛型不是类 所以不能用Object
    public void Test001(FX<?> as){
        System.out.println(as);
    }
}

1.2 comparable< T> 接口与comparator< T>接口

一个类实现了comparable接口,这个类就是可以比较的,这个类组成的集合就可以进行排序
看例子

package aggregate;

import java.lang.reflect.Array;
import java.util.*;

public class Compara implements Comparable<Compara>{
    private int age;
    private String name;
    public Compara(int age,String name){
        this.age =age;
        this.name =name;
    }
    @Override
    public int compareTo(Compara o) {
        // TODO Auto-generated method stub
        return this.age - o.age;
    }

    @Override
    public String toString(){
        return "这个人叫 "+name+"  这个人的年龄是 "+age;
    }
    public static void main(String[] args) throws Exception {
        Compara compara0 = new Compara(100, "xyd");
        Compara compara1 = new Compara(10, "xyd");
        Compara compara2 = new Compara(15, "xyd");
        System.out.println(compara0.compareTo(compara1));//比较这两个对象
        Compara compara[] = {compara0,compara1,compara2};
        Arrays.sort(compara);//数组排序
        for(Compara a:compara){
            System.out.println(a);
        }

    }
}

结果:
90
这个人叫 xyd 这个人的年龄是 10
这个人叫 xyd 这个人的年龄是 15
这个人叫 xyd 这个人的年龄是 100

我在测试的时候使用的是JDk1.8 找不到 Arrays类 应该是Eclipse版本太低的原因 换成1.7解决问题

comparator接口常用与以下

  1. 类的设计时没有考虑比较的问题,这时候我们就可以自己实现比较了
  2. 排序的时候需要升序逆序啥的
package aggregate;
//要对这个类排序
public class NOCompara {
    private int age;
    public NOCompara(int age){
        this.age = age;
    }
    public int getAge(){
        return this.age;
    }

    public String toString(){
        return "age = "+age;
    }
}

//写排序的类
package aggregate;

import java.util.Arrays;
import java.util.Comparator;

public class ComparatorImp implements Comparator<NOCompara> {

    @Override
    public int compare(NOCompara o1, NOCompara o2) {
        // o2-o1 是降序排列   o1-o2 是升序排列
        return o2.getAge()  - o1.getAge();
    }

        public static void main(String[] args) {
            NOCompara as[]  = {new NOCompara(7),new NOCompara(700),new NOCompara(100)};
            Arrays.sort(as,new ComparatorImp());

            for (NOCompara noCompara : as) {
                System.out.println(noCompara);
            }
        }
}

2.0 Collection API 简介 收集api(我原来喜欢说集合 后来发现不准确)

2.1 Collection的层次结构

java语言入门 (四)java 泛型与收集API(6)

这个接口有以下的方法
向这个收集中 添加 元素,删除 判断是否存在,收集的大小,收集变为数组等等 自己查阅api
jdk中 没有一个类直接实现这个接口,而是实现他的子接口 set接口和list 接口

2.2 set接口

set接口是你可以理解为数学上的集合 特点是无序,没有重复元素
这个接口在collection的接口上明确了一些语义,例如 add(Object A) 不能添已经在集合中的元素

他有一个实现类HashSet

一个子接口 SortedSet 接口 他的实现类是TreeSet();
TreeSet 的底层实现是红黑树 他的特点是数据时按顺序存放的,至于是逆序还是顺序取决于比较算子Comparator

扩展
Hash 的意思就是散列函数 详情请查看数据结构

2.3 list接口

list接口类似数学上的数列模型,也就是序列 其特点是可以有重复元素,并且是有序的 元素的顺序是从0开始的

list有许多方法,详情查阅api
例如:
add(E element); //在尾部插入元素
add(int pos,E element); //在指定位置插入元素
get(int pos);//得到指定位置的元素
*
*
*
很多

2.3.1 ArrayList与LinkedList 类

ArrayList 底层实现是数组 大小可变,访问速度快,插入效率低
LinkedList 底层实现是双向链表 访问效率慢,插入效率高 提供了头尾增删访问的方法addFirst(Object obj头部插入

2.3.2 Vector(矢量)类和Stack(栈)类

1.0 Vector和ArrayList 差不多,现在通常会用后面的,区别是前者是线程同步的,使用的同时会对他加锁,也实现了可变大小的数组,容量不够时候会增加
2.0 Stack的数据结构是堆栈,特点是先进后出 有下面的几个方法

方法 说明
push() 入栈
pop() 出栈 同时删除了栈顶元素
peek() 读栈顶元素不删除
empty() 判断栈时候为空

3.0 Collectionl类

这个类定义了一些对收集,集合操作的一些方法 具体查阅api

4.0 Map接口及实现层次java语言入门 (四)java 泛型与收集API(6)

map接口是以 键值对的方式存储的,与collection接口下的不一样,

这个接口的实现类很多 最常用的是HashMap HashTable 他们俩的区别就好像,ArrayList与Vector的区别

HashTable 是线程访问安全的

有很多方法,查阅api

欢迎评论交流