【LIst、Set】

今日内容
    数据结构
    List子体系
    Set子体系
    Collections工具类


集合体系
    Collection(单列集合)
        |-List:存取有序,有索引,可以存储重复元素
            |-ArrayList:数组结构
            |-Vector:数组结构
            |-LinkedList:链表结构
        |-Set:存取无序,无索引,不能存储重复元素
            |-HashSet:哈希表结构
                |-LinkedHashSet:链表哈希表结构
            |-TreeSet:二叉树结构


    Map(双列集合)


数据结构
    栈
        一端开口一端封闭

        压栈:进栈或者入栈
        弹栈:出栈

        特点:先进后出
             后进先出

        举例:
            子弹弹夹
            超市货架
            内存图中的方法进栈出栈

    队列
        两端开口

        特点:先进先出

        举例:
            火车过山洞
            排队

    数组
        特点:查询快,增删慢

        查询快:数组中有连续的索引,查询的时候直接根据索引找到
        增删慢:由于数组长度固定,如果要添加或者删除某个元素,必须新建一个数组,然后再将
               原数组中的元素复制到新数组中

    链表
        特点:查询慢,增删快

        查询慢:地址不是连续的,必须从头往里一个个开始查找
        增删快:增删不会影响链表的整体结构,增删时只要改变节点记录的下一个节点

    红黑树
        是二叉树中的一种

        特点:查询快 排序

List集合
    List是一个接口,它继承了Collection接口,所以Collection接口中定义的功能方法在List中都能使用
    由于List的特点不一样,比如有索引,所以List除了有共性的方法,还有其特有的方法

    都是和索引相关的方法:
    void add(int index, E element):将指定的元素添加到指定的索引位置
    E get(int index):获取指定索引处的元素
    E remove(int index):删除指定索引处的元素,并返回被删除的元素
    E set(int index, E element):修改指定索引处的元素

    ArrayList
        底层是数组数据结构,查询快,增删慢

        如果是增删比较多的时候,不选择ArrayList,选LinkedList,否则就选择ArrayList

    LinkedList
        底层是链表结构,查询慢,增删快

        特有方法:
            public void addFirst(E e):添加到第一个位置           add(0,e)
            public void addLast(E e):添加到最后一个位置          add(list.size(),e)
            public void push(E e):相当于addFirst

            public E getFirst();                                get(0)
            public E getLast();                                 get(list.size()-1)

            public E removeFirst();                             remove(0)
            public E removeLast();                              remove(list.size()-1)
            public E pop();

    Vector
        底层是数组结构,出现的版本JDK1.0,集合体系(框架)是JDK1.2出现

        面试题:ArrayList和Vector的区别?
            ArrayList的出现替代了Vector,Vector和ArrayList大致相同,ArrayList做了两点改进:
            (1)方法的名称进行规范和简化
                   void addElement(E obj)  ->boolean add(E e)
                   elements() ->iterator()
                   E elementAt(int index)  ->E get(int index)

            (2)效率提高了
                Vector是同步的,多线程下安全,加了同步锁,加锁之后每次执行需要判断锁,效率低
                ArrayList是不同步的,多线程下不安全,没有加同步锁,不需要判断锁,效率高


        面试题:迭代器与(Iterator)枚举(Enumeration)的区别?
            迭代器与(Iterator)枚举(Enumeration)有两点不同:

            (1)迭代器可以移除 collection 中的元素,而枚举没有提供移除(remove)的功能。
            (2)方法名称得到了改进。
                boolean hasMoreElements()  ->   boolean hasNext()
                E nextElement()           ->    E next()

