浅谈java集合框架

举报
运气男孩 发表于 2021/12/14 23:59:37 2021/12/14
【摘要】 集合的由来 为了满足这些常规的编程需要,我们要求能在任何时候,任何地点创建任意数量的对象。集合是什么 Java集合类存放于java.util包中,是一个用来存放对象的容器 注意: 集合只能存放对象集合存放的是多个对象的引用,对象本身还是放在堆内存中集合可以存放不同类型,不限数量的数据类型集合框架简化图集合框架简化图说明: 所有集合类都位于java.util包下。Java的集合类主要由两个接口...

集合的由来 

为了满足这些常规的编程需要,我们要求能在任何时候,任何地点创建任意数量的对象。

集合是什么 

Java集合类存放于java.util包中,是一个用来存放对象的容器 

注意: 

  • 集合只能存放对象
  • 集合存放的是多个对象的引用,对象本身还是放在堆内存中
  • 集合可以存放不同类型,不限数量的数据类型

集合框架简化图

集合框架简化图说明: 

所有集合类都位于java.util包下。Java的集合类主要由两个接口派生而出:CollectionMap,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类 

Collection接口是一组允许重复的对象

Set接口继承Collection,集合元素不重复
List接口继承Collection,允许重复,维护元素插入顺序

Map接口是键―值对象,

Set、List和Map可以看做集合的三大类 

List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问 

Set集合是无序集合,集合中的元素不可以重复,访问集合中的元素只能根据元素本身来访问 

Map集合中保存Key-value对形式的元素,访问时只能根据每项元素的key来访问其value 


List接口 

         List集合代表一个有序集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素 

         List接口继承于Collection接口,它可以定义一个允许重复的有序集合。因为List中的元素是有序的,所以我们可以通过使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack 

ArrayList 

          ArrayList是一个动态数组,也是我们最常用的集合。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10)。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率 。

ArrayList擅长于随机访问。同时ArrayList是非同步的 

LinkedList 

        同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表。 

        由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作 

        与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List 

         List list = Collections.synchronizedList(new LinkedList(...)); 

异同点 

ArrayList和LinkedList

ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构 对于随机访问get和set,ArrayList绝对优于LinkedList,因为LinkedList要移动指针 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据,这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据 

Vector 

         与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样 

Stack 

         Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈 。

Set接口 

         Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样允许null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同。Set接口有三个具体实现类,分别是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet 

         Set是一种不包含重复的元素的Collection,无序,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。需要注意的是:虽然Set中元素没有顺序,但是元素在set中的位置是由该元素的HashCode决定的,其具体位置其实是固定的 

HashSet 

         HashSet 是一个没有重复元素的集合。它是由HashMap实现的,不保证元素的顺序(这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致),而且HashSet允许使用null 元素。HashSet是非同步的,如果多个线程同时访问一个haseSet,而其中至少一个线程修改了该set,那么它必须保持外部同步。 HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能 

HashSet使用和理解中容易出现的误区 :

HashSet中存放null值 :HashSet中是允许存入null值的,但是在HashSet中仅仅能够存入一个null值 

HashSet中存储元素的位置是固定的 

HashSet中存储的元素的是无序的,这个没什么好说的,但是由于HashSet底层是基于Hash算法实现的,使用了hashcode,所以HashSet中相应的元素的位置是固定的 

LinkedHashSet 

         LinkedHashSet继承自HashSet,其底层是基于LinkedHashMap来实现的,有序,非同步。LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素 。

TreeSet 

       TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。 注意:TreeSet集合不是通过hashcode和equals函数来比较元素的。它是通过compare或者comparaeTo函数来判断元素是否相等。compare函数通过判断两个对象的id,相同的id判断为重复元素,不会被加入到集合中。 

HashSet、LinkedHashSet、TreeSet比较 

Set接口 Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。 Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不会接受这两个对象 。

HashSet有以下特点:

->  不能保证元素的排列顺序,顺序有可能发生变化。

->  不是同步的。

->  集合元素可以是null,但只能放入一个null 

LinkedHashSet          LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。

         LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet 

TreeSet类        

 TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。          

TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0 

Map接口 

         Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同 

HashMap 

         以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构 

LinkedHashMap 

         LinkedHashMap是HashMap的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用LinkedHashMap 

        LinkedHashMap是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变 

TreeMap 

          TreeMap 是一个有序的key-value集合非同步,基于红黑树(Red-Black tree)实现,TreeMap存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是自然排序,一种是定制排序,具体取决于使用的构造方法 

自然排序:TreeMap中所有的key必须实现Comparable接口,并且所有的key都应该是同一个类的对象,否则会报ClassCastException异常 

定制排序:定义TreeMap时,创建一个comparator对象,该对象对所有的treeMap中所有的key值进行排序,采用定制排序的时候不需要TreeMap中所有的key必须实现Comparable接口 

         TreeMap判断两个元素相等的标准:两个key通过compareTo()方法返回0,则认为这两个key相等 

         如果使用自定义的类来作为TreeMap中的key值,且想让TreeMap能够良好的工作,则必须重写自定义类中的equals()方法,TreeMap中判断相等的标准是:两个key通过equals()方法返回为true,并且通过compareTo()方法比较应该返回为0 

HashTable与HashMap 

相同点

都实现了Map、Cloneable、java.io.Serializable接口

都是存储"键值对(key-value)"的散列表 

不同点

历史原因:HashTable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现

同步性:HashTable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的

对null值的处理:HashMap的key、value都可为null,HashTable的key、value都不可为null  

基类不同:HashMap继承于AbstractMap,而Hashtable继承于Dictionary 支持的遍历种类不同:HashMap只支持Iterator(迭代器)遍历。而Hashtable支持Iterator(迭代器)和Enumeration(枚举器)两种方式遍历 

集合工具类Collections 

Collections类是用于操作List、Set和Map等集合的工具类,该类提供了大量的方法对集合元素进行排序、查询和修改等操作 

1、向集合添加元素并执行反序操作 

2、对集合中的元素进行查找和替换 

3、对集合中的元素进行随机排列和对集合中的元素进行排序 

自然排序

    自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列。   Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等,如果返回一个正数,则表明obj1大于obj2,如果是负数,则表明obj1小于obj2。 

定制排序        

自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法 

Collection 和 Collections区别 

java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set 

java.util.Collections 是一个包装类(工具类/帮助类)。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,用于对集合中元素进行排序、搜索以及线程安全等各种操作,服务于Java的Collection框架 

关于java的集合框架就说到这里了,如有不足之处,欢迎指正!

感恩能与大家在华为云遇见!希望能与大家一起在华为云社区共同成长。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。