0
点赞
收藏
分享

微信扫一扫

Java常用集合解析

       java中最常用的两个顶层集合分别为Collection和Map,其中Collection接口又由List和Set两部分组成,这两种接口都是Collection的子接口List接口的集合主要特点是存储可重复,插入顺序有序。主要包含:ArrayList,LinkedList。Set接口的集合主要特点是存储不可重复,插入和取出顺序无序。主要包含:HashSet,TreeSet。Map接口下都是实现键值对关系的数据集合,专门处理键值映射数据的存储,可以根据键实现对值的操作。主要包含:HashMap,TreeMap。下文将一一介绍这些常用的集合。

       ArrayList是在实际的开发中使用频率最高的一个集合,它实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高,是List接口的实现,线程不安全ArrayList实现原理及特点: 数组实现, 查找快, 增删慢 数组为什么是查询快?因为数组的内存空间地址是连续的.ArrayList底层维护了一个Object[] 用于存储对象,默认数组的长度是10。可以通过 new ArrayList(20)显式的指定用于存储对象的数组的长度。底层实现了自动扩容,当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来的容量的1.5倍。由于ArrayList是数组实现, 在增和删的时候会牵扯到数组增容, 以及拷贝元素,所以慢。数组是可以直接按索引查找, 所以查找时较快 可以考虑,假设向数组的0下标未知添加元素,那么原来的下标位置的元素需要整体往后移,并且数组可能还要增容,一旦增容,就需要要将老数组的内容拷贝到新数组中,所以数组的增删的效率是很低的。

LinkedList采用链表存储方式。插入、删除元素时效率比较高,查找数据慢。LinkedList实现原理及特点:由于LinkedList:在内存中的地址不连续,需要让上一个元素记住下一个元素.所以每个元素中保存的有下一个元素的位置.虽然也有下标,但是查找的时候,需要从头往下找,显然是没有数组查找快的.但是,链表在插入新元素的时候,只需要让前一个元素记住新元素,让新元素记住下一个元素就可以了.所以插入很快。由于链表实现, 增加时只要让前一个元素记住自己就可以, 删除时让前一个元素记住后一个元素, 后一个元素记住前一个元素. 这样的增删效率较高。 但查询时需要一个一个的遍历, 所以效率较低。

HashSet采用哈希表实现(底层实际上是一个HashMap实例),它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变,不能对该集合元素进行排序,并且此类允许使用 null 元素。HashSet实现原理及特点:HashSet由哈希表实现,哈希表边存放的是哈希值。HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同) 而是按照哈希值来存的所以取数据也是按照哈希值取得(这里不必深究哈希算法明白是对数据进行一个编码的处理行为即可)。HashSet不存入重复元素的原因是使用hashcode和equals方法,对存入的数据进行编码比较,不同的编码才会存入集合。HashSet如何去除重复的原理如下图:

Java常用集合解析_Java集合

图1:hashCode值不相同的情况

图2:hashCode值相同,但equals不相同的情况。

HashSet:通过hashCode值来确定元素在内存中的位置。一个hashCode位置上可以存放多个元素。当hashcode() 值相同equals() 返回为true 时,hashset 集合认为这两个元素是相同的元素.只存储一个(重复元素无法放入)。调用原理:先判断hashcode 方法的值,如果相同才会去判断equals 如果不相同,是不会调用equals方法的。HashSet到底是如何判断两个元素重复。 通过hashCode方法和equals方法来保证元素的唯一性,add()返回的是boolean类型 判断两个元素是否相同,先要判断元素的hashCode值是否一致,只有在该值一致的情况下,才会判断equals方法,如果存储在HashSet中的两个对象hashCode方法的值相同equals方法返回的结果是true,那么HashSet认为这两个元素是相同元素,只存储一个(重复元素无法存入)。

TreeSet采用红-黑树的数据结构,默认对元素进行自然排序(String)。红黑树算法的规则: 左小右大。TreeSet集合相对于HashSet最大的特点就是能够进行排序,需要指定排序规则:1.元素自身具备比较性,需要元素实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做元素的自然排序也叫做默认排序。2.容器具备比较性,当元素自身不具备比较性,或者自身具备的比较性不是所需要的。那么此时可以让容器自身具备。需要定义一个类实现接口Comparator,重写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。

Map接口中最常用的实现类是HashMap,底层也是哈希表数据结构,线程是不同步的,可以存入null键,null值,所以不安全。其次TreeMap的实现原理和TreeSet基本一直,只不过Map是一一对应的关系。注意:如果在Map集合中添加的键值重复会覆盖原来的键值对,替换为新的键值对。

学会集合的选择和使用会帮助你在实际开发的过程中事半功倍,使用什么样的集合应该根据实际项目需求来进行选择,这样才能和项目相得益彰。

举报

相关推荐

0 条评论