今天介绍JavaSE中一个常用的工具——集合,在介绍前,先看看一张集合框架关系图,我将集合中常用的接口和实现类做类标志,让刚入门的伙伴大概知道需要学习哪些常用的集合类,至于其他未作标记的接口或是实现类可以做个了解。
集合中有两大总接口分别是Collection接口和Map接口。而Collection接口下有List和Set两个接口,实际上对于常用的集合类来说,我们只需学习List接口、Set接口和Map接口,大体上就足够了。
List接口的两个实现类:1、ArrayList(这个算是所有集合类中最常用的集合类,重点掌握)2、LinkList
Set接口的两个实现类:1、HashSet 2、TreeSet
Map接口的两个实现类:1、HashMap 2、TreeMap
有没有发现Set接口的两个实现类和Map接口的两个实现类很相似,都有Hash和Tree,这里可以先说Set接口底层的原理就是用Map接口实现的。
介绍到这,大家对集合中常用类有了一个名字上的印象和几者之间关系的认识。
简单的谈谈集合由来,我们都知道对象可以用来封装对象,但是要是对象也多了呢?
没有变化我们同样需要一个容器存储对象,而这个容器就是集合,集合是专门用来存储对象的类,这时集合的最大特点。有了这一层认识后,开始学习集合对象。
我们将集合定义为了存储对象的容器,既然是容器,就应该会操作容器中元素(容器中的对象的另一种叫法)的方法,再知道具体有哪些方法前,我们是不是可以自己推测出一些方法呢?
首先可以往容器中添加对象,是不是该有个添加的方法,Collection接口确实有提供添加的方法boolean add(Object obj),以此推测,应该会有删除方法:boolean remove(Object obj);判断方法:如判断是否为空boolean isEmpty()、判断是否包含某对象boolean contains(Object obj);获取集合对象中的方法:Iterator iterator()这个方法现在不了解没关系,我们现在只需知道这是一个获取集合对象的方法,所有的Collection对象都可以用这个方法获取集合中的元素;获取集合大小方法:int size()。
说到这基本把Collection接口中常用的方法讲完了,而List接口和Set接口又是继承Collection接口,同样包含父接口Collection这些常用方法,又将List接口和Set接口中的一些常用方法说完了,额,是不是太简单了,当然不是这样的,对象是千变万化的,只有一种容器是满足不了我们日常的需求,我们需要不同的容器应用在不同的场合中。因此才会有Set接口、List接口和Map接口等。而我们需要重点学习这些不同接口的自身的特点和应用场景。
概念有了,现在可以先来做个具体的例子。
运行环境:JDK1.7 开发工具:Myeclipse10.7
新建一个java工程,定义一个CollectionTest1测试类。首先有一个问题:Collection是一个接口,它不能实例化为对象,这时需要选择一个它的实例类,我们就先选择最常用的ArrayList实现类来测试。具体代码如下:
package com.java.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* Collction集合常用方法测试
*/
public class CollectionTest1 {
//创建Collection对象
@SuppressWarnings("rawtypes")
Collection container = new ArrayList();
/**
* 添加对象(元素)
*/
@SuppressWarnings("unchecked")
public void addElement(){
container.add("张三");
container.add("李四");
container.add("王五");
System.out.println(container);
}
/**
* 删除对象(元素)
*/
public void deleteElement(){
container.remove("张三");
System.out.println(container);
}
/**
* 判断对象(元素)
*/
public void judgeElement(){
System.out.println("是否包含王五" + container.contains("王五"));
System.out.println("是否包含张三" + container.contains("张三"));
}
/**
* 获取对象(元素)
*/
@SuppressWarnings("rawtypes")
public void getElement(){
//第一种形式
System.out.println("第一种获取元素方法");
for(Iterator it = container.iterator(); it.hasNext();){
System.out.print(it.next() + "\t");
}
System.out.println();
//第二种形式
Iterator it = container.iterator();
System.out.println("第二种获取元素方法");
while(it.hasNext()){
System.out.print(it.next() + "\t");
}
}
public static void main(String[] args) {
CollectionTest1 ct1 = new CollectionTest1();
//添加
ct1.addElement();
//删除
ct1.deleteElement();
//判断
ct1.judgeElement();
//获取
ct1.getElement();
}
}
有几个注意点:
1、控制台打印Collection对象和打印集合中的元素区别:
Collection对象
System.out.print(Collection对象);
它会以 [ 元素 ] 形式输出在控制台上,如上图
而
System.out.print(it.next());打印获取到的集合中元素,没有方括号。
2、获取集合中元素的两种形式
在此先说下Iterator接口
Iterator接口,之前在Collection基本方法中提起到,之前只是有了个初步了解,知道Iterator接口是用来获取集合中元素。接下来我们就简单介绍这个集合对象的特殊接口——迭代器。
对于迭代器我们不需要知道它详细的代码实现方法,可以肯定的是它底层涉及到了遍历的算法。需要了解的是:迭代器是在容器内部实现的,也就是说集合中的内部类实现类该接口。具体原因是因为每一个容器数据结构都不同,它必须依赖具体容器。每一种容器因为内部数据结构的不同,获取其中元素方法必然会有所不同。通过该方式可以不需要暴露容器对象内部细节。可以说,对使用容器的人而言,迭代器的具体实现不重要,只要通过容器获取该迭代器的实现对象即可获取容器中元素。
总结一下:
1、迭代器是在Collection的内部类中被实现。
2、无需关注迭代器具体实现,获取迭代器对象就可以使用了。
3、通过迭代器获取集合元素,可隐藏集合对象的内部细节。
接下来再看迭代器的具体应用方法。
//第一种形式
for(Iterator it = container.iterator(); it.hasNext();){
System.out.print(it.next() + "\t");
}
//第二种形式
Iterator it = container.iterator();
System.out.println("第二种获取元素方法");
while(it.hasNext()){
System.out.print(it.next() + "\t");
}
hasNext()用于判断集合中是否有元素
next()用于获取集合中元素
此处有两种遍历方式,一种是for循环,另一种是while循环。两者各有优缺点,for循环有点是限定类Iterator对象的访问,在for循环结束后Iterator对象所占用内存便被释放,缺点:可读性差。while循环再循环外定义Iterator对象,循环结束后,Iterator对象依然存储,优点:可读性好点。两者遍历方式while()循环应用较多。