复习11:List&Set&Queue

集合:List

List是什么

List是Collection的一个子接口,被称为有序列表

List的特点

  • 有序:每一个元素的索引被确定
  • 重复:集合中的元素可重复
  • 线性:元素的内存地址是连续的

List的实现类

  • ArrayList
  • LinkedList
  • Vector:与ArrayList相同,但是目前已不再使用Vector

Vector与ArrayList之间的关系:StringBuffer与StringBuilder之间的关系

List的迭代方式

  • 迭代器
  • for-each
  • for()
    • 有索引

List的常用API

  • add(int index,element):将元素添加到索引的位置
  • remove(index):移除索引位置的元素
  • get(index):获取索引位置的元素
  • set(int index,element):使用新的元素替换索引位置的元素
  • indexOf(…):返回元素在集合中第一次出现的位置的索引
  • lastIndexOf(…):返回元素在集合中最后一次出现的位置的索引
  • List subList(int fromIndex,int endIndex):截取[fromIndex]到[endIndex]之间的集合(左开右闭)
    • 修改子集合中的元素时,父集合中的元素也会有同样的变化
    • 添加元素到子集合中时,父集合中会插入相同的元素(与子集合顺序保持一致)
    • 删除子集合中的元素时,父集合中的相同元素也会被删除
    • 由此我们得出结论:子集合与父集合共用一个内存空间,所有对子集合的操作都会影响到父集合
    • 解除父、子集合绑定的方法:List list =new ArrayList(LIst sunList)
  • toArray(…):
    • toArray():默认将集合转换成一个Object类型的数组
    • toArray(T[] a):将集合转换为一个指定类型的数组(a是数组对象,不需要有元素)
      • 传递的数组参数的长度大于集合的长度,则多出来的位置用null填充
      • 传递的数组参数的长度小于集合的长度,则默认将数组长度扩容到与集合长度相同

数组转换成集合:List list = Arrays.asList(Array a)

  • 泛型类型与传递的数组类型相同
  • 转换后的list并非寻常的集合,而是数组的一个内部类,不能进行增、删(改变长度),可以进行改、查;如果想操作该集合,只需创建一个新的集合对象,将list作为参数构造新集合

ArrayList

ArrayList的实现

数组(Array)

ArrayList的特点
  • 内存空间连续
  • 查找效率高:元素的索引是确定的
  • 插入效率低
    • 头部插入最慢:所有元素需要后移一位
    • 中部插入其次:插入位置之后的元素需要后移一位
    • 尾部插入最快:元素不需要后移
ArrayList的常用API
  • int size():返回列表中的元素
  • boolean isEmpty():判断列表是否为空
  • boolean contains(Object element):判断列表是否包含元素
  • boolean add(Object element):将元素添加到列表末尾
  • void clear():情况列表中的所有元素
  • void add(int index,Object element):将元素插入到指定索引的位置
  • Object remove(int index):删除指定索引位置的元素,并将该元素返回
  • boolean remove(Object element):删除列表中第一次出现的匹配元素
  • Object set(Object oldE,ObjectnewE):使用新元素替换列表中的旧元素,并将旧元素返回
  • Object get(int index):获取指定索引位置的元素
ArrayList的长度与扩容方式
  • 初始长度:10
  • 扩容方式:扩容后的大小=原始大小+原始大小/2(/2的结果向下取整),例如:原始大小是15,扩容后的大小为:15+15/2=22

Vector的初始长度与ArrayList相同,但是Vector是成倍扩容(初始长度为10,扩容之后长度为20)

LinkedList

LinkedList的实现

LinkedList的实现原理是链表,它的链表结构是双向的,可以从头部或者尾部开始访问,也可以同时访问头尾

  • LinkedList既可以作为List,也可以作为双端队列(拥有双端队列和栈的所有方法)
LinkedList的元素特点

链表的基本单元是节点,LinkedList的元素就存放在节点中

  • 节点的结构:三层结构
    • 头部(Previous):存放上一个节点的地址信息
    • 中部:存放元素信息
    • 尾部(Next):存放下一个节点的地址信息
  • 元素的索引不确定
