day_17_集合概述、List、Set、比较器

Day17-集合

  1. Collection
    1.1 概述
  • 通过继承体系发现,集合中两大分类,List和Set 并且 两个都继承了Collection
  • 那也就意味着,Collection中的方法是List和Set都有的,
  • 所以我们先讲Collection,看看它里面都有什么方法
  • Collection 集合 只能存储单个元素,并且只能保存引用数据类型,不能保存基本数据类型
  • 因为 底层就是 Object[] 数组,既然是Object 所以 即可以说 只能保存Object单一元素,也可以说
  • 可以保存任何元素,因为Object是祖类,所有类型都会发生向上转型(多态)
  • 基本类型真的不能存吗? 真的,因为基本类型和Object没有关系,但是 可以把基本类型转换为对应的包装类类型,而 包装类 是Object的子类,这样就能间接存储基本类型了
  • 常用方法 :
  •  	boolean add() : 添加元素
    
  •  	void clear() : 清空集合
    
  •  	boolean remove() 删除某个元素
    
  •  	boolean isEmpty() 判断集合中是否为空
    
  •  	boolean contains() : 是否包含某个元素
    
  •  	int  size() 返回集合中 元素个数
    

java集合是使程序能够存储和操纵元素不固定的一组数据。 所有Java集合类都位于java.uti包中。
【问】:之前我们需要把多个元素放到一起的时候,使用的是数组。那么为何还要提供Java集合工具类呢?
我们通过对比数组和Java集合工具类来解释Java集合工具类的必要性。
在这里插入图片描述

注意:如果集合中存放基本类型,一定要将其 “装箱”成对应的”基本类型包装类”。

1.2 继承体系

在这里插入图片描述
在这里插入图片描述

由以上两图我们可以看出Java集合类有清晰的继承关系,有很多子接口和实现类。但是,并不是所有子接口或实现类都是最常用的。
下面我们列举出最常用的几个子接口和实现类:
Collection ——> List ——> ArrayList类
Collection ——> List ——> LinkedList类
Collection ——> Set ——> HashSet类
Collection ——> Set ——> SortedSet接口 ——> TreeSet类
Map ——> HashMap类
Map ——> SortedMap ——> TreeMap类
1.3 Collection和Iterator
1.3.1 Collection概述
Collection接口是List接口和Set接口的父接口,它定义的方法可以用于操作List集合和Set集合。
Collection接口定义的方法

在这里插入图片描述

1.3.2 Collection使用

在这里插入图片描述
在这里插入图片描述

1.3.3 Iterator概述

在这里插入图片描述

  • Iterator是迭代器
  • 迭代器是一种模式,它可以使序列类型的数据结构的遍历行为和被遍历的对象分离
  •  也就是 我们无需关心该序列底层数据结构是什么样子的,只要拿到这个对象,使用迭代器就可以遍历这个对象的内部数据
    
  • 创建迭代器对象
  •  Iterator it = 集合对象.iterator();
    
  •  	调用集合对象自己的iterator方法就可以创建属于自己的迭代器
    
  • Iterator方法
  •  1 boolean hasNext() : 判断光标下一位 是否还有元素,有就返回true,没有就返回false,
    
  •  		生成迭代器的时候,光标不是指向第一个元素的,而是在最顶端,没有指向任何元素
    
  •  		光标不会自动复位,使用完之后,必须重新生成
    
  •  2 E next() : 把光标向下移动一位,并返回该位上的数据
    
  •  3 remove() : 删除当前光标指向的元素
    
  •  三个方法的使用顺序,就是 1,2,3 
    
  • 迭代器 一旦创建,如果集合中添加或者删除元素,那么迭代器必须重新重新生成,
  • 否则调用next()方法会报错
  • 但是 更改数据 不用重新生成
  • 增强for循环,forEach 就是为了让用iterator循环访问的形式变简单,写起来方便,当然功能不太全,没有办法删除
  • 所以需要有删除操作的话,还是要用原来的iterator形式
  • 所以 forEach也是迭代器,使用forEach和使用iterator一样,不能添加或删除集合数据,但是更改可以
  • 而 普通for和while这种遍历,都是和数据结构存储有关系的,比如数组 需要使用 arr[index]去访问
  • 并且可以进行添加和删除操作

注意 使用迭代器进行遍历操作时 如果需要删除元素,只能使用 迭代器的remove方法,不能使用集合的remove方法

  1. Collection接口的iterator()和toArray()方法都用于获得集合中的所有元素,前者返回一个Iterator对象,后者返回一个包含集合中所有元素的数组。
  2. Iterator接口隐藏底层集合中的数据结构,提供遍历各种类型集合的统一接口。

在这里插入图片描述

1.3.4 Iterator使用

在这里插入图片描述
在这里插入图片描述

1.3.5 注意 : Contains和remove

  • boolean contains(Object o)
  •  判断集合中是否包含某个元素
    
  • boolean remove(Object o)
  •  在集合中删除指定元素
    
  • 这两个方法,底层都会去调用equals方法进行比较
  •  c.contains("asd") , 会用 asd 调用String的equals方法 挨个和集合中元素进行比较
    
  •  判断谁,就用谁调用equals方法,和集合中元素进行比较
    

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

所以如果是存储的自定义类型(类对象),就需要根据需求覆写equals方法

