《Java编程思想》中提过:如果一个程序只包含固定数量的且其生命周期都是已知的对象,那么这是一个非常简单的程序。
如果我们编写的程序中对象的数量和生命周期是已知的,那么可以依靠创建命名的引用来持有每一个对象,例如我们需要两个Person对象,可以:
Person p1 = new Person();
Person p2 = new Person();
但在我们项目开发中,仅靠这么做,会存在两个非常普遍的问题:
为了解决这个问题,Java提供了两种常用的保存对象方式:
Java的集合类主要由两个接口派生而出:Collection和Map,这两个接口又包含了一些接口或实现类,见下图。
注:虚线框表示abstract类或接口,实线框表示实现类。
Collection(集合)
一个“独立”的元素序列,通常这些元素都服从某些规则
(1)List必须按照插入的顺序保存元素
(2)Set不能有重复元素
(3)Queue保持一个队列(先进先出)的顺序
Map(图)
一组成对的“键值对”对象,可以使用键来查找值
我们采用随机数生成器,生成10个0到5之间的整数,将它们分别添加到List、Set、Map和Queue中,打印出结果,会发生什么呢?
public class ListAndSet {
public static void main(String[] args) {
List list = new ArrayList();
Set set = new HashSet();
Map map = new HashMap();
Queue queue = new LinkedList();
Random random = new Random();
//随机生成0到5的整数,循环10次
for (int i=0; i<10; i++) {
int num = random.nextInt(5);
System.out.print(num);
list.add(num);
set.add(num);
map.put(i, num);
queue.offer(num);
}
System.out.println();
System.out.println(list);
System.out.println(set);
System.out.println(map);
System.out.println(queue);
}
}
首先,可以看到,List和Set采用add()方法来添加一个元素,Map采用put(key,value)的方式存放一组键值对,Queue采用offer()方法添加元素。
打印出的结果
0211212040
[0, 2, 1, 1, 2, 1, 2, 0, 4, 0]
[0, 1, 2, 4]
{0=0, 1=2, 2=1, 3=1, 4=2, 5=1, 6=2, 7=0, 8=4, 9=0}
[0, 2, 1, 1, 2, 1, 2, 0, 4, 0]
可以看到,List按照插入的顺序来添加元素,Set中没有重复的元素,Map存储了一组键值对,Queue将元素插入到队尾。
**注意:**细心的朋友可以发现, 我们使用List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList(),创建其它集合类时也是如此,这是为什么呢?
因为List有多个实现类,如 LinkedList、 ArrayList等,现在用的是ArrayList,也许哪一天你需要换成其它的实现类呢?这时你只要改变这一行就行了:List list = new LinkedList();它使用了list地方的代码根本不需要改动。
一般,我们在创建具体类的对象时,都将其向上转型为对应的接口,然后在其余的代码中都使用这个接口,这是为了方便以后扩展。但这种方式并非总能奏效,因为某些类具有额外的功能,如果你需要用到这些方法,就不能将它们向上转型为更通用的接口。