• Collection接口及其常用子类(java.util包)


    1. Collection接口

    • List关注事物的索引列表

      • ArrayList:可以理解为一个可增长的数组,提供快速迭代和随机访问的能力。
      • LinkedList:可以理解为一个双链表,提供快速插入删除的能力。
      • Vector:是线程安全版本的ArrayList,但是性能低。

    Collection结构图及总结

    Collection是单个集合保存的最大父接口。
    每一次进行数据操作的时候只能够对单个对象进行处理。

    public interface Collection<E> extends Iterable<E>
    
    • 1
      • Iterable是一个迭代器接口。
        接口Iterable,该接口包含一个能够产生Iterator接口的iterator()方法,并且Iterable对象被foreach用来在序列中移动,因此创建的任何实现了Iterable接口的类都可以将它用于foreach。
      •  

      • 1.1Collection接口中的核心方法

        ****add(T t) //向类集中添加元素
        ****iterator() //取得类集迭代器
        addAll()
        clear()
        contains()
        remove()
        size()
        toArray()
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8

        ---------简写,并不全是无参。加星号的表示比较重要。

        collection只定义了存储数据的标准,但是无法区分存储类型。
        实际中更多的是使用两个子接口:1. List(允许重复) 2. Set(不允许重复)

        1.2List接口

        在进行单个集合处理时,优先考虑List接口,是允许数据重复的。

        List接口若想保存自定义类的对象,该类必须覆写equals()才能使用contains()、remove()。
        所以使用List接口一定得覆写equals()方法。

        List接口除了实现Collection接口的方法,还有自己独有的方法。

        public E get(int index) //根据索引获取数据
        public E set(int index,E element) //根据索引更新数据,返回原来数据
        
        • 1
        • 2

        List中有三个常用的子类,值得去深究它们之间的区别和底层实现。
        1.ArrayList 2.Vector 3.LinkedList 都继承抽象类 AbstractList< E>抽象类

        重点重点重点重点

        • 问题1:ArrayList和Vector区别

        共同点:底层都是用数组实现存储对象
        区别:

        1. 版本
          ArrayList JDK1.2。Vector JDK1.0:在类集出现之前,都是直接继承这个类。
        2. 初始化策略
          Vector在无参构造执行后将对象数组大小初始化为10.
          ArrayList在构造阶段并不初始化对象数组,在第一次添加元素时才初始化数组。-懒加载策略
          创建大小minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
          DEFAULT_CAPACITY大小为10
        3. 扩容策略:
          Vector:2倍(根据操作系统不同而不同)
          int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
          ArrayList:1.5倍
          int newCapacity = oldCapacity + (oldCapacity >> 1);
        4. 线程处理:
          Vector: 方法上加锁,线程安全,效率较低。 synchronized
          ArrayList: 异步处理,线程不安全,效率较高。
          (即便要用线程安全的List,也不用Vector)
        5. 遍历:
          Vector: 支持较老的迭代器Enumeration
          ArrayList:不支持
        • 问题2:ArrayList和LinkedList区别

        共同点:都没有加锁操作,异步处理。
        区别:

        1. 底层实现:
          ArrayList:使用数组
          LinkedList:使用链表

        1.3 Set接口

        不允许数据重复!!

        没有扩充方法,直接覆写collection的抽象方法。

        • 有两个很重要的子类:
        1. HashSet ||无序存储
          实际上就是HashMap 的Key值+一个静态的null对象
          底层使用哈希表+红黑树
          允许存放null
        2. TreeSet ||有序存储
          底层使用红黑树
          不允许存放null
          :因为是有序存储,所以自定义类要想保存到TreeSet中
          必须①实现Comparable接口
          或者②向TreeSet中传入比较器(Compartor接口)
          实现比较标准,才能实现TreeSet中部分方法。
        • 问题1:说到了Comparable和Compartor接口,那就简单比较区分一下:

        它们的目的和作用都是一样的,在Java中实现自定义类的比较。
        多用于TreeSet和TreeMap。

        但是使用方法上和功能实现上都是完全不一样的。

        实现java.lang.Comparable(1.2)接口,就说明该类支持排序。
        存放该类的collection或者数组可以通过collections.sort()进行排序。可以直接存放在TreeSet中。
        接口内就一个int ComparTo(T o)方法,覆写这个方法,就是告诉怎么去比较。在类内实现排序。
        称之为 类内比较器。

        第三方实现java.util.Comparator (1.5)接口,是需要比较的类本身不支持排序,就可以外部建立一个该类的"比较器"来进行排序。这个外部比较器实现Compartor接口即可。
        接口中有个compare(T t,E e)方法。创建一个类在类外实现排序。必须实现equals
        称之为 外部比较器。
        -策略模式,更加灵活,可以轻松改变策略进行第三方排序。

        • 问题2:既然知道了TreeXXX自定义类的比较方法,那么同样在意顺序的HashXXX怎么比较对象顺序呢?

        这就得引出一个HashCode概念,这是通过哈希算法散列得来的。哈希表中的概念。
        要判断大小就得同时覆写HashCode()和equals()两个方法。
        必须hashCode和equals都返回ture才是相等。
        equals比较的是元素的内容,HashCode比较的是元素存储的经过hash转化的地址。

        equals相同,hashcode一定保证相同
        hashcode相同,equals不一定相同

        这里又引入了一个问题,问题3:哈希碰撞,~~~
        把任意长度的字符串变成固定长度的字符串,所以必有一个输出串对应无穷多个输入串,碰撞是必然存在的。
        解决方法在这里就简单一提,
        1.开放定址法,也就是一直为冲突的元素找新地址
        2.再哈希法,就是同时构造多个hash函数,冲突就换函数
        3.链地址法,把冲突的元素放进一个链表中
        4.建立公共溢出区,将冲突的元素统一放入另一个区域

        • 问题4:那为什么非要在乎比较对象大小这个概念?

        因为Set是不可重复的,那既然不可重复就得规定一个标准,让计算机知道怎么样才能算相等,就像定义了一个学生信息表,你就得规定姓名和学号完全一样才算相等。
        还有就是TreeXXX在意的是对象的自然排序,所以必须要定义这个比较"准则"。

        2. Collections工具类


        • 常用子类
        1. 将线程不安全集合包装成线程安全集合(不推荐)
          推荐使用juc包下的并发集合类(ConcurrentHashMap、CopyOnWriteArrayList)
          eg:把ArrayList变的安全
          内部实现就是在方法内部使用 线程安全同步代码块,效率较低
          synchronizedList(list)
        2. 向集合中一次加入多个元素
          addAll()
        3. 集合反转
          reverse()
        4. 集合排序
          sort()

        写到这里,Collection接口和Map接口的特点、实现以及它们的常用子类的特点、区别、适用都已经有个大概了解和区分了。

  • 相关阅读:
    MySQL递归查询树状表的子节点、父节点
    ajax传递参数给springmvc总结[转]
    转:Java中String与byte[]的转换
    easymock的用法
    java的反射
    spring的依赖注入
    等页面加载完
    ajax请求
    对象的复制
    springJDBC
  • 原文地址:https://www.cnblogs.com/renjiaqi/p/14073206.html
Copyright © 2020-2023  润新知