java中的集合List,Set,Map

Collection

集合包含Collectionmap接口,Collection又由两个子接口List和Set构成,每个子接口又有自己不同的实现类。
在这里插入图片描述

List接口(有序,值可重复)

List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引来访问List中的元素,类似数组。List允许有相同的元素。

实现List接口的常用类有LinkedList,ArrayList,Vector。

ArrayList类:是最常用的List实现类,它实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。

ArrayList(可以理解成动态数组)

  • add:添加单个元素

  • remove:删除指定元素

  • contains:查找元素是否存在

  • size:获取元素个数

  • isEmpty:判断是否为空

  • clear:清空

  • addAll:添加多个元素

  • containsAll:查找多个元素是否都存在

  • removeAll:删除多个元素

LinkedList类: LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
LinkedList的底层操作机制
(1)LinkedList底层维护了一个双向链表
(2)LinkedList中维护了两个属性first和last分别指向首节点和尾节点
(3)每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表。
(4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。
(5)一个简单的双向链表:
在这里插入图片描述
ArrayList和LinkedList的比较:
ArrayList:
底层结构:可变数组;
增删的效率:较低;
改查的效率:较高;
LinkedList:
底层结构:双向链表;
增删的效率:较高、通过链表追加;
改查的效率:较高;

如何选择ArrayList和LinkedList:

  1. 如果我们改查的操作多,选择ArrayList
  2. 如果我们增删的操作多,选择LinkedList
  3. 一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList
  4. 在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList。

Vector类:
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的 Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。

遍历方式

迭代器 Iterator:

  • 迭代器主要用于遍历Collection集合中的元素
  • 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器
  • 仅用于遍历集合,Iterator本身并不存放对象。

增强for循环
可以替代iterator迭代器,特点:增强for就是简化版的iterator本质一样。只能用于遍历集合或数组。

for(元素类型 元素名:集合名或数组名){
    
    
	访问元素
}

Set接口(值不可重复)

Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。 很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。
注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。

  1. 无序(添加和取出的顺序不一致,没有索引)
  2. 不允许重复元素,所以最多包含一个null

set接口的遍历方式

同Collection的便利方式一样,因为Set接口是Collection接口的子接口

  1. 可以使用迭代器
  2. 增强for
  3. 不能使用索引的方式来获取

hashset

  1. hashset实现了set接口
  2. hashset实际上是hashmap
  3. 可以存放null值,但是只能有一个
  4. hashset不保证元素是有序的,取决于hash后,再确定索引的结果
  5. 不能有重复元素/对象,在前面set接口使用已经讲过

hashset底层是hashmap, hashmap底层是(数组+链表+红黑树)

LinkedHashSet

底层数据结构是双向链表和哈希表,有序。
由链表保证元素有序,由哈希表保证元素唯一。

TreeSet

底层数据结构是红黑树,内部实现排序,也可以自定义排序规则。
自然排序、比较器排序保证元素排序。根据比较的返回值是否是0来保证元素唯一性。

ArraySet

底层数据结构是双数组,有序。

Map接口

Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。

jdk8

  1. Map与Collection并列存在,用于保存具有映射关系的数据Key-Value
  2. Map中的Key和value可以是任何引用类型的数据,会封装到HashMap
  3. Map中的key不允许重复,原因和HashSet一样
  4. map中的value可以重复
  5. map中的key可以为null,value也可以为null,注意key为null,只能有一个,value为null可以有多个
  6. 常用String类作为Map的key
  7. key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value
    ![
    ](https://img-blog.csdnimg.cn/cb904bf906ea4debbb3626c9325e58b1.png)

常用方法:

  1. put
  2. remove
  3. get
  4. size
  5. isEmpty
  6. clear
  7. containsKey

Map遍历方法

  1. containsKey查找键是否存在
  2. keySet获取所有的键
  3. entrySet获取所有关系k-v
  4. values获取所有值

小结:

  1. Map接口的常用实现类:HashMap,Hashtable,Properties
  2. HashMap是Map接口使用频率最高的实现类
  3. HashMap是以key-val对的方式来存储数据
  4. key不能重复,但是是值可以重复,允许使用null键和null值
  5. 如果添加相同的key,则会覆盖原来的key-val,等同于修改,(key不会替换,val会替换)
  6. 与HashSet不一样,不保证映射的顺序,因为底层是以hash表的方式来存储的。
  7. HashMap没有实现同步,因此是线程不安全的。
Hashtable类

Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。Hashtable是同步的。

HashMap类

HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap 的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。

  1. 存放的元素是键值对:即k-v

  2. hashtable的键和值都不能为null,否则抛出NullPointerException

  3. hashtable使用方法基本上和hashmap一样

  4. hashtable是线程安全的,hashmap是线程不安全的

扩容机制:

properties

  1. Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保存数据。
  2. 他的使用特点和Hashtable类似
  3. Properties还可以用于从xxx.properties文件中,加载数据到properties类对象,并进行读取和修改
  4. 说明:工作后 xxx.properties文件通常作为配置文件,这个知识点在IO流举例。

集合选型规则

  1. 先判断存储的类型(一组对象[单列]或一组键值对[双列])
  2. 一组对象[单列]:Collection接口

允许重复: List

增删多: LinkedList [底层维护了一个双向链表]

改查多: ArrayList [底层维护Object类型的可变数组]

不允许重复: Set

无序: HashSet [底层是HashMap,维护了一个哈希表 即(数组+链表+红黑树)]

排序: TreeSet

插入和取出顺序一致: LinkedHashSet,维护数组+双向链表

  1. 一组键值对:Map

键无序:HashMap [底层是:哈希表 jdk7:数组+链表, jdk8:数组+链表+红黑树]

​键排序:TreeMap

键插入和取出顺序一致:LinkedHashMap

​读取文件:Properties

猜你喜欢

转载自blog.csdn.net/weixin_44516623/article/details/128066675