一.泛型
1. 泛型:广泛的数据类型,确保类型安全的一种途径
2.instanceof也是确保类型安全的一种手段
(1).泛型类的定义
在类或方法上都可以使用泛型
返回的类型和传入的类型是同一种
EasyGenericity<J,M,N,Y,Easy> {
private M m;
public void test(M m,N n){
}
public static <J extends List> J testA(J j){
return j;
}
public <E> E test(E e){
return e;
}
类型转换时没有明确对象的数据类型进行强制数据类型转换会抛出ClassCaseException(类型转换异常)类型不安全
public static void main(String[] args) {
testA(new ArrayList());
//类型安全
List list=new ArrayList();
list.add("123");
for(Object object:list){
//类型不安全
String str=(String)object;
System.out.println(str);
}
List<String> listA=new ArrayList<>();
listA.add("123");
Map<String,Object> map=new HashMap<>();
//只要是泛型就是对象
}
}
泛型类的语法格式:
第一种:class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
第二种: class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
在返回值类型前面定义
注:泛型只能接受类,所有的基本数据类型必须使用包装类!
T可以代表任何数据类型,方便我们指定类型传参。
注:类名后的 <T> 代表占位符,表示当前类是一个泛型类
当我们不确定数据类型时,我们可以暂时使用一个字母 T代替数据类型,例如写一个方法,但是我们不知道它是传递的是什么数据类型,我们就可以使用泛型,到时候只要指明T是什么数据类型,就可以使用了。
(2).泛型的数组使用
泛型使用数组时: T[] ts = new T[5];//是不对的
原因:在编译时时,会把T转换为Object,而Object范围很大,到时候就无法确定是什么数据类型了。
(3).泛型的上界
语法格式:
class 泛型类名称<类型形参 extends 类型边界> {
...
}
示例:
public class MyArray<E extends Number> {
... //相当于 < T >
}解析:可以把<E extends Number>当成<T>来看,Number可能是接口,也可能是类。而此时的T,有了限制,T的范围是 Number的子类。
注:泛型无下界。
(4).泛型的方法
语法格式:方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }
//静态的泛型方法 需要在static后用 <> 声明泛型类型参数
public static <E> void swap(E[] array, int i, int j) {
E t = array[i];
array[i] = array[j];
array[j] = t;
}注:其他的方法不需要用 <> 声明
二、Set集合
(1).
List是有序集合(取出顺序与添加顺序是一样的),Set是无序的(取出顺序和添加顺序不一样)
Set中不能存储相同的数据。
(2).1. 实例化HashSet
HashSet set=new HashSet();
HashSet可以存储空值
TreeSet不能存储空值
存入数据使用add();
set.add("123");
删除数据
set.remove("123");
获取Set元素个数
set.size();
TreeSet底层使用红黑树实现 不能存Null值
树的遍历:先序遍历 中序遍历 后序遍历 (根据访问根节点的顺序命名),无论哪种便利都是先左后右 2. TreeSet遍历方式 中序遍历 TreeSet 内部使用二叉树 内部节点是可以比较大小 同一个TreeSet对象中存储的内容都应该是可比较的 默认情况下不能存储不同类型
3. LinkedHashSet 是有序的集合Set,是线程不安全的,底层实现是LinkedHashMap
三.Map
1. Map 存的是键值对 键---名字 值---对象 Map不属于collection
2.
Map map = new HashMap();
//存放数据
map.put("A1", "张三");
//可以通过存入数据的key获取存入的对象
Object obj = map.get("A1");//获取A1对应的value值
System.out.println(obj);
///通过key删除键值对
Object rem_obj = map.remove("A1");
System.out.println("删除的value值:" + rem_obj);
//是否包含key
map.containsKey("A1");
//是否包含value值
map.containsValue("张三");
//获取所有的key
Set setKey = map.keySet();
//获取所有的value
Collection con = map.values();
map.put(null, null);//可以为空
map.put("A1", null);
map.put("A1", "张三");
System.out.println(map);
3. TreeMap
key应该是可比较的,不能是null
4.
Hashtable key和value都不能是null值
Hashtable 是线程安全的集合,效率较低
5.
ConcurrentHashMap 线程安全 效率较高
四.HashMap 底层实现---数组加链表
HashMap的数组默认容量为16 每次扩容两倍 扩容阈值 0.75 存入12个元素扩容 一个链上达到8就对该链进行树化 一个树上的元素低于6这个数就退化成链 最小树化容量阈值 64 如果数组的长度没有达到64,优先扩容 注意:线程安全的Map 有两个 Hashtable(性能不高)和ConcurrentHashMap(性能优异 锁的颗粒度比较小)