java语言入门 (四)java 泛型与收集API(6)
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);
}
}
结果:
几点说明:
- 泛型的类型参数只能是类类型,包括自定义类型 也就是说FX< Integer> fx = new FX< Integer>(); <>里不能是int
- 泛0型的类型参数可以有多个例如 Map< K,V >
类型参数说的是定义阶段
参数类型说的是使用阶段 - 参数类型可以使用继承语句 表示限定参数的范围 例如 public class FX < T extends Number> //限定T的类型<=Number
- 泛型的参数类型还可以是通配符类型 例如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接口常用与以下
- 类的设计时没有考虑比较的问题,这时候我们就可以自己实现比较了
- 排序的时候需要升序逆序啥的
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的层次结构
这个接口有以下的方法
向这个收集中 添加 元素,删除 判断是否存在,收集的大小,收集变为数组等等 自己查阅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接口及实现层次
map接口是以 键值对的方式存储的,与collection接口下的不一样,
这个接口的实现类很多 最常用的是HashMap HashTable 他们俩的区别就好像,ArrayList与Vector的区别
HashTable 是线程访问安全的
有很多方法,查阅api
欢迎评论交流