一、集合整体框架图

集合框架图

二、讲解

1、Collection集合接口

Collection集合

1.1、Collection

Java标准库自带的java.util包提供了集合类:Collection,它是除Map外所有其他集合类的根接口。Java的java.util包主要提供了以下三种类型的集合:

  • List:一种有序列表的集合,例如,按索引排列的StudentList
  • Set:一种保证没有重复元素的集合,例如,所有无重复名称的StudentSet
  • Queue: 一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作 。FIFO

1.1.1、List

List的行为和数组几乎完全相同:List内部按照放入元素的先后顺序存放,每个元素都可以通过索引确定自己的位置,List的索引和数组一样,从0开始。 所以List和Array可以相互转换

注意: 要正确使用Listcontains()indexOf()这些方法,放入的实例必须正确覆写equals()方法,否则,放进去的实例,查找不到。我们之所以能正常放入StringInteger这些对象,是因为Java标准库定义的这些类已经正确实现了equals()方法。

List衍生出来的子类包括一下三种:

  • ArrayList ArrayList在内部使用了数组来存储所有元素

例如,一个ArrayList拥有5个元素,实际数组大小为6(即有一个空位):

  • LinkedList 底层的数据结构是基于双向循环链表的,且头结点中不存放数据
  • Vector 可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。不过,Vector的大小是可以增加或者减小的,以便适应创建Vector后进行添加或者删除操作。 实现该接口的类是Stack (LIFO)

1.1.2、Set

Set实际上相当于只存储key、不存储value的Map。我们经常用Set用于去除重复元素

因为放入Set的元素和Map的key类似,都要正确实现equals()hashCode()方法,否则该元素无法正确地放入Set

  • HashSet HashSet这个类实现了Set集合,实际为一个HashMap的实例
  • SortedSet 提供排序操作,实现他们的子类都具有接口中定义的功能
  • EnmuSet 一个专为枚举设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定

1.1.3 Queue

队列(Queue)是一种经常使用的集合。Queue实际上是实现了一个先进先出(FIFO:First In First Out)的有序表。它和List的区别在于,List可以在任意位置添加和删除元素,而Queue只有两个操作:把元素添加到队列末尾;从队列头部取出元素。

  • PriorityQueue 优先队列的作用是能保证每次取出的元素都是队列中权值最小的
  • Deque 含义是“double ended queue”,即双端队列,它既可以当作栈使用,也可以当作队列使用

3、Map

Map框架

Map这种键值(key-value)映射表的数据结构,作用就是能高效通过key快速查找value(元素)

重复放入key-value并不会有任何问题,但是一个key只能关联一个value, 如果放入的key已经存在,put()方法会返回被删除的旧的value,否则,返回null

可以通过for each遍历keySet(),也可以通过for each遍历entrySet(),直接获取key-value

正确使用Map必须保证:

  1. 作为key的对象必须正确覆写equals()方法,相等的两个key实例调用equals()必须返回true
  2. 作为key的对象还必须正确覆写hashCode()方法,且hashCode()方法要严格遵循以下规范:
  • 如果两个对象相等,则两个对象的hashCode()必须相等;
  • 如果两个对象不相等,则两个对象的hashCode()尽量不要相等。

即对应两个实例ab

  • 如果ab相等,那么a.equals(b)一定为true,则a.hashCode()必须等于b.hashCode()
  • 如果ab不相等,那么a.equals(b)一定为false,则a.hashCode()b.hashCode()尽量不要相等。
  • HashMap 是最常用的( 实际上HashMap初始化时默认的数组大小只有16 ) 使用Map的时候,只要key不相同,它们映射的value就互不干扰。但是,在HashMap内部,确实可能存在不同的key,映射到相同的hashCode(),即相同的数组索引上,肿么办? 我们就假设"a""b"这两个key最终计算出的索引都是5,那么,在HashMap的数组中,实际存储的不是一个Person实例,而是一个List,它包含两个Entry,一个是"a"的映射,一个是"b"的映射

hashCode()方法编写得越好,HashMap工作的效率就越高

  • EnmuMap key的对象是enum类型
  • TreeMap 在内部会对Key进行排序,这种Map就是SortedMap。注意到SortedMap是接口,它的实现类是TreeMap , 使用TreeMap时,放入的Key必须实现Comparable接口 , 注意到Comparator接口要求实现一个比较方法,它负责比较传入的两个元素ab,如果a<b,则返回负数,通常是-1,如果a==b,则返回0,如果a>b,则返回正数,通常是1TreeMap内部根据比较结果对Key进行排序
  • Properties 配置文件

4、Iterator

Java的集合类都可以使用for each循环,ListSetQueue会迭代每个元素,Map会迭代每个key ,好处如下:

  • 对任何集合都采用同一种访问模型;
  • 调用者对集合内部结构一无所知;
  • 集合类返回的Iterator对象知道如何迭代。

5、 Collections

Collections是JDK提供的工具类,同样位于java.util包中。它提供了一系列静态方法,能更方便地操作各种集合。

  • 创建空集合 List<String> list2 = Collections.emptyList()
  • 创建单元素集合 List<String> list2 = Collections.singletonList("apple"); 不如使用List.of()方便
  • 排序 Collections可以对List进行排序。因为排序会直接修改List元素的位置,因此必须传入可变List
  • 洗牌 Collections提供了洗牌算法,即传入一个有序的List,可以随机打乱List内部元素的顺序,效果相当于让计算机洗牌
  • 不可变集合 List mutable = new ArrayList<>(); List immutable = Collections.unmodifiableList(mutable); immutable.add(“orange”); // UnsupportedOperationException! 然而,继续对原始的可变List进行增删是可以的,并且,会直接影响到封装后的“不可变”List ,所以再变为不可变的集合后,要扔掉之前的List集合引用
  • 线程安全集合 Collections还提供了一组方法,可以把线程不安全的集合变为线程安全的集合

分类: Java

0 条评论

发表评论

电子邮件地址不会被公开。