java集合进阶篇上【完整版】

15-集合进阶上

单列集合顶层接口Collection

  • List系列集合:添加的元素是有序,可重复,有索引的
  • Set系列集合:添加的元素是无序,不重复,无索引的

java集合进阶篇上【完整版】_第1张图片

  • Collection是单列集合的祖宗接口,他的功能是全部单列集合都可以继承使用

java集合进阶篇上【完整版】_第2张图片

迭代器

java集合进阶篇上【完整版】_第3张图片

package io.xiaoduo.arrayListForward;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Test2 {
    public static void main(String[] args) {
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        // 创建指针
        Iterator<String> it = coll.iterator();
        while (it.hasNext()) {
            String item = it.next();
            System.out.println(item);
        }
    }
}

细节注意点

  • 没有下一个报错NoSuchElementException
  • 迭代器遍历完毕,指针不会复位
  • 循环中只能用一次next方法
  • 迭代器遍历时,不能用集合的方法进行增加或者删除

增强for遍历

  • 增强for的底层就是迭代器,为了简化迭代器的代码书写
  • JDK5之后出现的,其内部原理就是一个Iterator迭代器
  • 所有的单列集合和数组才能用增强for进行遍历
  • 修改增强for中的变量不会改变集合中原本的数据

lambda表达式forEach遍历

  • js警告
list.forEach((s) -> { sout(s); });

List中的常见的方法和五种遍历方式

java集合进阶篇上【完整版】_第4张图片

  • List集合的遍历方式
    • 迭代器遍历
    • 列表迭代器遍历
    • 增强for遍历
    • Lambda表达式遍历
    • 普通for循环(因为List集合存在索引)
package io.xiaoduo.arrayListForward;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Test4 {
    public static void main(String[] args) {
        List<String> arr = new ArrayList<>();
        arr.add("aaa");
        arr.add("bbb");
        arr.add("ccc");

        Iterator<String> it = arr.iterator();
        while (it.hasNext()) {
            String str = it.next();
            System.out.println(str);
        }

        System.out.println("------");

        ListIterator<String> lit = arr.listIterator();
        while (lit.hasNext()) {
            String str = lit.next();
            System.out.println(str);
        }

        System.out.println("------");

        for (String s : arr) {
            System.out.println(s);
        }

        System.out.println("------");

        arr.forEach(item -> System.out.println(item));

        System.out.println("------");

        arr.forEach(System.out::println);

        System.out.println("------");

        for (int i = 0; i < arr.size(); i++) {
            String item = arr.get(i);
            System.out.println(item);
        }
    }
}

java集合进阶篇上【完整版】_第5张图片

数据结构

java集合进阶篇上【完整版】_第6张图片

队列

java集合进阶篇上【完整版】_第7张图片

数组

java集合进阶篇上【完整版】_第8张图片

链表

java集合进阶篇上【完整版】_第9张图片
java集合进阶篇上【完整版】_第10张图片

ArrayList底层原理

  1. 利用空参创建集合的时候,在底层创建一个长度为0的数组
  2. 添加第一个元素时,底层会创建一个新的长度为10的数组
  3. 存满时会扩容1.5倍
  4. 如果一次添加多个元素,1.5倍还放不下,则新创建数组的长度以实际为准

LinkedList集合

  • 底层数据结构是双向链表,查询慢,首尾操作的速度是极快的,所以多了很多首尾操作的特有api

java集合进阶篇上【完整版】_第11张图片

泛型深入

  • 泛型:是JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查
  • 泛型的格式:<数据类型>
  • 注意:泛型只能支持引用数据类型

泛型的好处

  • 统一数据类型
  • 把运行时期的问题提前到了编译阶段,避免了强制类型转换可能出现的异常,因为在编译阶段就能确定下来

泛型的细节

  • 泛型中不能写基本数据类型
  • 指定泛型的具体类型后,传递数据时,可以传入该类型或者其子类类型
  • 如果不写泛型,类型默认是Object

泛型可以在很多地方定义

