本篇博客只是对于自己学习java提供的collection和map两种容器的总结,从每种容器的优缺点和底层实现的角度,做了简单的总结,所以要求阅读者对于java容器这一块有基本的认识。
数据结构:
是以某种形式将数据组织在一起的集合,数据结构不仅存储数据,还支持那些访问和处理数据的操作。在面向对象的思想里,一种数据结构被认为是一种容器,是个能存储其他对象的对象,所以一种数据结构本质上是一个类,使用数据域存储数据,同时提供方法支持查找,插入,删除等动作。
java提供了两种容器:
一种是为了存储一个元素的集合,成为集合(Collection)
一种是为了存储键/值对,称为图(map)。
Set:用于存储互不相同的元素。
List:用于存储有序元素的集合。
Map:存储键值对。
对于接口的具体实现:
上面这张图是对于每种接口的具体的实现类。
java原生数据类型:
基本数据类型是四类八种
第一类:整型 byte short int long
第二类:浮点型 float double
第三类:逻辑型 boolean(它只有两个值可取true false)
第四类:字符型 char
这八种java原生数据类型不是对象,其余的都是对象比如Integer就是对象。
为什么这里插入java原生的数据类型那:
集合中放置的都是对象,是不能够放置原生的数据类型的。我们在使用的时候需要使用原生数据类型的包装类才能加入到集合中。因为集合中放置的都是object类型,因此取出来的时候也是object类型,那么必须使用强制类型转换将其转换为真正的类型(就是我们放进去时候的类型)。
set
HashSet:
中的元素是没有被排序的。
底层实现:底层是采用hashmap来实现的,当使用add方法将对象添加到set中的时候,实际上是将对象作为底层所维护的map对象中的key,而value则是同一个object对象,这个对象我们是用不上的。
LinkedHashSet:
是链表是先的扩展HashSet类,支持对元素的排序。保持元素插入的时候的顺序。
TreeSet:
是set的子接口,是实现了SortedSet接口的具体类,确保规则集中的元素是有序的,允许自定义排序。
排序使用的方法:
①使用Compareable接口,由于添加到set中的对象都是compareable的实例,所以可以使用compareto的方法对他们进行排序,这是一中默认的方式的排序。
②在被插入的对象没有实现java.lang.Comparable类的时候,我们可以定义一本比较器来比较这些元素,就是java.util.Comparator接口中的compare和equals的方法。让我们新放入的对象来实现这个接口。
实现set接口的几种类型的比较:
如果我们不需要保持元素的排序关系,我们使用hashset,应为hashset中插入和删除元素花费的时间比较少,如果需要一个排好序的集合的时候,可以从这个集合中创建一个树形集。
list
List:允许存储重复的元素,并且允许指定存储的位置,用户可以使用下标来访问元素。
扩展了collection的接口,并且双向遍历线性表增加了一个列表迭代器java.util.Iterator.
Arraylist:
可变大小的数组。
底层采用的数组来实现的,当采用不带参数的构造方法生成arraylist对象时,实际上会在底层生成一个长度为10的object类型的数组。如果元素超过了数组的容量,就会创建一个更大的新数组,并将当前的数组复制到新的数组中。
对于删除或者插入操作,如果不是在末尾进行,需要将删除或者插入元素的后续元素向前或者向后移动代价是比较大的。(知识有底层的实现方式决定的。)
linkedlist:
采用的是链表来实现的底层,在链表中存储元素。
所谓的链表底层实现,是通过我们存储的对象经过我们entry类型包装形成的。也就是linkedlist是由多个entry包装好的对象组成的。
实现list接口的两种类型的比较:
操作插入和删除的时候linkedlist只需要操作指针,而arraylist需要移动数据(除了在末尾插入或者删除元素外,这候arraylist比linkedlist效率高)。
在访问元素的时候Arraylist是连续存放的只要找到了第一个,加上50就找到了第五十一个。,而linkelist是需要一个个的往后找。
set和list的比较:
set是比list更加高效的,如果应用程序用set就足够,那么就使用set,在这个基础还是那个如果程序不需要特别顺序吗,就选择hashset。
Map
集合看完了,我们下载来看看我们的图:就是map:中的键值不能够重复的。
hashMap:
条目没有顺序的,放进去和取出来不一定是同样的顺序。定位一个映射,插入一个映射,删除一个映射,最高效。
map的keyset()方法会返回key的集合,因为map的键值不能够重复的,所以keySet()的方法返回的类型是set。而map的value值是可以重复的,因此vlaues()方法的返回类型是Collection,可以容纳重复的元
素。
底层实现:HashMap底层就是一个数组结构,每个数组元素的类型都是链表,链表中每个entry又是有链表这种结构不断往下链。每个entry里面是有key和value。
。当新建一个HashMap的时候,就会初始化一个数组。当向里面put一堆键值的时候,他会根据key的hashcode值计算出一个位置(数组上面的位置),这个位置就是此对象要放置的位置,如果这个数组位置上面有对象了,那么对象放入到链表的头部,最先加入的放在链尾。下面这张图是我们hashmap的最终结构图
LinkedHashMap:
使用链表实现来扩展hashMap,支持条目的排序(按照插入顺序或者访问顺序来排序)。
TreeMap:
在遍历排好顺序的键值时候是很高效的。
像treeset一样可以使用Comparable或者Comparator接口来排序,实现了sortedMap接口。
注意
①关于hashmap的底层可以网上详细了解一下,这里推荐:
http://www.cnblogs.com/xwdreamer/archive/2012/06/03/2532832.html
②在java语言中归根到底是由数组来维护或者是链表,或者两者混合结构,才能够维护一群对象。
③链表中的元素是entry。Entry的具体结构:
④对于接口collection和map的实现类的数据结构的特性是由底层的数据结构实现决定的。
本篇文章只是一个总结。