Java容器框架分析(一)——相关概念综述

2017/2/21 posted in  Java  

概述

容器,就是用于容纳其它对象的对象。在Java API中已经实现了很多常用的容器统称为Java Collections Framework(JCF)。JCF起始于JDK 1.2 使用JCF的优点在于:

  • 降低编程难度
  • 提高程序性能
  • 提高API之间的互操作性
  • 降低学习难度
  • 降低设计和实现相关API的难度
  • 增强程序的重用性

Java容器只能存放对象,对于基础类型(如int、double、float等),需要将其包装成对应的包装类型对象后才能放到容器之中,当然很多情况之下拆包和解包过程可以由虚拟机自动完成。

泛型

Java 容器能够容纳任何类型的对象,这一点表面上是通过泛型机制完成,Java 泛型不是什么神奇的东西,只是编译器为我们提供的一个 “语法糖”,泛型本身并不需要Java虚拟机的支持,只需要在编译阶段做一下简单的字符串替换即可。实质上Java的单继承机制才是保证这一特性的根本,因为所有的对象都是Object的子类,容器里只要能够存放Object对象就行了。
事实上,所有容器的内部存放的都是Object对象,泛型机制只是简化了编程,由编译器自动帮我们完成了强制类型转换和类型检测而已。JDK 1.4 以及之前版本不支持泛型,类型转换需要程序员显式完成。

//JDK 1.4 or before
ArrayList list = new ArrayList();
list.add(new String("Monday"));
list.add(new String("Tuesday"));
list.add(new String("Wensday"));
for(int i = 0; i < list.size(); i++){
    String weekday = (String)list.get(i);//显式类型转换
    System.out.println(weekday.toUpperCase());
}
//JDK 1.5 or latter
ArrayList<String> list = new ArrayList<String>();//参数化类型
list.add(new String("Monday"));
list.add(new String("Tuesday"));
list.add(new String("Wensday"));
for(int i = 0; i < list.size(); i++){
    String weekday = list.get(i);//隐式类型转换,编译器自动完成
    System.out.println(weekday.toUpperCase());
}

内存管理

Java不需要程序员来管理内存回收,而是有着一套自动的垃圾回收机制。另外,由于Java里的对象都在堆上,所以容器中放的其实是对象的引用而不是对象本身,这就避免了容器对象的拷贝复制问题。

接口与实现

接口

为了规范容器的行为,统一设计,JCF定义了14种容器接口,他们之间的关系如下图:

Map接口并没有继承自Collection接口,因为Map表示的是关联式容器而不是集合,但是Java在Map接口中提供了从Map转化为Collection的方法,可以方便的将Map切换到集合视图。上图中提供了Queue接口,却没有Stack接口,是因为在JDk 1.6之后Stack接口的功能已经被Deque取代。

实现

上述接口的通用实现类见下表:

迭代器(Iterator)

跟C++的STL一样,JCF的迭代器为我们提供了遍历容器中元素的方法,只有容器本身清楚容器里元素的组织方式,因此迭代器只能通过容器本身得到。每个容器都会通过内部类的形式来实现自己的迭代器,相比C++ STL的迭代器,JCF的迭代器更容易使用。
实例代码:

//通过迭代器来访问容器元素
ArrayList<String> list = new ArrayList<String>();
list.add(new String("Monday"));
list.add(new String("Tuesday"));
list.add(new String("Wensday"));
//得到迭代器
Iterator<String> it = list.iterator();
while(it.hasNext()){
    String weekday = it.next();//访问元素
    System.out.println(weekday.toUpperCase());
}
//JDK 1.5引入了增强的for循环,简化了迭代容器时的写法。
//使用foreach迭代
ArrayList<String> list = new ArrayList<String>();
list.add(new String("Monday"));
list.add(new String("Tuesday"));
list.add(new String("Wensday"));
for(String weekday : list){
    System.out.println(weekday.toUpperCase());
}

声明

本系列博文装载自:https://github.com/CarpenterLee/JCFInternals
作者:CarpenterLee