在这里插入图片描述
在这里插入图片描述

1.4 List

  • List元素的特性 : 有序可重复
  •  存入顺序和取出顺序是一致的,并且有指定的下标可以表示数据的唯一性,所以可以存在重复数据
    
  • 底层实现
  •  	ArrayList : 底层是数组,查询效率较高,添加和删除效率较低
    
  •  	LinkedList : 底层是双向链表,查询效率较低,添加和删除效率较高
    

Vector 已经过时了,ArrayList是Vector的升级版,而Vector属于线程安全,ArrayList属于非线程安全,所以ArrayList效率较高

在这里插入图片描述
在这里插入图片描述

1.4.1 ArrayList

  • 深入List
  • ArrayList : 底层索引数组,下标0开始 初始化容量为 10 ,扩大容量为 原始容量的1.5倍.非线程安全,效率高
  • Vector : 初始化容量为10 , 扩大容量为 原始容量的 2 倍,线程安全,效率低
  • 所以 Vector已经废弃
  • List遍历方式
  •  while , for, foreach , iterator 
    

常用方法

  • add(E e) : 将指定元素添加到尾部
  • add(int index,E e) : 将指定元素添加到指定位置,原位置内容统一向后移动
  • set(int index,E e) : 更改指定位置上的元素值
  • get(int index) : 获取指定索引上的元素
  • remove(int index) : 删除指定索引上的元素
  • remove(Object o) : 删除指定元素

在这里插入图片描述

在这里插入图片描述

1.4.2 LinkedList

1.4.2.1 基本使用

  • LinkedList : 底层是双向链表

  •  链表 : 链表中保存的是节点,每个节点中有三个元素
    
  •  	1 自身对象(添加的元素) , 2 上一个节点的地址 , 3 下一个节点的地址
    
  • 链表是没有下标的,内存空间也不是连续的,所以查询比较慢

  •  由于内存空间不是连续的,只是保存上下节点的引用,随意添加删除比较快
    
  • add(E e) : 添加到尾部

  • push(E e) : 添加到头部

  • addFirst(E e) : 添加到头部

  • addLast(E e) : 添加到尾部

  • offerFirst(E e) 添加到头部,成功返回true

  • offerLast(E e) : 添加到尾部,成功返回true

  • get(int index) : 返回指定下标对应的数据(链表没有下标,只是模拟下标,方便我们查询使用)

  • 本质 就调用了两个方法 : linkLast 和 linkFirst 所以没任何区别

底层实现
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.4.2.2 底层实现
1.4.2.2.1 Node节点类

在这里插入图片描述

节点类其实是 LinkedList中的一个静态内部类,并且该类中保存三个属性
添加的数据 item
上一个节点内存地址 next
下一个节点内存地址 prev
根据Node节点类的实现方式,就能看出,该节点是双向的
1.4.2.2.2 LinkedList类
在这里插入图片描述

而LinkedList中 保存了两个节点类的对象,分别是首节点和尾结点,方便我们使用,所以我们可以首部添加,也可以尾部添加
已添加为例,讲解LinkedList的底层实现
1.4.2.2.3 添加-add

在这里插入图片描述
在这里插入图片描述

根据add方法,最终发现实现尾部添加的是 linkLast方法
下一步 进行代码分析
在这里插入图片描述

1.4.2.2.4 获取-get
在这里插入图片描述

校验下标

在这里插入图片描述

在这里插入图片描述

获取数据

在这里插入图片描述

Get只是模拟下标获取的方式而已,其实本质就是遍历,从头挨个找
只不过做了一定的判断,判断是找前半截还是后半截,来决定 是正序遍历还是倒叙遍历
本质就是循环通过next一个一个的节点去找,所以这个get和ArrayList中的get完全不是一回事,ArrayList中就是封装了下标访问方式而已,下面是ArrayList的get方法实现
在这里插入图片描述

在这里插入图片描述

1.4.2.2.5 删除原理

在这里插入图片描述

在这里插入图片描述

1.5 Set和排序

  • Set元素特点 : 无序不可重复
  • TreeSet : 底层红黑树
  • HashSet : 底层散列表
    在这里插入图片描述
    在这里插入图片描述

1.5.1 TreeSet

  • TreeSet : 元素必须有序,添加的元素会按照某种规则自动排序
  • 想要使用TreeSet,元素必须要排序
  •  数字 : 默认从小到大
    
  •  字符串 : 默认比较每位ASCII码
    
  •  日期 : 默认比较自然日期 昨天-今天-明天
    

在这里插入图片描述
在这里插入图片描述

1.5.2 排序
1.5.2.1 Comparable

  • 比较器有两种 : 1 元素自身比较器, 2 比较器类
  • 思考 : 为什么字符串,Integer,Date可以排序?
  •  因为都实现了 implements Comparable 
    
  • 因为使用treeSet在进行数据添加的时候,会自动调用该对象的compareTo()方法和集合内元素进行比较
  • 如果我们想要存储自定义类型怎么办?
  •  需要实现该接口才行
    

在这里插入图片描述

添加的时候 会自动调用该对象的compareTo方法,而该方法就在Comparable接口中,所以 必须要实现,否则不能添加到TreeSet中

在这里插入图片描述

在这里插入图片描述

’’在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值