Java集合框架库

1. 集合简介

1.1 集合概念

什么是集合:存储数据的容器。 数组、数据库也可以存储数据。

1.2 集合的作用

  1. 集合的作用:存储数据。
  2. 集合的使用场景:对元素数量没有明确判断,并且容易发生改变,存储好的数据有很多复杂的后续操作。

1.3 集合和其他容器的比较

  1. 数据库:mysql文件类型的数据库。数据可以长时间存储,从而可以使数据反复的使用。
  2. 数组 / 集合:暂存,单次使用。项目运行起来:创建数组或者集合,将数据存进去。一旦项目结束数组和集合都不存在,数据也随即不存在。
  3. 数组的缺点:(1)扩容操作可能在代码中要出现多次。(2)数组越界。
Integer[] arr = new Integer[10];
//异常:数组越界
//下标:index
int get(int index, Integer[] arr){
	if(index > 0 && index < arr.length)
		return arr[index];
}
  1. 集合:对普通数据结构的封装。

    数组:ArrayList、Vector对数组封装,会自动扩容,自动判断下标是否越界。
    链表:LinkedList
    堆:优先级队列
    
  2. 数组和集合相比:

    1.数组是静态的,集合是动态的。
    2.集合功能更全面(功能之一:下标是否越界)
    3.数组需要指定类型,存储的数据必须是该类型。
      集合创建时不需要(可有可无)。如果有,存储数据必须是该类型;如果没有,存储数据可以是任意的。
      注意:集合指定存储数据类型的方式用的较多,原因是更好管理
    4.数组在指定类型时,既可以使用普通类型,也可以使用引用类型。
      集合只能使用引用类型。
    5.数组是Java内置类型,数组效率更高。
    
    什么时候用集合,什么时候用数组?
    	数组:对元素数量有明确的判断,并且轻易不会发生改变,存储好的数据不会有太多复杂后续操作。
    	集合与之相反。
    

2. 集合框架库概述

集合框架主要结构图:
在这里插入图片描述
3大部分:Iterator、Collection、Map

(面试)集合框架中的顶级接口有哪些:Collection、Map

各个接口的特点:

  1. Iterator:迭代器遍历集合,从前向后遍历。

    ListIterator接口:是Iterator接口的子接口,可以进行双向输出,既可以从前向后遍历,也可以从后向前。 
    
  2. Collection接口:是存放一组单值的最大接口。
    所谓的单值是指集合中的每个元素都是一个对象。一般很少直接使用此接口直接操作。

    (1)List接口:是Collection接口的子接口,也是最常用的接口。此接口对Collection接口进行了大量的扩充,里面的内容是允许重复允许为NULL的并且有序(插入的顺序)。
    	ArrayList :【 22】 【 11】 【15】【null】【15】
    (2)Set接口:是Collection接口的子类,没有对Collection接口进行扩充,里面不允许存放重复内容!
    	SortedSet接口:单值的排序接口。实现此接口的集合类,里面的内容可以使用比较器排序。
    	TreeSet 【 11】 【 15】 【22】
    (3)Queue接口:是Collection接口的子接口,队列接口,具有队列先入先出的特点。此接口的子类可以实现队列操作。
    
  3. Map接口:是存放一对值的最大接口!即接口中的每个元素都是一对,以key --> value的形式保存,并且Key是不重复的,元素的存储位置由key决定。也就是可以通过key去寻找key-value的位置,从而得到value的值。适合做查找工作。

    (1)SortedMap接口:存放一对值的排序接口。实现此接口的集合类,里面的内容按照key排序,使用比较器排序。(大小有序)
    	HashMap:双值 key value【小明 10】【小红 20】【小强 30】
    	TreeMap:【15 10】【22 20】【33 30】(有序)
    
  4. 所有的集合要么是Map接口下,要么是Collection接口下的。要么存放单值元素,要么存放双值元素。

  5. 接口不能实例化对象,具体的类才能实例化对象。

3.迭代器

3.1 迭代器模式

  1. 迭代器模式

    提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
    
  2. 作用

    (1)遍历集合时,不暴露集合内部结构。
    (2)为遍历不同的聚合结构提供一个统一的接口。
    
  3. 使用方式

    (1)首先得有集合
    (2)迭代器角色(具体迭代器角色)
    

3.2 迭代器模式的角色构成

  1. 迭代器角色(Iterator)

    定义遍历元素所需要的方法,一般来说会有这么三个方法:
    	next()方法:取到当前的元素,并且移动到下一个元素的位置;
    	hasNext()方法:判断遍历是否结束;
    	remove()方法:删除当前对象;
    
  2. 具体迭代器角色(Concrete Iterator)

    实现迭代器接口中定义的方法,完成集合的迭代。ArrayList中的Itr。
    
  3. 容器角色(Aggregate)

    一般是一个接口,提供一个iterator()方法,例如Java中Collection接口,List接口,Set接口等。
    
  4. 具体容器角色(Concrete Aggregate)

    就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
    

4. 快速失败机制

在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exception。

  1. 原理

    迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用modCount变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hasNext()/next()遍历下一个元素之前,都会检测modCount遍历是否为expectedModCount值,是的话就返回遍历;否则抛出异常,终止遍历。
    
  2. 注意

    这里异常的抛出条件是检测到modCount != expectedModCount这个条件。如果集合发生变化时修改modCount值刚好又设置为了 expectedModCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。
    
  3. 场景

    java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。
    

5. 安全失败机制

采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。

  1. 原理

    由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中队员集合所作的修改并不能被迭代器检测到,所以不会触发Concurrent Modification Exception。
    
  2. 缺点

    基于拷贝内容的优点是避免了Concurrent Modification Exception,但同样的,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
    
  3. 场景

    java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。
    
发布了11 篇原创文章 · 获赞 0 · 访问量 129

猜你喜欢

转载自blog.csdn.net/baidu_41806513/article/details/104180388