Java集合框架

容器

容器是一个Java 所编写的程序,原先必须自行编写程序以管理对象关系,容器都会自动帮您做好。
常用容器:WebSphere,WebLogic,Resin,Tomcat,Glassfish。
不一定的对的概况,java中的容器也就是java世界里面承装对象的器皿。

Java的集合框架在Java.util下。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


java集合框架

集合框架——提供一种可以保存多种类型元素,并且长度不受限制的容器,来更加方便的保存对象。盛装对象,操作对象。

Java 集合框架主要包括两种类型的容器。

一种是集合(Collection),存储一个元素集合,Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。
另一种是图(Map),存储键/值对映射。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

集合框架里的三大块内容。

集合框架是一个用来代表和操纵集合的统一架构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。

  • 接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map
    等。之所以定义多个接口,是为了以不同的方式操作集合对象
  • 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。
  • 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。
    在这里插入图片描述

Collection 和 Collections 是两个不同的概念。之所以放在一起,是为了更好的比较。Collection是容器层次结构中根接口。而Collections是一个提供一些处理容器类静态方法的类。

java集合框架的设计理念

集合框架被设计成要满足以下几个目标。

  • 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
  • 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
  • 对一个集合的扩展和适应必须是简单的。
java的集合和数组

集合可以看作是一种容器,用来存储对象信息。所有集合类都位于java.util包下,但支持多线程的集合类位于java.util.concurrent包下。
  数组与集合的区别如下:

  1. 数组长度不可变化而且无法保存具有映射关系的数据;集合类用于保存数量不确定的数据,以及保存具有映射关系的数据。
  2. 数组元素既可以是基本类型的值,也可以是对象;集合只能保存对象。


系列文章

Java集合类主要由两个根接口Collection和Map派生出来的,Collection派生出了三个子接口:List、Set、Queue(Java5新增的队列),因此Java集合大致也可分成List、Set、Queue、Map四种接口体系,(注意:Map不是Collection的子接口)。
其中List代表了有序可重复集合,可直接根据元素的索引来访问;Set代表无序不可重复集合,只能根据元素本身来访问;Queue是队列集合;Map代表的是存储key-value对的集合,可根据元素的key来访问value。

JDK11api

https://tool.oschina.net/apidocs/apidoc?api=jdk-zh

Collection接口

Collection接口常用方法
在这里插入图片描述

常用的List

Java的ArrayList
Java的LinkedList
Java的Vector
Java的Stack

ArrayList其实就相当于顺式存储,它包装了一个动态数组 Object[],当实例化一个ArrayList时,一个数组也被实例化,当向ArrayList中添加对象时,数组的大小也相应的改变。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。这样就带来以下有特点:
快速随即访问,你可以随即访问每个元素而不用考虑性能问题,通过调用get(i)方法来访问下标为i的数组元素。
向其中添加对象速度慢,当你创建数组时并不能确定其容量,所以当改变这个数组时就必须在内存中做很多事情。
操作其中对象的速度慢,当你要向数组中任意两个元素中间添加对象时,数组需要移动所有后面的对象。

LinkedList相当于链式存储,它是通过节点直接彼此连接来实现的。每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可,当删除记录时也一样。这样就带来以下有特点:
操作其中对象的速度快,只需要改变连接,新的节点可以在内存中的任何地方。
不能随即访问,虽然存在get()方法,但是这个方法是通过遍历接点来定位的,所以速度慢。
LinkedList既可以当作“栈”使用,又可以当作队列使用。

以下情况使用 ArrayList :

  • 频繁访问列表中的某一个元素。
  • 只需要在列表末尾进行添加和删除元素操作。
    以下情况使用 LinkedList :
  • 你需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

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

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

常用的Set

Java的HashSet
Java的TreeSet
Java的LinkedHashSet
Java的EnumSet

Set不允许存储相同的元素,所以如果把两个相同元素添加到同一个Set集合,则添加操作失败

HashSet是Set集合最常用实现类,是其经典实现。HashSet是按照hash算法来存储元素的,因此具有很好的存取和查找性能。
HashSet具有如下特点:
  ♦ 不能保证元素的顺序。
  ♦ HashSet不是线程同步的,如果多线程操作HashSet集合,则应通过代码来保证其同步。
  ♦ 集合元素值可以是null。

TreeSet类
  TreeSet时SortedSet接口的实现类,TreeSet可以保证元素处于排序状态,它采用红黑树的数据结构来存储集合元素。TreeSet支持两种排序方法:自然排序和定制排序,默认采用自然排序。
  ♦ 自然排序   TreeSet会调用集合元素的compareTo(Object
obj)方法来比较元素的大小关系,然后将元素按照升序排列,这就是自然排序。如果试图将一个对象添加到TreeSet集合中,则该对象必须实现Comparable接口,否则会抛出异常。当一个对象调用方法与另一个对象比较时,例如obj1.compareTo(obj2),如果该方法返回0,则两个对象相等;如果返回一个正数,则obj1大于obj2;如果返回一个负数,则obj1小于obj2。
Java常用类中已经实现了Comparable接口的类有以下几个:   
♦BigDecimal、BigDecimal以及所有数值型对应的包装类:按照它们对应的数值大小进行比较。
♦Charchter:按照字符的unicode值进行比较。   
♦ Boolean:true对应的包装类实例大于false对应的包装类实例。
♦ String:按照字符串中的字符的unicode值进行比较。   
♦ Date、Time:后面的时间、日期比前面的时间、日期大。

