我们知道,数组作为一种容器,它的长度是不可变的,这就导致我们必须在使用数组前预估所需要的大小,很不方便。而接下来我们要介绍的集合也是一种容器,和数组类似,集合也必须存储一系列相同类型的元素。不过集合的长度是可变的。
之前我们熟知的 ArrayList<E>
类型就是典型的集合类型,其中E是泛型的意思,在集合中,E必须是引用对象类型。这就告诉我们,不能使用java中的基本数据类型,必须使用引用数据类型。那么如果我们就是想使用基本数据类型怎么办?当然是用包装类啦。例如我们要存储整数序列。可以这样声明ArrayList
:
ArrayList<Integer> myArr=new ArrayList<Integer>();
其他的集合也类似。
下面我们正式开始集合的学习。
集合的概述
我们学到的集合会有很多,但最常见的无非是下面几种:
Vector<E>
ArrayList<E>
LinkedList<E>
TreeSet<E>
HashSet<E>
LinkedHashSet<E>
这些集合看看起来很多,其实主要分为两大类。
一类是Vector<E> ArrayList<E> LinkedList<E>
这三种,他们都是有序的,可以存储重复元素,最关键的是:他们都有下标索引,所以可以使用for循环遍历,而且可以使用get(index)
直接访问。
这一类容器中,我们把他们中的共性抽取出来,写成抽象函数(他们重写后函数同名但是具体实现可能不同),然后将抽象函数封装到List
接口中。
剩下的三种中,LinkedHashSet<E>
是HashSet<E>
的子类,而TreeSet<E>
和HashSet<E>
都不能存储重复数据,而且没有下标索引,所以不能使用for循环遍历.
我们把这两个容器的公共特性抽取出来,写成抽象函数(函数名相同,但两种容器的重写方式不同),封装到Set
接口中。
然后我们把Set
接口和List
接口中的共性继续抽取,写成抽象函数放到Collection
接口中。
具体实现的图示如下
图中有错误不知道大家有没有发现。是的,List,Set,Collection都是接口,而不是集合。这有什么意义呢?
我们知道,接口(或者是抽象类)是不能实例化对象的。
所以我们学习的时候虽然是自顶向下学习,但是会使用多态,即父类的索引(或接口的索引)指向子类的对象(或接口的实现)。
下面我们正式开始自顶向下学习集合
Collection
作为这一组集合的根接口,Collecton接口中的所有方法在本组集合中都可以使用,下面介绍几个共性的方法。
import java.util.Collection;
import java.util.ArrayList;
首先作为工具,Collection是存在java.util包中的。
接口是抽象的,所以我们使用多态,即Collection
的索引指向ArrayList
的
对象。
Collection<Integer> myColl=new ArrayList<Integer>();//多态
然后我们打印索引试试:
System.out.println(myColl);
显示的结果是这样的:
我们知道,打印索引,正常情况下应该打印地址的哈希值,但打印出了这么个东西,说明Collection重写了从Object类(一切类的祖宗)继承来的toString()
myColl.add(3);
myColl.add(3);
myColl.add(42);
System.out.println(myColl);
打印出来是这样的
但是千万要注意了,不能使用for循环遍历,也不能使用[]
类似数组的下表访问法,因为我们刚说完,Collection
是抽取Set
和List
的共性得到的,List
有索引可以使用get(index)
,Set
无索引不能使用get(index)
,共性就是不能使用get(index)
喽。
果然直接就报错了
注意,前面说集合里面只能放引用数据类型,很多人疑问,为什么现在这里直接添加了基本数据类型呢?因为现在的JDK支持自动拆箱和自动装箱。所以基本类型就会自动被打包为引用数据类型了,所以大家可以放心使用。
Collection<Integer> myColl=new ArrayList<Integer>();//多态
myColl.add(3);
myColl.add(3);
myColl.add(42);
myColl.remove(3);//移除第一个出现的3
myColl.clear();//清空集合中所有元素
System.out.println(myColl.contains(3));//判断集合中有没有出现过该对象
System.out.println(myColl.isEmpty());//判断现在集合是否为空
System.out.println(myColl.size());//返回集合中元素的个数
Object [] a=myColl.toArray();//Object数组可以接受任何对象
for(int i=0;i<a.length;i++){
System.out.println(a[i]);
}
由于Collection
是这些集合的根接口,所以这些方法是Collection
后代类(或者说是实现类)都可以用的,只不过玩一个多态,各自的具体实现或许略有不同。