集合 &迭代器Iterator

集合

集合中有collection和Map集合
collection接口中包括LIst接口和Set接口

Collection中只能存储单个元素 并且只能保存单个元素,只能存储引用类型的数据,不能保存基本类型的数据
因为 底层就是 Object[] 数组,既然是Object 所以 即可以说 只能保存Object单一元素,也可以说可以保存任何元素,因为Object是祖类,所有类型都会发生向上转型(多态)

集合中的常用方法
Booleanadd()  添加元素
void clear() : 清空集合
boolean remove() 删除某个元素
boolean isEmpty() 判断集合中是否为空
 boolean contains() : 是否包含某个元素
int  size() 返回集合中 元素个数

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方法

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

List

List元素的特性 : 有序可重复
存入顺序和取出顺序是一致的,并且有指定的下标可以表示数据的唯一性,所以可以存在重复数据

底层实现

  • ArrayList : 底层是数组,查询效率较高,添加和删除效率较低
    LinkedList : 底层是双向链表,查询效率较低,添加和删除         效率较高
    Vector 已经过时了,ArrayList是Vector的升级版,而Vector属于线程安全,ArrayList属于非线程安全,所以ArrayList效率较高*
    

ArrayList

底层索引数组,下标0开始 初始化容量为 10 ,扩大容量为 原始容量的1.5倍.非线程安全,效率高

  • Vector : 初始化容量为10 , 扩大容量为 原始容量的 2 倍,线程安全,效率低

  • 所以 Vector已经废弃

  • List遍历方式


常用方法

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

Linkedlist

linkedlist的基本使用
他的底层是双向链表
链表 : 链表中保存的是节点,每个节点中有三个元素

  •  	1 自身对象(添加的元素) , 2 上一个节点的地址 , 3 下一个节点的地址
    链表是没有下标的,内存空间也不是连续的,所以查询比较慢
      由于内存空间不是连续的,只是保存上下节点的引用,随意添加删除比较快
    
* push(E e) : 添加到头部
* addFirst(E e) : 添加到头部
* addLast(E e) : 添加到尾部
* offerFirst(E e) 添加到头部,成功返回true
* offerLast(E e) : 添加到尾部,成功返回true
* get(int index) : 返回指定下标对应的数据(链表没有下标,只是模拟下标,方便我们查询使用)

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

他的底层实现是 NODE节点
节点类其实是 LinkedList中的一个静态内部类,并且该类中保存三个属性
添加的数据 item
上一个节点内存地址 next
下一个节点内存地址 prev
根据Node节点类的实现方式,就能看出,该节点是双向的

Set

特点:元素无序不可重复的
TreeSet 集合 底层是红黑树数据结构
Hashset 集合 底层是散列表

使用的方法和父类collection接口中的方法一致

TreeSet

元素必须有序 并且是同一类型的对象 添加的元素必须按某种规则自动排序

HashSet

  • hash算法 : 是一种安全的加密算法,把不定长的值改变为定长值,并不能保证唯一性
  • 散列表 :
  •  数组中 保存链表(单向链表),并且链表节点内有四个属性
     		1 key  2  value  3 next  4  hash
    
     散列表是一种数据结构,不过java中屏蔽了,直接以封装的形式封装到了HashSet, HashMap 和HashTable中
     其中hashTable已经过时
    
     hash算法在java中 就是指 hashCode函数及重写
    
     哈希的目的 就是为了查询快,因为hash是一个固定的值
    
    1 hash过程
     拿到对象,调用对象自身的hashCode()方法,然后进行hash算法,得到数组下标,把值保存到对应的数组中,
    
    Set特性 : 无序 , 不可重复(hashCode和equals)
    
    2 HashSet 和 HashMap 
     HashSet 就是HashMap的封装,本质就是一个HashMap
     默认初始化容量 都是 16 
     封装之后 HashSet把value值屏蔽了,只能操作key,所以在使用set添加的时候,只需要传入key即可
    
    3 添加过程
     1 使用添加的键值对中的key,调用key的hashCode方法,生成hash值,进行hash算法得到数组下标
     		,判断该下标上是否有元素,如果没有,把该键值对 保存到该数组中即可
     2 如果该数组中有对象,则调用key的equals方法和数组中的元素进行比较,如果相等则key不添加,value值覆盖
     3 如果不相等,就把该 对象的 添加到已有元素的next属性,形成链表
     4 如果添加的时候 就已经是链表了,则需要用key和链表中所有的元素key进行比较是否相等
    

hashset的使用

  • 因为散列表中 需要使用hashCode和equals来表示对象的唯一性
  • 所以 在进行添加自定义类型的时候,需要考虑 按需求重新hashCode和equals方法
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页