LinkedList的结构特点:
  • 内存空间不连续
  • 查找效率低
    • 访问头、尾元素最快
    • 访问中部元素最慢
  • 插入效率高:新元素的头部指向上一个元素的尾部,新元素的尾部指向下一个元素的头部
LinkedList的常用API

LinkedList与ArrayList的方法类似,下面介绍一些LinkedList的特有方法

  • addFirst(E e):将指定元素添加到此列表的开头
  • addList(E e):将指定元素添加到此列表的尾部
  • getFirst():返回此列表的第一个元素
  • getLast():返回此列表的最后一个元素
LinkedList的长度与扩容方式
  • 由于LinkedList是双向链表,因此LinkedList没有初始化大小,也没有扩容机制

集合:Set

Set是什么

Collection接口下的一个子接口,被称为散列表

Set的特点

  • 无序
    • 元素在Set中的顺序与添加顺序不同
    • 元素在Set中的顺序由hashCode()决定
  • 不可重复
    • Set中的元素不可重复

Set的实现类/子接口

  • HashSet(实现类)
  • SortedSet(子接口)
    • TreeSet:SortedSet的实现类

Set的迭代方式

  • 迭代器
  • for-each

因为set没有索引,所以无法使用for()迭代

Set的API

Set的方法都是从Collection中继承的,没有特有方法

HashSet可以添加null值

HashSet实现不可重复添加元素的原理

  1. 通过待添加元素的hashCode()确定该元素在Set中的位置
  2. 如果该位置上已有元素,则通过待加入元素的equals()判断两者是否是相同元素
  3. 如果判断结果为true,则放弃添加
  4. 如果判断结果不一致,则添加到相同位置
    • 在该位置形成一个链表,原来的元素向后推,新的元素排在前面

原理的核心步骤就是第1、2步,要求待添加的元素重写hashCode()和equals(),且必须两个方法都要重写,否则会发生:

  • hashCode()重写,equals()未重写:相同位置存在相同元素
  • hashCode()未重写,equals()重写:不同位置存在相同元素

注意:若将一个元素添加到Set之后,修改了有关hashCode()计算的属性值,会发生的事情有:

  • 可以再次添加:hashCode()发生了变化,计算的位置与之前不同
  • 无法删除之前添加的元素:hashCode()发生了变化,计算的位置与之前不同

TreeSet

TreeSet是什么

可以排序的散列表

  • 添加到TreeSet中的元素自动按照自然顺序排序,被添加的元素需要实现Comparable接口
TreeSet的底层实现:二叉树

虽然TreeSet实现了自然排序,但它本身仍然是无序的(本质是散列表)

TreeSet实现不可重复添加与排序的原理

不再使用hashCode()和equals(),而是实现Comparable或者Comparator接口

  • 待添加的元素已实现Comparable接口:通过compareTo()的返回值判断两个元素是否相同
  • 待添加的元素未实现Comparable接口:通过声明Set对象时传入一个Comparator比较器,添加元素时根据比较器的返回值判断两个元素是否相同

集合:Queue

Queue是什么

Collection下的一个子接口,称为队列

Queue的特点

一头进,一头出(先进先出,后进后出)

Queue的实现类/子接口

Deque:子接口

  • LinkedList:实现类

Queue的API

Queue是Collection的子接口,继承了Collection的方法,下面介绍一些Queue有其特有的方法:

  • offer():添加元素
  • peek():返回队列中的第一个元素,该元素不会从队列中删除
  • poll():返回队列中的第一个元素,该元素会从队列中删除

Deque

Deque是什么

双端队列

Deque的特点
  • 两头都可以进出
  • 可以作为栈来使用,拥有栈的方法
Deque的API
  • Deque继承了Queue的方法
  • Deque有其特有的方法:
    • offerFirst()
    • offerLast()
    • peekFirst()
    • peekLast()
    • pollFirst()
    • pollLast()
    • getFirst()
    • getLast()
  • 栈的方法:
    • push():将元素加入栈中(旧元素在后面,新元素在前面)
    • pop():返回栈中第一个元素(最后添加的元素),并将该元素从栈中删除

队列、双端队列、栈的区别

进出口 元素进出先后级
队列 一个口进,一个口出 先进先出、后进后出
双端队列 两个口都可以进出 无影响
只有一个口能进出 先进后出,后进先出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章