开发和学习中需要时刻和数据打交道,如果组织这些数据是我们编程中重要的内容。 我们一般通过“容器”来容纳和管理数据。
事实上,数组就是一种容器,可以在其中放置对象或基本类型数据。
数组的优势:是一种简单的线性序列,可以快速的访问数组元素,效率高。如果从效率和类型检查的角度讲,数组是最好的。
数组的劣势:不灵活:容量事先定义好,不能随着需求的变化而扩容。比如:我们在一个用户管理系统中,要把今天注册的所有用户取出来,那么这个用户有多少个?我们在写程序时是无法确定的。因此,就不能使用数组。
因此,数组远远不能满足我们对于“管理和组织数据的需求”。我们需要一种更强大、更灵活的,容量随时可扩的容器来装载我们的对象。 这就是我们今天要学习的容器,或者叫集合。
图1 容器中的接口层次结构
泛型Generics
泛型是JDK5.0以后增加的,他可以帮助我们建立类型安全的集合。在使用了泛型的中,不必进行强制类型转换。JDK提供了支持泛型的编译器,将运行时的类型检查提前到了编译时执行,使代码可读性和安全性更高。
泛型的本质就是“数据类型的参数化”。 我们可以把“泛型”理解为类型的一个占位符(形式参数),即告诉编译器,在调用泛型时必须传入实际类型。
自定义泛型
我们可以在类的声明处增加泛型列表,如:<T,E,V>。 此处,字符可以是任何标识符,一般采用这3个字母。
【示例1】泛型类的声明
class MyCollection<E> { Object[] objs = new Object[5]; public E get(int index){ return (E)objs[index]; } public void set(E e ,int index){ objs[index] = e; } } |
泛型E像一个占位符一样表示“未知的某个数据类型”,我们在真正调用的时候传入这个“数据类型”。
public class TestGenerics { public static void main(String[] args) { MyCollection<String> mc = new MyCollection<String>(); mc.set("aaa", 0); mc.set("bbb", 1);
String str = mc.get(1); //由于加了泛型,直接返回的就是String类型
System.out.println(str); } } |
容器中使用泛型
容器相关类都定义了泛型,我们在开发和工作中,在使用容器类时都要使用泛型。这样,在容器的存储数据、读取数据都避免了大量的类型判断,非常便捷。
【示例2】泛型的使用
public static void main(String[] args) { List<String> list = new ArrayList<String>(); Set<Man> mans = new HashSet<Man>(); Map<Integer, Man> maps = new HashMap<Integer, Man>(); Iterator<Man> iterator = mans.iterator(); } |
通过阅读源码,我们发现Collection、List、Set、Map、Iterator接口都定义了泛型:
因此,我们在使用这些接口及其实现类时,都要使用泛型。
菜鸟雷区 我们只是强烈建议使用泛型。事实上,不使用编译器也不会报错! |
Collection接口
Collection 表示一组对象,它是集中、收集的意思。Collection接口的两个子接口是List、Set接口。
Collection接口中定义的方法
方法 | 说明 |
boolean add(Object element) | 增加元素到容器中 |
boolean remove(Object element) | 从容器中移除元素 |
boolean contains(Object element) | 容器中是否包含该元素 |
int size() | 容器中元素的数量 |
boolean isEmpty() | 容器是否为空 |
void clear() | 清空容器中所有元素 |
Iterator iterator() | 获得迭代器,用于遍历所有元素 |
boolean containsAll(Collection c) | 本容器是否包含c容器所有元素 |
boolean addAll(Collection c) | 将容器c中所有元素增加到本容器 |
boolean removeAll(Collection c) | 移除本容器和容器C中都包含的元素 |
boolean retainAll(Collection c) | 取本容器和容器C中都包含的元素,移除非交集元素 |
Object[] toArray() | 转化成Object数组 |
由于List、Set是Collection的子接口,意味着所有List、Set的实现类都有上面的方法。我们下一节中,通过ArrayList实现类来测试上面的方法。
「全栈Java笔记」是一部能帮大家从零到一成长为全栈Java工程师系列笔记。笔者江湖人称 Mr. G,10年Java研发经验,曾在神州数码、航天院某所研发中心从事软件设计及研发工作,从小白逐渐做到工程师、高级工程师、架构师。精通Java平台软件开发,精通JAVAEE,熟悉各种流行开发框架。
笔记包含从浅入深的六大部分:
A-Java入门阶段
B-数据库从入门到精通
C-手刃移动前端和Web前端
D-J2EE从了解到实战
E-Java高级框架精解
F-Linux和Hadoop