类后面 泛型类
方法上面 泛型方法
接口后面 泛型接口

泛型类

  • 使用场景:当一个类中,某个变量的数据类型不确定时,就可以定义带有泛型的类

泛型方法

修饰符 <类型> 返回值类型 方法名(类型 变量名) {}
public <T> void fn(T t) {}

泛型接口

修饰符 interface 接口名<类型> {}
public interface List(T) {}

泛型的继承和通配符通配符

  • 泛型不具备继承性,泛型里面写的是什么类型,就只能传递什么类型的数据,但数据具备继承性
  • 泛型的通配符:?
    • ? extend E
    • ? super E

哪里定义泛型

  • 泛型类:在类名后面定义泛型,创建该类对象的时候,确定类型
  • 泛型方法:在修饰符后面定义泛型,调用该方法的时候,确定类型
  • 泛型接口:在接口后面定义泛型,实现类确定类型,实现类延续泛型

使用场景

  • 定义类,方法,接口的时候,如果类型不确定,就可以定义泛型
  • 如果类型不确定,但是能知道是哪个继承体系中的,可以使用泛型的通配符

数据结构

二叉树

java集合进阶篇上【完整版】_第12张图片

二叉查找树

java集合进阶篇上【完整版】_第13张图片

java集合进阶篇上【完整版】_第14张图片
java集合进阶篇上【完整版】_第15张图片
java集合进阶篇上【完整版】_第16张图片

java集合进阶篇上【完整版】_第17张图片

平衡二叉树

java集合进阶篇上【完整版】_第18张图片

红黑树

java集合进阶篇上【完整版】_第19张图片

Set集合

  1. Set系列集合的特点
    • 无序、不重复、无索引
    • Set集合的方法上基本与Collection的API一致
  2. Set集合的实现类特点
    • HashSet:无序、不重复、无索引
    • LinkedHashSet:有序、不重复、无索引
    • TreeSet:可排序、不重复、无索引
  3. HashSet底层原理
    • 创建一个默认长度16,默认加载为0.75的数组,数组名table
    • 根据元素的哈希值跟数组的长度计算尺应存入的位置
    • 判断当前位置是否为null,如果是null直接存入
    • 如果位置不为null,表示有元素,则调用equals方法比较属性值
    • 一样:不存;不一样:存入数组,形成链表
    • JDK8以前:新元素存入数组,老元素挂在新元素下面
    • JDK8以后:新元素直接挂在老元素下面
  4. LinkedHashSet集合的特点和原理是怎样的
    • 有序、不重复、无索引
    • 底层基于哈希表,使用双链表记录添加顺序
  5. 在以后如果要数据去重,我们使用哪个
    • 默认使用HashSet
    • 如果要求去重且存取有序,才使用LinkedHashSet
  6. TreeSet集合的特点是怎样的
    • 可排序、不重复、无索引
    • 底层基于红黑树实现排序,增删改查性能好
  7. TreeSet集合自定义排序规则有几种方式
    • 方式一:Javabean类实现Comparable接口,指定比较规则
    • 方式二:创建集合时,自定义Comparator比较器对象,指定比较规则
  8. 方法返回值的特点
    • 负数:表示当前要添加的元素是小的,存左边
    • 正数:表示当前要添加的元素是大的,存右边
    • 0:表示当前要添加的元素已存在,舍弃

总结

  1. 如果想要集合中的元素可重复
    • 用ArrayList集合,基于数组的(用的最多)
  2. 如果想要集合中的元素可重复,而且当前的增删操作明显多于查询
    • 用LinkedList集合,基于链表的
  3. 如果想对集合中的元素去重
    • 用HashSet集合,基于哈希表的(用的最多)
  4. 如果想要对集合中的元素去重,而且保证存取有序
    • 用LinkedHashSet集合,基于哈希表和双链表,效率低于HashSet
  5. 如果想要对集合中的元素进行排序
    • 用TreeSet集合,基于红黑树,后续也可以用List集合实现排序

你可能感兴趣的:(java,java,开发语言)