Java集合类

Iterator接口常用方法

  1. boolean hasNext()
  2. E next()
  3. default void remove()
    删除集合里上一次next方法返回的元素
  4. default void forEachRemaining(Consumer<? super E> action)
    • 调用forEachRemaining遍历集合元素时,程序会依次将集合元素传给Consumer的accept方法。
    • Consumer action为函数式接口,可以用Lambda表达式实现。
    • 通过迭代器调用

Iterable接口常用方法

  1. Iterator iterator()
    返回迭代器对象
  2. default void forEach(Consumer<? super T> action)
    • 调用forEach遍历集合元素时,程序会依次将集合元素传给Consumer的accept方法。
    • Consumer action为函数式接口,可以用Lambda表达式遍历集合元素。
    • 通过集合调用
  3. default Spliterator spliterator()

Collection接口常用方法

  • 添加

    • boolean add(Object obj):
    • boolean addAll(Collection coll):
  • 删除

    • boolean remove(object obj);//会改变集合的长度
    • boolean removeAll(Collection coll);//将两个集合中的相同元素,从调用removeAll的集合中删除
    • void clear();
  • 判断

    • boolean contains(object obj);//
    • boolean containsAll(Colllection coll);
    • boolean isEmpty();判断集合中是否有元素。
  • 获取

    • int size():
    • Iterator iterator();取出元素的方式:迭代器

Map接口常用方法

  • 添加:

    • value put(key,value)

      返回前一个和key关联的值,如果没有返回null.
      如果添加的key值重复,则对应的新的value会替代旧的value,并返回旧的value的值,如果key是第一次添加,则返回null

  • 删除:

    • void clear() //清空map集合。
    • value remove(key) //根据指定的key翻出这个键值对,并返回对应key值
  • 判断

    • boolean containsKey(key):
    • boolean containsValue(value):
    • boolean isEmpty();
  • 获取

    • value get(key):通过键获取值,如果没有该键返回null。
      当然可以通过返回null,来判断是否包含指定键。

    • int size(): 获取键值对的个数。

    • Set keySet():获取map中所有键所在的set集合

    • Set<Map.Entry<K,V>> entrySet()

      获取此映射所包含的映射关系的set视图,Entry是Map中的静态接口,可以直接访问Map中的内容
      Collection values():返回此映射包含的值的Collection视图

集合类

集合类的由来

便于存储数量不定的对象。实现存储数量不定的方法:通过扩容。

集合类VS数组

内容长度
集合引用类型可变
数组引用类型or基本类型固定
  • 存储任意数量的对象,而非基本类型。如果存储基本类型,会自动装箱为引用类型。
  • 对象一旦被装入,就会向上转型为Object类型,因而从集合中取出时也是Object类型。使用泛型后,会自动进行类型转换。

集合类的继承关系

  • 完整版
    在这里插入图片描述
  • 简化版
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

集合类的分类和比较

Iterable Collection List Vector 元素不唯一 有序 同步允许null基于数组
ArrayList不同步 基于数组
LinkedList基于双向链表
SetHashSet 元素唯一无序 不同步允许null基于hash表
TreeSet有序不同步允许null基于红黑树
QueuePriorityQueue
ArrayDeque
MapHashtable 键值唯一无序同步不允许null作为键或值基于hash表
HashMap无序不同步null既可以作为键也可以作为值基于hansh表
TreeMap无序不同步允许null作为键或者值(注意事项见下)基于红黑树

注意事项:

  • 当第二次存入key为null的键值对时,如果集合自身不带比较器,那么需要调用元素自身的compareTo()方法,即key.compareTo()方法,此时必然产生NullPointerException异常。

集合遍历方法

  • 使用Iterator的hasNext(),next()
  • 使用Iterator的forEachRemaining(Lambda表达式)
  • 使用集合的forEach(Lambda表达式)
  • 使用foreach语句
  • 使用for语句对数组结构的List集合进行遍历

常见问题

hashmap和hashtable的区别

HashMap不同步允许null作为键或值用containsvalue和containsKey方法实现Map接口的类
Hashtable同步不允许有null的键和值用contains方法方法继承Dictionary 类且实现Map接口的类

Iterator和Iterable的区别

