一、泛型(Generic)
1.基本概念:
数据类型的参数化。(把类型当成参数一样传递,只能用引用类型)
2.泛型的好处:
(1)代码可读性更好(不用强制转换)
(2)程序更加安全(只要编译时期没有警告,运行时期就不会出现ClassCastException异常)
3.类型擦除:
编码时采用泛型写的类型参数,编译器会在编译时去掉。
4.泛型类 :
E(在容器中使用,表示容器中的元素)、
T(表示普通的JAVA类)、
K(表示键,类如Map中的键Key)、
V(表示值)、
N(表示数值类型)、
?(表示不确定的JAVA类型)
注意:在创建对象时,指定泛型具体类型
5.泛型接口:
泛型接口和泛型类的声明方式一致
注意:在实现接口时可以传递具体数据类型也可以仍然使用泛型作为数据类型
6.泛型方法:
调用泛型方法时,不需要像泛型类那样告诉编译器是什么类型,编译器可以自动推断出类型。
-非静态方法:可以使用泛型类中所定义的泛型,也可以将泛型定义在方法上。
-静态方法:无法访问类上定义的泛型,必须将泛型定义在方法上。
泛型方法与可变参数:在泛型方法中,泛型也可以定义可变参数类型。
//语法结构:
public <泛型标识符号> void showMsg(泛型标识符号. . . agrs){}
7.泛型中的通配符:
无界通配符:当类型不确定时可以使用
通配符的上下限定:
-通配符的上限限定:
?实际类型可以是上限限定中所约定的类型,也可以是约定类型的子类型
-通配符的下限限定
?实际类型可以是下限限定中所约定的类型,也可以是约定类型的父类
8.泛型的局限性和常见错误:
1)局限性:泛型主要用于编译阶段,编译后生成字节码class文件不包含泛型中的类型信息。类型参数在编译后会替换成Object,运行时虚拟机并不知道泛型。
2)常见错误: 基本类型不能用于泛型,不能通过类型参数创建对象
二、容器介绍
1.容器简介:
基础数组并不能满足我们对于“管理和组织数据的需求”,所以我们需要一种更强大、更灵活、容量随时可以扩容的容器来装载我们的对象。这就是容器也叫集合(Collection)。
2.容器结构:
Collection(单例集合),Map(双例集合)
三、单例集合
1.Collection接口:
(1)接口介绍
Collection表示一组对象,它是集中、收集的意思。Collection接口的两个子接口是List、set接口。
(2)Collection接口中定义的方法:
-增加元素到容器中-从容器中移除元素-容器中是否包含元素-容器中元素的数量
-容器是否为空-清空容器中所有的元素-获取迭代器,用于遍历所有的元素
-本容器是否包含c容器中的所有元素-将容器所有的元素加入本容器
-移除本容器和容器c中都包含的元素-取交集(保留交集)-转化成Object数组
2.List接口
(1)List接口特点:
有序,可重复
(2)List接口常用方法:
-在指定位置插入元素,以前元素全部后移一位
-修改指定位置的元素-返回指定位置的元素
-删除指定位置的元素,后面的元素全部前移一位
-返回第一个匹配元素的索引,如果没有该元素,返回-1
-返回最后一个匹配元素的索引,如果没有该元素,返回-1
1)ArrayList:
1.底层:是使用数组来存储元素.
2.特点:查询效率高,增删效率低,线程不安全。索引查找,索引添加,并集,
交集,差集
2)Vector:
1.底层:是数组,相关方法加了同步检查(synchronized同步标记).
2.特点:线程安全,效率低。
3)LinkedList:
1.底层:用双链表实现的存储。
2.特点:查询效率低,增删效率高,线程不安全
4)总结:LIst实现类的选用规则
需要线程安全时,用Vector
不存在线程安全问题时,查询较多用ArrayList(一般使用它),增加或删除元素较多用LinkedList.
3.Set接口
(1)特点:
无序,不可重复修改
(2)set接口的常用方法:
因为List与Collection都继承Collection接口,且Set没有新增方法,则与List相同
注意:在set中没有索引,所以查找只能遍历查找,没有对应的get(int index)方法
1)HashSet:
1.底层:使用HashMap存储元素
2.特点:HashSet是一个不保证元素的顺序且没有重复元素的集合,是线程并不安全的。HashSet允许有null元素
无序:在hashset中底层使用的hashmap存储元素的。hashMap底层使用的是数组与链表实现元素的存储。元素在数组中存放时,并不是有序存放的也不是随机存放的,而是对元素的哈希值进行运算决定元素在数组中的位置。
不重复:当两个元素的哈希值进行计算得到相同的在数组中的位置时,会调用元素的equals()方法判断两个元素是否相同。如果元素相同则不会添加该元素,如果不相同会使用单向链表保存该元素。
3.自定义存储对象(我记得是必须实现equls方法与hashCode方法)
2)TreeSet:
1.底层:使用TreeMap存储元素
2.特点:可以对元素进行排序。(底层实际是用TreeMap实现的,内部维持了一个简化版的TreeMap,通过key来存储元素,TreeSet内部需要对存储的元素进行排序,因此,我们需要给定排序规则。)
排序 规则实现方式:-1通过元素自身实现比较规则
需要实现Comparable接口中的compareTo方法,该方法中用来定义比较规则。TreeSet通过调用该方法来完成对元素的排序处理。
-2通过比较器指定比较规则
通过比较器定义比较规则时,我们需要单独创建一个比较器需要实现Comparator接口中的compare方法来定义比较规则。在实例化TreeSet时将比较器对象交给TreeSet来完成元素的排序处理。此时元素自身就不需要实现比较规则了。
四、双例集合
1.接口的特点:
存储结构为:Key与Value,一个键只能对应一个值,值可以重复。
2.Map接口中常用的方法:
-把key与value添加到Map集合中
-从指定Map中将所有映射关系复制到此Map中
-删除key对应的value-根据指定的key,获取对应的value
-判断容器中是否包含指定的key
-判断容器中是否包含指定的value
-获取Map集合中所有的key,存储到set集合中
-返回一个Set基于Map.Entry类型包含Map中所有映射
-删除Map中所有的映射
1)HashMap容器的使用
1.采用哈希算法实现,时Map接口最常用的实现类。
2.键不能重复:由于hashMap底层采用了哈希表存储数据,我们要求键不能重复,如果发生重复,新键值替换掉旧的。
3.查找,删除,修改方面都有非常高的效率
4.HashTable类和HashMap用法几乎一样,底层实现几乎一样,只不过HashTable的方法添加了synchronized关键字确保线程同步检查,效率较低。
区别:hashMap线程不安全,效率高。允许key或value为null
hashTable线程安全,效率低。不允许key或value为null
2)TreeMap容器使用
1.支持对key的排序,key需要实现比较规则
2.TreeMap是可以对键进行排序的一种容器,在需要对键排序时可选用treeMap。(treeMap底层是基于红黑树实现的)
3.在使用TreeMap时需要给定排序规则:
-1.元素自身实现比较规则 -2.通过比较器实现比较规则
四、Iterator接口
1.作用:
定义了对单例集合进行迭代的标准
2.Iterator迭代器接口介绍:
Collection接口继承了Iterable接口,在该接口中包含一个名为iterator的抽象方法,所有实现了Collection接口的容器类对该方法做了具体实现。iterator方法会返回一个Iterator接口类型的迭代器对象,在该对象中包含三个方法用于实现对单例容器的迭代处理
3.工作原理:
可以理解为游标
4.Iterator接口定义的三个方法:
boolean hasNext();//判断游标当前位置是否还有元素没有被遍历;
Object next();//返回游标当前位置的下一个元素并将游标移动到下一个位置;
void remove();//删除游标当前位置的元素,在执行完next后该操作只能执行一次;
5.迭代器使用时要注意:
(1)不要在一次循环中多次调用next方法
(2)如果要遍历时,删除集合中的元素,建议使用 iterator.remove();
五、Collections工具类
(操作容器的工具类)java.utils.Collections提供了对Set、List、Map进行排序、填充、查找元素的辅助方法。

