• JAVA集合框架


    collection大致介绍

    Collection是集合层次结构中的根接口。

    集合表示一组对象。有些集合允许重复元素,有些则不允许。有些是有序的,有些是无序的。

    JDK没有提供此接口的任何直接实现:它提供了更具体的子接口(如Set和List)的实现。

    这个接口通常用于在需要最大通用性的地方传递和操作集合 包或多集(可能包含重复元素的无序集合)应该直接实现此接口。

    Collection的大致结构体系:

    其中常用的有:

    List, ArrayList, LinkedList, Vector.

    Set, HashSet, TreeSet, LinkedHashList

    下文中会挨个看看大致的特性和部分源码.

    Collection接口提供的功能:

    1.添加:
        // 添加一个元素.
        boolean add(E e);
        // 添加多个元素.
        boolean addAll(Collection<? extends E> c);
    2.删除:
        // 删除一个元素.
        boolean remove(Object o);
        // 删除多个元素.
        boolean removeAll(Collection<?> c);
        // 清空集合
        void clear();
    3.判断:
        // 判断是否为空,为空则返回true
        boolean isEmpty();
        // 判断是否包含元素
        boolean contains(Object o);
        // 是否全部包含指定元素
        boolean containsAll(Collection<?> c);
        // 判断是否相等
        boolean equals(Object o);
    4.获取:
        // 继承自Iterable<E>的迭代器, 用于遍历所有元素
        Iterator<E> iterator();
        // 返回集合的哈希码
        int hashCode();
    5.长度:
        //返回此集合中的元素数目。如果数量超过int最大值就返回int最大值
        int size(); 
    6.交集:
        // 移除未包含在c中的所有元素.返回值表示是否发生过移除操作
        boolean retainAll(Collection<?> c);
    7. 转换
        // 转换为数组
        Object[] toArray();
        // 转换为特定类型的数组
        <T> T[] toArray(T[] a);
    8. 流操作
        // 串行流操作
        default Stream<E> stream()
        // 并行流操作
        default Stream<E> parallelStream()
    

    Iterator 大致介绍

    Iterator(迭代器),用于以迭代的方式遍历集合.

    是一种模式、详细可见迭代器设计模式.

    可以使得序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。

    只要拿到这个对象,使用迭代器就可以遍历这个对象的内部。

    一般是在集合内提供私有的实现方法,用于迭代集合类.

    Tterator提供的接口:

    // 是否有下一个元素
    boolean hasNext();
    // 返回迭代中的下一个元素。
    E next();
    /** 
     * 从基础集合中移除此迭代器返回的最后一个元素(可选操作)。
     * 此方法在每次调用next时只能调用一次。
     * 如果没有继承方法,默认会抛出 UnsupportedOperationException("remove") 异常
     */
    default void remove()
    // 提供函数式编程
    default void forEachRemaining(Consumer<? super E> action)
    

    Fail-Fast 机制

    概念

    fail-fast机制,即快速失败机制,是java集合中的一种错误检测机制。

    当在迭代集合的过程中集合的结构发生改变(对集合结构的操作会记录操作次数),就会发生fail-fast,抛出ConcurrentModificationException异常。

    在面对并发修改时,迭代器会快速而干净地失败,而不是在将来某个不确定的时间冒任意的、不确定的行为的风险。

    fail-fast机制并不保证在不同步的修改下一定抛出异常,它只是尽最大努力去发现并抛出异常,迭代器的快速故障行为应该只用于检测bug。

    源码中 如何实现的

    以为迭代ArrayList为例:

    fail-fast的实现依赖于ArrayList<E>的父类AbstractList<E>,在AbstractList<E>中,有一个protected transient int modCount = 0;的成员变量来记录集合被操作的次数.

    在ArrayList中, add,remove,replace等操作都会有modCount++来记录集合的被操作次数.

    在进行迭代的过程中调用每个方法前对modCount和开始迭代时记录的expectedModCount进行比对. 如果不一样就快速抛出ConcurrentModificationException错误,防止因为意外产生错误.

    // 调用迭代器
    public Iterator<E> iterator() {
        return new Itr();
    }
    // ArrayList中自己实现的迭代器部分代码
    private class Itr implements Iterator<E> {
            int cursor;       // index of next element to return
            int lastRet = -1; // index of last element returned; -1 if no such
            // 初始化时记录当前的操作数
            int expectedModCount = modCount;
            ......
            ......
            @SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                ......
                ......
            }
            // 比对操作数的值是否有差异
            final void checkForComodification() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
            }
        }
    

    值传递和引用传递, 深复制和浅复制

    值传递和引用传递概念:

    1. 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数.
    2. 引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数.

    在java中, 基本类型变量传递的是值的副本, 相当于把自己赋值一份传递,即使自己的副本变了,自己也不会改变.

    而对象型变量, java传递的是引用的副本(复制指向地址的指针),而不是自己实际值的副本.所以传递后的对象被改变的话, 之前的对象也会同步改变.因为指向的内存中的实际对象被改变了.

    P.S.在这里, String类型有些特殊, 一方面, String属于对象, 传递的是引用的副本, 另一方面,String的特殊结构(字符串常量都存在堆内存中的字符串常量池中), 且String不可更改, 只能创建新的.所以String传递后更改也不会影响之前的.

    深复制和浅复制概念:

    1. 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
    2. 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

    Collection中引用的System.arraycopy()就属于浅拷贝.

  • 相关阅读:
    DB2常用命令2
    主流数据库命令的区别
    数据库开发
    DB2常用函数
    java Http post请求发送json字符串
    Spring Boot集成MyBatis与分页插件
    js实现加密(?!)
    本周、本月等日期的获取
    POST请求中参数以form data和request payload形式+清空数组方式
    转:目前为止最全的微信小程序项目实例
  • 原文地址:https://www.cnblogs.com/zuojing/p/12978413.html
Copyright © 2020-2023  润新知