Set集合
    Set接口中的方法和Collection中的完全一样,没有特有方法,不用单独学习了

    Set的特点:
        (1)不保证有序
        (2)无索引,不能操作所有和索引相关的方法
        (3)不能存储重复元素

        Set虽然不保证有序,但是遍历出来的结果是固定的
    HashSet
        // 创建HashSet集合对象
        // 添加元素,使用add方法
        // 遍历,使用迭代器和增强for


    哈希值
        哈希值就是一个十进制的整数

        通过hashCode方法可以得到哈希值
        如果没有重写Object类中的hashCode方法,可以反映对象的内存地址值
        如果重写了Object类中的hashCode方法,就不能反映对象的内存地址值

        不同的对象哈希值不一般不同,也有可能相同,但是相同对象的哈希值一定相同

        哈希值相同,说明一定是同一个对象吗?  不一定
        哈希值不同,说明一定是不同对象吗?    一定


    HashSet集合不能存储重复元素的原理
        HashSet底层添加方法(add)依赖的是hashCode和equals方法
        首先调用的是hashCode计算哈希值,比较集合中的元素是否和该哈希值相同,
        如果哈希不同直接认为是不同元素,进行存储,这时不需要调用equals方法。
        如果哈希值相同,此时就需要继续借助equals方法来判断,比较的是内容
        如果equals比较的结果为true,则认为是相同元素,不存储
        如果equals比较的结果为false,则认为是不同的元素,存储


        hashCode粗过滤,它存在意义就是为了减少equals的执行次数,hashCode重写的原则是让不同的成员变量的对象哈希值尽量不同
        equals完全过滤,重写比较其中的内容

        结论:HashSet存储自定义对象,如果想保证去重,必须重写hashCode和equals方法
              重写使用快捷键:alt+insert 选择hashCode和equals


        课堂练习:
            使用HashSet存储Student自定义对象,有四个Student对象分别是:
            向问天,20
            叶良辰,18
            李天一,16
            叶良辰,18
            我们认为姓名和年龄相同的学生为同一个学生,希望对是同一个的学生进行去重。


    LinkedHashSet
        是HashSet的子类,HashSet中的方法它都能使用
        特点:
            (1)有序(保证怎么存就怎么取)
            (2)无索引
            (3)不能存储重复元素

        该集合除了有序之外,其余的都和父类HashSet一样

        课堂练习:
            定义一个集合,存储一些列字符串:"hello","world","php","hello","hello","java"
            要求去除重复的字符串,并且保证元素取出的顺序和存储的顺序一致

            选择LinkedHashSet集合

Collections工具类

    可变参数
        JDK1.5的新特性(自动拆装箱、泛型、增强for、可变参数、枚举)

        格式:
            数据类型... 变量名

        使用的位置
            只能在方法的小括号中,当作方法的形式参数使用

            修饰符 返回值类型 方法名(数据类型... 变量名){
            }

        可变参数本质
            它是一个数组

        使用场景
            当参数的类型确定,但是传递的个数不确定的时候

            当参数的类型不确定,传递的个数也不确定就可以使用终极版本:Object... 变量名


    两种排序方式:
        自然排序(Comparable接口)
            (1)要进行排序的对象所在的类必须实现该接口
            (2)实现int compareTo(T o)  方法,定义比较的规则
        比较器排序(Comparator接口)
            (1)创建一个比较器对象[使用匿名内部类创建对象,自定义一个实现类]
            (2)实现int compare(T o1, T o2)  方法,定义比较的规则
            (3)当做参数传递到需要比较器的方法中,比如:
                static <T> void  sort(List<T> list, Comparator<? super T> c)
                其中第二个参数传递的就是比较器对象

        以上两种方式都可以定义比较的规则
            (1)如果是JDK提供的类,比如Integer、String,已经实现了第一种自然排序(Comparable接口)方法,按升序排
                如果不想要第一种排序方式默认的排序规则,我们就可以再使用第二种排序方式对第一排序方式的规则进行覆盖
            (2)如果是自定义的类,没有定义排序的规则,以上两种排序方式我们都可以选择

            如果两种排序方式都存在的情况下,优先使用第二种的排序规则


 

猜你喜欢

转载自blog.csdn.net/L531003231/article/details/81748041