2019.03.06 - Java集合

集合的概念

集合:就是用来存放数据的一个容器

集合与数组的比较

为什么需要集合

  • 数组

    • 长度是固定的,不能再去添加元素
    int[] a = {10, 20, 30};
    a[3] = 0;//报错,数组越界
    
  • 集合类

    • 长度可以改变
    • 能存储任意的对象
    • 长度是随着元素的增加而增加

集合与数组的区别

  1. 数组能存基本数据类型 和 引用数据类型
  2. 集合当中只能存引用数据类型(对象),也可存放基本数据类型(本质是 自动装箱)
  3. 数组的长度是固定的,集合的长度可以改变

集合与数组的适用场合

  • 如果元素个数是固定的,推荐使用数组
  • 如果元素不固定,推荐使用集合

集合的集成体系

  • Collection接口(父接口)
    • List接口(有序)
      • ArrayList实现类(数组)
      • LinkedList实现类(链表)
      • Vector实现类(数组)
    • Set接口(无序)
      • HashSet实现类(hash算法)
      • TreeSet实现类(二叉树)

继承关系图

在这里插入图片描述

Collection

Collection的特点

  • List可以添加重复元素,而Set不能添加重复元素(如果添加重复时,其返回值为false)
  • 可以添加基本数据类型(自动装箱)
  • 添加任何对象
  • 打印直接得到内容(List内部覆盖toString()

在这里插入图片描述

Collection的常用方法

  • add(元素):追加对象,其返回值永远是true
  • remove(元素):移除指定的元素
  • size():判断集合的长度(有几个元素)
  • clear():清空集合
  • isEmpty():验证集合是否为空

在这里插入图片描述

与all相关的常用方法

  • 集合.addAll(集合):拼接集合
//c1是[a, b, c]
//c2是[a, b, c]
c1.addAll(c2)//[a, b, c, a, b, c]
  • 集合.removeAll(集合):删除两个集合的交集
  • 集合.containsAll(集合):判断调用的集合是否包含(全部包含) 传入的集合
    • 返回值:全部包含,true;未全部包含,false
  • 集合1.retainAll(集合2):取交集,把交集结果给 集合1
    • 返回值:如果改变,true;如果未变,false

集合的遍历

数组形式的遍历

  • 先把集合转换成数组
  • 然后遍历数组

元素为基本数据类型

在这里插入图片描述

元素为对象

向上转型(向根类转型):数组里的元素都是Object类型
在这里插入图片描述

迭代器

迭代器常用方法

  • 创建迭代器:集合.iterator()
    • 返回值:迭代器对象
    • 示例:Iterator it = c1.iterator();
  • 获取元素:迭代器.next()
    • 返回值:获取当前游标的内容,游标并往后移动一位
    • 示例:Object o = it.next();
  • 判断迭代器是否还有元素:迭代器.hasNext()
    • 返回值:有,true;无,false

迭代器的遍历

语法格式

在这里插入图片描述

元素为自定义对象的遍历
  • 定义Cat
    在这里插入图片描述
  • 遍历元素为Cat类型的迭代器,需要 向下转型
    在这里插入图片描述

List

  • list有角标
  • 根据角标添加元素:index必须<=size,否则会报错
  • 根据角标获取元素

并发修改异常

  • 并发修改异常:在迭代集合的过程中,是不允许直接修改集合结构。

    • 因为,在获取迭代器的时候,迭代器和集合进行了关联,为保持双方数据一致,modCountexpectedModCount需要是相等的。
  • 如需删除,可使用迭代器的删除

  • modCount != expectedModCount:就会抛出ConcurrentModificationException,目的是保证 迭代器 与 集合 的内容一致。

    • modCount:集合修改次数
    • expectedModCount:迭代当中记录集合修改的次数
    • 迭代器的remove()会强制modCount = expectedModCount;

代码示例

  • Iterator有remove,但无add
    在这里插入图片描述

ListIterator(list迭代器)

  • list特有的迭代器
  • 拥有add()方法
    在这里插入图片描述

ListIterator的常用方法

  • hasPrevious():迭代器当前元素 之前是否还有元素(倒序)
  • previousIndex():倒序游标
  • previous():前一个元素

在这里插入图片描述

ArrayList数据结构分析

ArrayList为什么可以增加元素

  • 数组被初始化就不会被改变
  • ArrayList:创建一个容量(角标)增加50%的新数组,把原数据复制到新数组中,然后扔掉原数组。

ArrayList特点

  • 查询和修改元素较快:通过索引,就能找到对应的值
  • 添加和删除比较慢:需要依次移动元素,即依次更改下标

代码练习:集合去重

元素为字符串

在这里插入图片描述

  • contains():判断集合是否包含某个对象,基于Object.equals(),即地址值的比较。

元素为自定义对象

  • 因为contains()是地址的比较,需要重写Student类equals(),使其基于name进行比较。
  • 可以使用eclipse的sources -> generate equals 自动生成。
    在这里插入图片描述

LinkedList

链表

  • 优点:链表插入与删除元素,较快
  • 缺点:查询与修改比较慢,因为需要遍历
  • 与数组(ArrayList)正好相反

链表的结构

在这里插入图片描述

链表的插入、删除节点

在这里插入图片描述

LinkedList常用方法

  • listIterator():可以使用List父类的所有方法

独有方法

  • list.addFirst("myxq");:在最前添加元素
  • list.addLast("last");:在最后添加元素
  • list.removeFirst();:移除第一个元素
  • list.removeLast();:移除最后一个元素
  • list.get(0):根据角标获取元素,源码基于for遍历,效率低;而ArrayList基于角标直接获取,效率更高。

利用LinkedList构造栈

  • 栈:先进后出
    在这里插入图片描述

Vector

  • Vector类很少使用,常用ArrayList
  • 从1.2开始并入List接口

Vector特有方法

  • addElement():添加元素,现在使用add()
  • elements():获取所有元素,用于遍历

Vector与ArrayList

  • 都是用数组实现
  • Vector的synchronized方法都会加同步锁,更安全;而ArrayList无同步锁。

猜你喜欢

转载自blog.csdn.net/weixin_42359693/article/details/88225842