在这里插入图片描述

  • Iterator接口
    • 含义上
      Iterator接口和Collection、Map接口一样,也是Java集合框架的成员。Collection、Map主要用于盛装对象,Iterator主要用于遍历(迭代)Collection集合中的对象,因而也叫作迭代器。Iterator对象必须依附于Collection对象,即如果又一个Iterator对象,则必然有一个与之关联的Collection对象。
    • 迭代状态上
      Iterator实例可以存储迭代状态,即可以通过hasnext()检查是否有下一个元素,并可以通过next()获取下一个元素
  • Iterable接口
    • 含义上
      Iterable接口是Collection接口的父类,其代表可以迭代的一系列元素的简单表示。它包含的 iterator() 函数用于返回迭代器对象,从而实现用Iterator迭代Collection对象。
    • 迭代状态上
      Iterable每次调用 iterator() 函数都会生成一个新的iterator实例,即返回一个从头开始计数的迭代器,多个迭代器是互不干扰的。

Iterator与fast-fail机制

  • 什么是fast-fail(快速失败)机制
    在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exceptionjava.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。
  • fast-fail(快速失败)机制的原理
    迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个modCount 变量。集合在被遍历期间如果内容发生变化(调用add、remove、clear等方法),就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
    注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount 这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。
  • 为什么需要fast-fail(快速失败)机制
    "快速失败"是java集合的一种错误检测机制,其作用主要是为了防止当多线程对集合进行结构上的改变或者集合在迭代元素时直接调用自身方法改变集合结构而没有通知迭代器时,会造成数据不一致的问题,即保证操作的隔离性(我自己的理解)。当然,在单线程操作中也会出现为题,如:
    ArrayList<String> arrayList=new ArrayList<>();
            arrayList.add("hello");
            arrayList.add("how are you");
            arrayList.add("I'm ok");
            Iterator<String> iterator=arrayList.iterator();
            boolean shouldDelete=true;
            while (iterator.hasNext()){
                String string=iterator.next();
               if(shouldDelete){
                   shouldDelete=!shouldDelete;
                   arrayList.remove(2);
               }
            }
    

equals() 和 hashCode()

  • 为什么需要hashCode()方法和equals()方法
    equal():判断两个对象是否相同(一般是内容相同)
    hashCode():用来在散列存储结构中确定对象的存储地址,从而实现快捷查找
  • 为什么需要重写hashCode()方法和equals()方法
    我们经常会希望两个不同对象的某些属性值相同时就认为他们相同,所以我们要重写equals()方法。而按照原则,我们重写了equals()方法,也要重写hashCode()方法。
  • 如何重写hashCode()方法和equals()方法
    • JavaSE 8 Specification中对equals()方法的说明:
      • 自反性:A.equals(A)要返回true;
      • 对称性:如果A.equals(B)返回true, 则B.equals(A)也要返回true;
      • 传递性:如果A.equals(B)为true, B.equals©为true, 则A.equals©也要为true. 说白了就是 A = B , B = C , 那么A = C;
      • 一致性:只要A,B对象的状态没有改变,A.equals(B)必须始终返回true;
      • A.equals(null) 要返回false;
    • 在Java API文档中关于hashCode方法有以下几点规定(原文来自java深入解析一书)
      • 在java应用程序执行期间,如果在equals方法比较中所用的信息没有被修改,那么在同一个对象上多次调用hashCode方法时必须一致地返回相同的整数。如果多次执行同一个应用时,不要求该整数必须相同。

      • 如果两个对象通过调用equals方法是相等的,那么这两个对象调用hashCode方法必须返回相同的整数。

      • 如果两个对象通过调用equals方法是不相等的,不要求这两个对象调用hashCode方法必须返回不同的整数。但是程序员应该意识到对不同的对象产生不同的hash值可以提供哈希表的性能。

        重写了equals()方法也要重写hashCode()方法,这是因为要保证上面所述的第二个和第三个原则


参考文献

https://blog.csdn.net/u010983881/article/details/49762595 hashmap和hashtable的区别
https://www.nowcoder.com/questionTerminal/95e4f9fa513c4ef5bd6344cc3819d3f7 fast-fail机制和fail-safe机制
https://www.jianshu.com/p/1c2d31b1f69e 为什么需要fast-fail(快速失败)机制
https://github.com/CyC2018/CS-Notes/blob/master/notes/Java 容器.md 容器
https://blog.csdn.net/javazejian/article/details/51348320 重写equal()时为什么也得重写hashCode()
https://blog.csdn.net/xlgen157387/article/details/63683882 为什么要重写hashCode()方法和equals()方法以及如何进行重写

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值