JCF之Collection

JCF之Collection

【摘要】JCF,Java Collection Framework, JAVA集合框架~

前言

hi,思考一下:
共计有1亿个整数,范围是【1~10000001】,每个数只出现1次,
所以其中有一个数没有,请找出这个数。

Collection

JCF,Java Collection Framework, JAVA集合框架。
它解决了数据在存储中数据结构的问题,使用它,程序只关心自己的业务,不需要关心底层的数据结构。

容器类[Container],就是可以存放其它对象的对象,比如:数组就是容器。

比如:数组就有一个问题,就是它的长度是不可变的,所以,用数组来存放数据时,你得事先知道大小,但问题是,我们逻辑不允许我们事先知道,因为它是动态的。
所以,我们使用数组做为数据的结构时,都得程序员自己想办法“扩容”。

而JCF就是解决此问题而来的,有了它,我们再也不用自己去“扩容”了,而且JCF中提供了多种不同的数据结构来供我们选择。

首先,JCF的包:java.util,它采用接口+实现类的方式提供服务。先看接口:

1
2
3
4
5
6
7
8
9
10
11
java.util.Collection
\- List 【有序、可以重复】
\- ArrayList 以数组为数据结构的集合
\- Vector 同ArrayList
\- LinkedList 以链表为数据结构的集合

\- Set 【无序、不可以重复】
\- SortedSet 【排好序的、不可以重复的】
\- TreeSet[类] 以二叉树为数据结构的集合

\- HashSet[类] 以哈希表为数据结构的集合

Collection以对象为存储单元,我们通过字母E 代表对象的类型。
如:

1
2
3
4
5
6
7
8
Book b1 = new Book();
Book b2 = new Book();
Book b3 = new Book();
//创建集合对象
List collectionObj = new ArrayList();
collectionObj.add(b1);
collectionObj.add(b2);
collectionObj.add(b3);
  1. 如何选择集合?

    A. 从业务功能上去选。
    B. 从有序还是无序上去选。
    C. 从性能上选【要根据业务】。

  2. ArrayList和Vector的区别是什么?

    相同点:它们的操作都是一样的,底层的数据结构和算法也是一样的。
    唯一的不同点在于 Vector的所有方法都是同步的,也就是多线程安全的。而ArrayList则不是,所以,它是轻量级的。

注:StringBuilder和StringBuffer的区别同上。[StringBuffer是多线程安全的,同步的方法]。

  1. 在 List和Set 中,如何选择?
    从它们本身的特点中可以选择

    List => 有序、可重复
    Set => 无序、不可重复

  2. 在 List的实现类:ArrayList和LinkedList如何选择?
    从底层的数据结构的特点进行选择

    如果业务操作中,增删较多,选 LinkedList。
    如果业务操作中,查询较多,选 ArrayList。

  3. 在 Set的实现类:HashSet和TreeSet如何选择?
    从它们本身的特点中可以选择

    HashSet是无序的。
    TreeSet是排好序的。

Collection的迭代

方式一:使用 foreach循环,因为Collection接口继承于 java.lang.Iterable 接口。 [JDK5.0]
如:

1
2
3
4
5
6
7
8
List aList = new LinkedList();
aList.add("...");
aList.add("...");
aList.add("...");
//
for(Object e : aList) {
//...
}

方式二:使用迭代器[iterator]进行迭代
… 来自于上面的代码

1
2
3
4
5
//
Iterator iter = aList.iterator();
while(iter.hasNext()) {
Object e = iter.next(); //访问下个元素
}

注:
使用迭代器迭代集合时,元素是不能执行更新的。否则,会出现一个并发修改的异常。【ConcurrentModificationException】

Collections工具类

1
2
3
4
5
6
7
8
Collection集合的工具类
java.util.Collections
方法:
addAll
copy
sort 排序
shuffle 打乱顺序[洗牌]
...

集合和集合元素在内存中是如何存储的?
注:
针对集合的操作大多都是仅仅操作集合本身,而不是通过集合去操作元素。
如果是通过集合去操作了元素,那会影响到多个使用这些元素的集合。
如:

1
2
3
4
5
6
7
8
9
10
Book b1 = new Book();
Book b2 = new Book();
Book b3 = new Book();
//
List<Book> a = new ArrayList<>();
Collections.addAll(a, b1, b2, b3);
//
List<Book> b = new ArrayList<>(a);
//这样一来,集合b和集合a 的确是两个集合对象,
//但是,它们的元素是共用的。

所以,如果你操作的是集合本身,它们互不相干。但是,一旦某个集合操作了元素本身,则会影响另一个。

集合元素的排序

  1. 默认规则 [自然规则]
1
Collections.sort(List a);

此方法中所讲的“默认规则”,就是这个集合中的元素都实现了一个叫 java.lang.Comparable的接口。
事实是,8种基本类型的包装类和String,Date都实现了这个接口,换句话说,这些对象都是可比较的。
所以:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
List<Integer> a = new ArrayList<>();
Collections.addAll(a, 1,5,89,45,12,6,2,3);
//
Collections.sort(a); //直接可以排序。
//排序后:{1,2,3,5,6,12,45,89}
//但是,
List<Book> b = new ArrayList<>();
Book b1 = new Book();
Book b2 = new Book();
Book b3 = new Book();
//
Collections.addAll(b, b1, b2, b3);
//
Collections.sort(b); //运行时报错。
  1. 指定比较规则
1
Collections.sort(List a, Comparator c);

这个方法针对集合List中的元素没有实现Comparable接口的要求,那它是如何进行比较的呢?
答案就是利用 Comparator 比较器接口。

注:使用Comparator接口相比Comparable接口有什么优势?
Comparator比较灵活,可以使用多种不同的比较规则。
而且对元素的类型没有要求。

集合本身是对象,所以,集合中也可以存集合。

作业: 改写BookServiceImpl, 使用集合来实现。

结束语

bye~

评论