JAVA数据结构-集合篇

来源:互联网 发布:最优路线算法 编辑:程序博客网 时间:2024/05/06 01:50

从事android工作这么多年,越来越发现java基本知识的重要性,数据结构是编程的核心,所以我打算重新回顾总结一下基础。

相信很多刚入门的android开发同学甚至工作几年的程序员可能一直一来都在用ArrayList和HashMap这两种集合类,只是用时爽快,但是有没有同学去思考过为什么我们一直在用这两种集合类,他们底层是如何实现的,以及其他的集合类又有什么优缺点呢?我们开始揭开java集合-Collection不神秘的面纱~

首先上一张集合类的继承关系图:

这里写图片描述

从这张图上我们可以很清晰的看到整个集合的组成结构,我们可以分为两块来学习,第一块是collection接口:

该接口提供了一些最基本的操作方法,比如说add、addAll、remove、
isEmpty、size、clear、contains、equals、containsAll、hashCode、
iterator,这些方法在其所有的子类中都会有不同的实现。

由于大部分的集合接口实现类都是不同步的,可以使用Collections.synchronized*方法创建同步的集合类对象。
如创建一个同步的List:
List synList = Collections.synchronizedList(new ArrayList());

List:ArrayList、LinkedList

ArrayList:ArrayList内部实现了可变数组,允许保存所有元素,包括null,考虑效率arraylist是非同步的,所以线程不安全,因为内部是数组实现,所以可以快速的根据索引找到某元素进行随机访问,缺点是对指定索引位置插入或删除元素的速度较慢。至于为什么它添加删除时会比较慢呢,我们看源码。
这里写图片描述
这里我们可以清晰的看出,arraylist每添加一个元素,他都会先生成一个新数组对象,然后将索引之前、和之后的数组元素分别copy到新数组中,然后再单独将a[index]赋值。

这里写图片描述
删除的时候,会将index之后的元素copy到本数组中index的位置上来(将index+1 - array.length 替换 index - array.length-1),然后将最后一位元素置空。

linkedList:采用链表结构保存对象,双向链表大家可以百度一下,简单的说它的每个节点上都会分别记住上一个元素和下一个元素的指针位置,因此这种结构对于向集合中插入、删除元素会更加快捷,但对于遍历集合元素的效率变低。
这里写图片描述

比如说删除某位置上的一个元素,只需找到location位置上的这个link(Link类会记录当前数据、前一个link、后一个link),然后改变前一个link的后指向,和后一个link的前指向就可以了,而不需要改变所有的元素。

Vector集合:是一个线程安全的集合,它与list最大的区别就是vetor是同步操作,而list不是,所以如果不考虑多线程带来的影响时可以使用list。
vector在add数据时,紧紧只是多了一个同步锁:

这里写图片描述

Set接口:HashSet、TreeSet。set集合中传入的对象不允许有重复元素!

HashSet : 由哈希表(实际上是一个HashMao实例)支持。不保证集合的迭代顺序,允许null元素。
创建时生成一个HashMap,键为数据,值为this。
这里写图片描述
这里写图片描述
这里有一个小技巧,如果你业务需求希望判断当前数据是否在集合中存在时,可以用HashSet,为什么呢,我们看一下源码:
这里写图片描述
这个key其实就是你要找的数据,在寻找时,它会先拿到数据的哈希值,然后只需要判断这个哈希值是否和HashMap中key的哈希值一致就可以确认是否有这个数据了,判断哈希值的速度会犹豫判断对象本身是否相等。

TreeSet: treeset内部维护一个TreeMap,实现了SortedSet接口,因此TreeSet类实现的Set集合在遍历集合时按照自然顺序递增排序,也可以指定比较器来递增排序

这里写图片描述
这里写图片描述
这里没什么好说的,在待会我们学习了treemap之后自然也就明白内部原理了。

由此可根据实际情况来选择使用ArrayList(非同步、非频繁删除时选择)、Vector(需同步时选择)、LinkedList(频繁在任意位置插入、删除时选择)。

Map集合: HashMap、TreeMap。
Map集合没有继承Collection接口,其提供的是key到value的映射。map中不能有相同的key,每个key只能映射一个value,value可以有重复。

HashMap: 是就哈希表实现的,允许使用null键和null值,但是要保证键的唯一性,HashMap通过哈希表对其内部的映射关系进行快速查找,不保证顺序。

map集合实际上是有一个Entry数组组成的,Entry接口中提供了存储键、值、哈希值的方法。
这里写图片描述
这里写图片描述

添加元素时,先拿key的哈希值在entry数组中找有没有哈希值相等的键,如果有则取出原来的这个entry对象,并将value重新富值,如果没有则new一个Entry对象。
这里写图片描述
这里写图片描述

TreeMap : TreeMap是由Entry对象为节点组成的一颗红黑树,put到TreeMap的数据默认按key的自然顺序排序,new TreeMap时传入Comparator自定义排序。红黑树网上很多资料,我讲不清,这里就不介绍了。

0 0
原创粉丝点击