• 7.31


    Map

    HashMap:作为Map的主要实现类,效率高,可以存储null;数组+链表(1.7以前) 数组+链表+红黑树(1.8)

    LinkedHashMap:保证遍历map元素时,可以按照添加的顺序实现遍历。

    原因:在原有map的基础上,添加了一对指针,指向前一个和后一个。

    TreeMap:保证按照添加的K-V对进行排序,实现排序遍历。此时使用key进行排序。

    底层使用红黑树。

    Hashtable:作为古老的实现类;线程安全,效率低;不能存储null的key和value

    Properties:常用来处理配置文件

    Map中的

    key:无序的、不可重复的,使用Set存储所有的entry; ---> key所在类需要重写equals()和HashCode();

    value:无序的,可重复的,使用Collection存储所有的value; 需要重写equals()方法;

    一个键值对:构成一个Entry对象

    Map中的entry:无序的、不可重复的,使用Set存储所有的entry

    源码分析(HashMap)

    jdk7

    • 在实例化以后,底层创建了长度是16的一维数组 Entry[] table ;

    • map.put(key1,value1);

      • 首先调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。如果此位置上的数据为空,此时的key1-value1添加成功

      • 如果此位置上的数据不为空,比较key1和已经存在的一个或多个数组的哈希值:如果key1的哈希值与已经存在的数组的哈希值都不相同,此时key1-value1添加成功;如果存在相同的,继续比较:调用key1所在类的equals()方法;如果false,添加成功;如果true,使用value1替换value2;

      • 默认的扩容方式;扩容为原来容量的2倍,并将原有的数据复制过来。扩容的时候,会重新算一次hash值。

    • 默认加载因子:0.75;当添加的时候达到了0.75,但新的key对应没有形成链表,也是直接加进去的。

    jdk8

    • new HashMap(); 底层没有创建一个长度为16的Node[] 数组

    • 首次调用put方法时,底层创建长度为16的数组

    • 当数组的某一个索引位置上的元素以链表形式存在的数据个数 >8 且当前数组的长度 > 64时,此时此索引位置上的所有数据改为使用红黑树存储。

    需要关心的几个值

    • DEFAULT_INITIAL_CAPACITY: HashMap 的默认容量 :16

    • DEFAULT_LOAD_FACTOR: HashMap 的默认加载因子 : 0.75

    • threshold: 扩容的临界值 = 容量*填充因子

    • TREEIFY_THRESHOLD:Bucket 中链表长度大于该默认值,转化为红黑树:8

    • MIN_TREEIFY_CAPACITY: 桶中的Node被树化时最小的hash表容量:64

    LinkedHashMap的底层实现原理:

    继承于HashMap ,区别:其内部提供了Entry,替换HashMap中的Node

    Collections

    • reverse();// 反转list

    • shuffle();// 随机排序

    • 如果程序要求线程安全,可以使用Collections将ArrayList和Map转化为线程安全的

    泛型

    在指明完以后,在接口类或接口中凡是定义类或接口时,内部结构(比如:方法、构造器、属性),在实例化以后,都会变成具体的泛型类型。比如 add(E e) -- > 实例化以后: add(Integer e) ;

    泛型的类型必须是类,不能是基本数据类型。需要用到基本数据类型的位置,需要使用包装类来替换。

    自定义泛型

    泛型类、泛型接口

    如果子类在继承带泛型的父类时,指明了泛型类型,则实例化子类对象时,不需要指明泛型。

    泛型类可能有多个参数;

    构造器是不带泛型的:public GenericClass(){};

    在编译的时候,只会有一个ArrayList被加载到JVM中,即使是有两种不同泛型的ArrayList

    泛型的不同引用不能相互赋值。

    在静态结构中不嫩更实用类的泛型。类的泛型是在实例化的时候才有。

    异常类不能声明为泛型类

    1. // T:type  K:key V:value
    2. public class Order<T>{
    3.    T orderT ; // 当成一个数据结构
    4.    public Order(T orderT) {
    5.       this.orderT = orderT;
    6.    }
    7.    // 编译不通过
    8.  //  T[] arr = new T[10];
    9.    T[] arr = (T[]) new Object[10];
    10.    
    11. }

     

    泛型方法

    在方法中出现了泛型结构,泛型参数与类的泛型参数没有任何关系。泛型方法所属的类是不是泛型类都没有关系

    泛型方法,可以声明为静态的。原因:泛型参数是在调用方法时确定的。并非在实例化类时确定。

    1. // 需要去告诉编译器,这个E是泛型的
    2. public List test1(E[] arr) {
    3.    
    4. }

    在继承关系的体现

    类A是类B的父类,但在泛型中是属于并列的结构。

    补充:类A是类B的父类,A 是 B的父类

    通配符

    添加:对于List就不能向其内部添加数据

    获取:允许读取数据,读取的数据类型为Object

    有限制条件的通配符的使用:

    1. ? extends A:
    2.    GA> 可以作为G<A>和G<B>的父类,其中B是A的子类
    3. ? super A:
    4.    GA> 可以作为G<A>和G<B>的父类,其中B是A的父类    

    IO流

    file

    三个构造器

    1. public void test1() {
    2.    //构造器1
    3.    new File(String pathname);// 指定路径
    4.    new File(String parent,String child);// child可以是一个目录
    5.    new File(File file ,String child);// file目录下的文件或目录
    6. }

    获取功能

    1. public String getAbsolutePath() ; // 获取绝对路径
    2. public String getPath(); // 获取路径
    3. public String getName();//获取名称
    4. public String getParent();//获取上层文件目录路径
    5. public long length() ; // 获取文件长度(字节数),不能获取目录的长度
    6. public long lastModified(); // 获取最后一次的修改时间,毫秒值
    7. public String[] list() ; //获取指定目录下的所有文件或文件目录的名称数组
    8. public File[] listFiles() ; // 获取指定目录下的所有文件或文件目录的File数组
    9. public boolean renameTo(File dest); // 把文件重命名为指定的文件路径,相当于移动+命名,如果已存在有相同命令的,则会失败
    10. public boolean isDirectory(); // 判断是否是文件目录
    11. public boolean isFile(); // 是否是文件
    12. public boolean exists(); // 判断是否存在
    13. public boolean canRead();
    14. public boolean canWrite();
    15. public boolean isHidden();
    16. public boolean createNewFile(); // 创建文件或文件目录
    17. public boolean mkdir();// 创建文件目录。如果此文件目录的上层目录不存在,不会创建
    18. public boolean mkdirs();// 创建文件目录,如果上层目录不存在,一并创建
    19. public boolean delete() ;// 不走回收站

    按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)

    按流角色的不同分为:节点流,处理流

     

    new FileWriter(String pathname,boolean append); // true 追加 false 覆盖

    对于文本文件,使用字符流处理;对于非文本文件,使用字节流处理。

    关闭流:关闭外层流的同时,内层流也会被关闭

     

    转换流

     

    1. 转换流:属于字符流

    InputStreamReader :  将一个字节的输入流转换为字符的输入流

    OutputStreamWriter : 将一个字符的输出流转化为字节的输出流

    1. 作用:提供字节流与字符流之间的转换

    2. 解码:字节、字节数组 --> 字符数组、字符串

    编码:字符数组、字符串 --> 字节、字节数组

  • 相关阅读:
    Android11系统桌面隐藏指定APP图标
    体验不尽,进化不止,看视频云技术六大创新
    算法基础:栈和队列
    Android学习之路(18) 数据存储与访问
    软考系列(系统架构师)- 2021年系统架构师软考案例分析考点
    BI业务分析思维:生产制造供应链订单交付优化分析三种方式
    成长杂志成长杂志社成长编辑部2022年第7期目录
    2023-CSPJ 题解
    KafkaConsumer 消费逻辑
    Uni-ControlNet: All-in-One Control toText-to-Image Diffusion Models——【论文笔记】
  • 原文地址:https://blog.csdn.net/weixin_53043125/article/details/126082192