对于TreeSet集合而言,它判断两个对象是否相等的标准是:两个对象通过compareTo(Object obj)方法比较是否返回0,如果返回0则相等。   
♦ 定制排序
  想要实现定制排序,需要在创建TreeSet集合对象时,提供一个Comparator对象与该TreeSet集合关联,由Comparator对象负责集合元素的排序逻辑。
  综上:自然排序实现的是Comparable接口,定制排序实现的是Comparator接口。

EnumSet是一个专为枚举类设计的集合类,不允许添加null值。EnumSet的集合元素也是有序的,它以枚举值在Enum类内的定义顺序来决定集合元素的顺序。


Map

Map没有继承Collection接口,Map接口是提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。即是一一映射,Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。Map常用方法:
在这里插入图片描述

Java的HashMap
Java的LinkedHashMap实现类
Java的Properties
Java的TreeMap

HaspMap 添加数据使用put(key, value),取出数据使用get(key), HashMap是允许null,即null value和null key。但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。
当我们将键值对传递给put()方法时,它调用建对象的hashCode()方法来计算hashCode值,然后找到bucket位置来储存值对象。当获取对象时,通过建对象的equals()方法找到正确的键值对,然后返回对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会存储在链表的下一个节点中。

HashMap与Hashtable是Map接口的两个典型实现,它们之间的关系完全类似于ArrayList与Vertor。HashTable是一个古老的Map实现类,它提供的方法比较繁琐,目前基本不用了,HashMap与Hashtable主要存在以下两个典型区别: 
 ♦ HashMap是线程不安全,HashTable是线程安全的。   ♦
HashMap可以使用null值最为key或value;Hashtable不允许使用null值作为key和value,如果把null放进HashTable中,将会发生空指针异常。
  为了成功的在HashMap和Hashtable中存储和获取对象,用作key的对象必须实现hashCode()方法和equals()方法。

LinkedHashMap实现类
LinkedHashMap使用双向链表来维护key-value对的次序(其实只需要考虑key的次序即可),该链表负责维护Map的迭代顺序,与插入顺序一致,因此性能比HashMap低,但在迭代访问Map里的全部元素时有较好的性能。

Properties
Properties类时Hashtable类的子类,它相当于一个key、value都是String类型的Map,主要用于读取配置文件。

TreeMap实现类
TreeMap是SortedMap的实现类,是一个红黑树的数据结构,每个key-value对作为红黑树的一个节点。TreeMap存储key-value对时,需要根据key对节点进行排序。TreeMap也有两种排序方式:

♦ 自然排序:TreeMap的所有key必须实现Comparable接口,而且所有的key应该是同一个类的对象,否则会抛出ClassCastException。
♦ 定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。

迭代遍历Interator

Java的Interator

Iterator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。Iterator提供的API接口如下:

♦ boolean hasNext():判断集合里是否存在下一个元素。如果有,hasNext()方法返回 true。
♦ Object next():返回集合里下一个元素。
♦ void remove():删除集合里上一次next方法返回的元素。
ListIterator接口继承Iterator接口,提供了专门操作List的方法。ListIterator接口在Iterator接口的基础上增加了以下几个方法:
♦ boolean hasPrevious():判断集合里是否存在上一个元素。如果有,该方法返回 true。
♦ Object previous():返回集合里上一个元素。
♦ void add(Object o):在指定位置插入一个元素。
ListIterator增加了向前迭代的功能(Iterator只能向后迭代),ListIterator还可以通过add()方法向List集合中添加元素(Iterator只能删除元素)。

排序——Comparator


附注:基本数据类型和引用数据类型
基本类型引用类型
booleanBoolean
StringString
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charChar
小结
  1. List的选择:
    比如:ArrayList和LinkedList都实现了List接口.因此无论选择哪一个,基本操作都一样.但ArrayList是由数组提供底层支持.而LinkedList是由双向链表实现的.所以,如果要经常向List里插入或删除数据,LinkedList会比较好.否则应该用速度更快的ArrayList。

  2. Set的选择
    HashSet总是比TreeSet 性能要好.而后者存在的理由就是它可以维持元素的排序状态.所以,如果需要一个排好序的Set时,才应该用TreeSet。

  3. Map选择:
    ♦ HashMap通常比Hashtable(古老的线程安全的集合)要快
    ♦ TreeMap通常比HashMap、Hashtable要慢,因为TreeMap底层采用红黑树来管理key-value。
    ♦ LinkedHashMap比HashMap慢一点,因为它需要维护链表来爆出key-value的插入顺序。 
    尽量选择HashMap。

在这里插入图片描述

参考文章

  1. https://blog.csdn.net/dandanzmc/article/details/23447827
  2. https://www.runoob.com/java/java-linkedlist.html
  3. https://zhuanlan.zhihu.com/p/104229853
  4. https://www.cnblogs.com/bingyimeiling/p/10255037.html
  5. https://www.jianshu.com/p/09e47ed2a2df
  6. https://baijiahao.baidu.com/s?id=1637859665467081225&wfr=spider&for=pc
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值