本文概述
本篇文章将分三块内容对Java中的集合框架进行介绍:
一. 集合框架相关概念
二. 集合体系通用方法
三. 集合遍历—Iteractor
一. 集合框架相关概念
集合:用于存储多个对象的容器
1. 为什么使用集合
在Java的世界中流行这么一句话:“一切皆对象”,任何事物都是以对象的形式体现。那有没有一种容器能够满足我们存储多个对象的需求呢?大家能想到的大概就是数组了,既然我们有了数组,那为什么还要使用集合呢?
首先,虽然数组能够存储对象,但是一旦对数组进行初始化,其长度就无法改变。其次数组只能存储同一类型的对象,这两点注定了数组难以满足Java作为面向对象语言适应存储对象不断变化的需求,这时集合就发挥了他的优势。
2.集合的特点
集合是一种只用于存储对象,但可以存储不同类型的对象,且长度可变的容器
3.数组和集合区别
从对数组和集合的分析中可以总结出两者的区别:
- 长度区别:
- 数组长度不变
- 集合长度可变 - 内容不同
-数组只能存储同一种类型的元素
-集合可以存储不同类型的元素 - 元素的数据类型
-数组可以存储基本数据类型和引用数据类型
-集合只能存储引用数据类型
4. 集合框架体系的形成
满足上述需求之后,如果又有需求提出:在这个容器中我不要重复的元素,或者这么多元素我要有一定的排列顺序等等。
针对不同的需求,Java提供了多种不同的集合类,多种集合类之间又有不同的数据结构(数据的存储方式),但同时他们又有共同的特性,比如存储和获取的功能,我们把这些集合的共性不断向上提取,最终形成了我们的继承体系结构:
二. 集合体系通用方法
在学习理论中,一个人学习一样技能一般方式:
分析:具体到抽象
实现:抽象到具体
使用:使用具体的
所以对于集合体系的学习也可以从较为抽象的Collection接口开始学习,因为学习了Collection就相当于学习了所有集合的共性。既然集合是一个容器,作为容器的共同方法应该不外乎添加,删除,查看,判断和修改等功能。所以在Collection接口中应该会提供这些抽象方法,这时就需要打开万能的API文档进行学习。
根据文档的查阅,我们可以将Collection中的方法分成以下几类(具体例子中以实现类ArrayList为例子):
1. 添加元素:
方法:
boolean add(E e);//添加一个对象,添加成功返回True
boolean addAll(Collection<? extends E> c);//添加一个集合中的所有元素
示例1:
public static void main(String args[]) {
Collection c1 = new ArrayList();
System.out.println("c1:" + c1);
c1.add("Java");
c1.add("Python");
System.out.println("c1:" + c1);
}
输出结果1:
c1:[]
c1:[Java, Python]
示例2:
public static void main(String args[]) {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("Java");
c1.add("Python");
c2.add("Java");
c2.add("wjy2");
System.out.println("c1:" + c1);
c1.addAll(c2);
System.out.println("c1:" + c1);
输出结果
c1:[Java, Python]
c1:[Java, Python, Java, wjy2]
2. 删除元素:
方法:
boolean clear();//清除所有元素
boolean remove(Object o);//移除某个元素
boolean removeAll(Collection<? extends E> c);//移除一个集合中所包含的元素
示例1:
public static void main(String args[]) {
Collection c1 = new ArrayList();
c1.add("Java");
c1.add("Python");
System.out.println("c1:" + c1);
c1.remove("Python");
System.out.println("c1:" + c1);
}
输出结果1:
c1:[Java, Python]
c1:[Java]
示例2:
public static void main(String args[]) {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("Java");
c1.add("Python");
c2.add("Java");
c2.add("wjy2");
c1.removeAll(c2);
System.out.println("c1:" + c1);
输出结果
c1:[Python]
3. 查找元素:
Iterator<E> iterator();//集合的遍历
Object toArray();//将集合转换成为数组,从而通过遍历数组的方式遍历集合
4. 判断内容:
方法:
boolean contains(object o);//集合中是否包括该元素
boolean contains(Collection<? extends E> c);//集合中是否包括该集合
boolean isEmpty();//判断集合是否为空
int size();//集合中元素的数量
示例:
public static void main(String args[]) {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("Java");
c1.add("Python");
c2.add("Java");
c2.add("wjy2");
System.out.println(c1.contains("xxx"));
System.out.println(c1.containsAll(c2));
System.out.println(c1.size());
System.out.println(c1.isEmpty());
}
输出结果:
false
false
2
false
思考:String类和Array类中判断长度是使用size()方法,还是length()方法,还是length属性呢?
5. 修改元素
方法:
boolean retainAll(Collection<? extends E> c);//取两个集合的交集,直接会对元素本身产生作用
示例:
public static void main(String args[]) {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
c1.add("Java");
c1.add("Python");
c2.add("Java");
c2.add("wjy2");
c1.retainAll(c2);
System.out.println("c1:" + c1);
}
输出结果:
c1:[Java]
注意:该方法会在原有集合上做出改变,只要原来的集合有改动就会返回True
三. 集合遍历—Iteractor
1. 集合遍历的方法
还记得集合体系图中最上层的接口Iterable吗?
我们可以通过Iterator来进行集合的遍历,使用while和for语句的代码如下:
while语句方法:
public static void main(String args[]) {
Collection c1 = new ArrayList();
c1.add(new Student("张三",18));
c1.add(new Student("李四",28));
c1.add(new Student("王五",38));
c1.add(new Student("赵六",48));
Iterator iter = c1.iterator();
while(iter.hasNext()) {
Student s = (Student) iter.next();
System.out.println(s.getName() + "---------" + s.getAge());
}
}
for语句方法:
for(Iterator iter = c1.iterator();iter.hasNext();) {
Student s = (Student) iter.next();
System.out.println(s.getName() + "---------" + s.getAge());
}
输出结果:
张三---------18
李四---------28
王五---------38
赵六---------48
从两种方法中不难发现,使用while方法代码非常清晰,具有良好的可读性。使用for方法可读性不如前者,但是能够在一次循环中很快的将Iterator对象变成内存垃圾,及时回收,效率更高。
具体使用哪种方法完全看个人喜好,所以不必纠结。
我们来总结一下集合的使用步骤:
1. 创建集合对象
2. 创建元素对象
3. 把元素添加到集合当中
4. 通过Iterator遍历集合
- 通过集合对象获取迭代器
- 通过迭代器中hasNext()方法判断是否又元素
- 通过迭代器对象next()获取元素并移动到下一个位置
2. 从原理层面理解Iterator集合遍历
学会了遍历的基本格式是不够的,还需要从源码角度理解Iterator的使用机制,才能够更好掌握集合的遍历。
Interator在源码中的框架大致是这样的:
public interface Iterator{
public abstract boolean hasNext();
public abstract Object next();
}
public interface Iterable{
Iterator iterator();
}
public interface Collection extends Iterable{
}
public interface List extends Collection{
}
public class ArrayList implements List{
}
迭代器之所以定义成接口而不是一个类,是因为Java中提供了很多集合类,而这些集合类的数据结构是不同的,存储方式和遍历方式也是不同的,所以最终迭代器被设计为了接口。最终的实现方法不在Collection中,不再List中,而是在具体的实现子类ArrayList中才得以实现。
而无论是集合本身还是集合遍历,都体现出Java作为面向对象语言所具备的继承,多态的特性,体现这Java设计语言本身的智慧与魅力。
本文对集合框架做了简单的概述,之后的文章会对集合具体的实现类做更深入的介绍,欢迎继续观看后续内容,一起体会Java语言的智慧与魅力。