javase

javase

[TOC]

类加载初始化

  • 类初始化过程
  • 实例初始化过程
  • 方法的重写

输出结果: ==1.(5) (1) 2.(10) (6) 3.(9) (3) (2) 4.(9) (8) (7) 3.(9) (3) (2) 4.(9) (8) (7)==

初始化顺序:

  • 父类静态变量,静态代码块 1.

  • 子类静态变量,静态代码块 2.

  • 父类实例变量,代码块,==构造方法== 3.
  • 子类实例变量,代码块,构造方法 4.
  • 静态方法不可重写.
  • 子类实例引用父类方法调用指向子类实例方法
public class Father {
    private int i=test();
    public static int j=method();

    static {
        System.out.println("(1)");
    }
    public Father() {
        System.out.println("(2)");
    }
    {
        System.out.println("(3)");
    }

    public int test() {
        System.out.println("(4)");
        return 1;
    }

    public int method() {
        System.out.println("(5)");
        return 1;
    }
}


class Son extends Father {
    private int i=test();
    public static int j=method();

    static {
        System.out.println("(6)");
    }
    public Son() {
        System.out.println("(7)");
    }
    {
        System.out.println("(8)");
    }

    public int test() {
        System.out.println("(9)");
        return 1;
    }

    public static int method() {
        System.out.println("(10)");
        return 1;
    }

    public static void main(String[] args) {
        Son son = new Son();
        System.out.println(" ");
        Son son1 = new Son();

    }
}

参数传递机制

  • 方法函数的传参机制
  • 不可变类型传参赋值
    • 不可变类型:string 包装类
1593778717(1).jpg

线程

六种状态(jdk1.8之后)

  • new(初始化)
  • runnable(可运行/运行状态)
  • blocked(阻塞状态)
  • waiting(无显示等待状态)
  • time_waiting(有限时等待状态)
  • terminated(终止状态)

源码

包装类

integer类

  • integer类缓存:默认缓存 -128 - 127,当采用

    Integer i = x;//x为具体的整数
    
    Integer o = new Integer(2);//此时不会指向缓存中的数
    

    并且x的值 -128<=x<=127 时,将变量 i 指向缓存中的已存在的integer对象,否则用new关键字开辟新空间并填入数值

  • 自动拆箱封箱

    Integer i1 = 40;
    Integer i2 = 40;
    Integer i3 = 0;
    Integer i4 = new Integer(40);
    Integer i5 = new Integer(40);
    Integer i6 = new Integer(0);
    
    System.out.println(i1 == i2);//true,调用了常量池
    System.out.println(i1 == i2 + i3);//true,操作会导致左右两边都转成基本数据类型
    System.out.println(i1 == i4);//false,常量池与新创建对象
    
    System.out.println(i4 == i5);//false,创建的不同对象
    
    System.out.println(i4 == i5 + i6);//true,包装类遇到运算符自动拆箱,比较的是值
    System.out.println(40 == i5 + i6);//true,同上
    

String类

  • string类底层使用的是final byte[] 数组,不可修改

String

  • 字符串拼接原理:运行时,两个字符串str1,str2的拼接首先会调用 String.valueOf(obj),

    这个Obj为str1,而String.valueOf(Obj)中的实现是return obj == null ? “null” : obj.toString(),

    然后产生StringBuilder, 调用的StringBuilder(str1)构造方法, 把StringBuilder初始化,

    长度为str1.length()+16,并且调用append(str1)! 接下来调用StringBuilder.append(str2),

    把第二个字符串拼接进去, 然后调用StringBuilder.toString返回结果!

    ==所以答案就是:==StringBuilder("a").append("b").toString();

    实际代码
    public class aaa {
      public static void main(String[] args) {
          String a = "abc";
          a = a + "d";
      }
    } 
    
    编译器之后的等效代码:
    public class aaa {
      public static void main(String[] args) {
          String a = "abc";
          StringBuilder temp = new StringBuilder(a);
          //temp.length=a.length+16
          temp.append("d");
          a = temp.toString();
      }
    }
    

StringBulider

StringBuffer

Collection接口

  • ==只能存放引用类型==,传入的数字会自动包装为包装类

List接口

  • 有序的,可重复

ArrayList类

  • 新建空数组时指向默认空=={}==这个东西,其容量为0,当存入数据时再开辟一个容量为10的数组
  • 非空情况默认初始化容量为==10==,当传入第11个时,新建一个容量为当前的==容量1.5倍的数组==,然后将原数组用System.arraycopy()函数复制过去.
  • arraylist最大容量为==(2^31)-1== 2147483647
  • timsort排序?????
  • 数据量小于32时使用插入排序
  • 大于32时合并排序

LinkedList

  • node<E>节点为双向链表
  • get(int index) 会判断index参数的大小,小于==size>>1==即(二分之一size)时从从头节点开始正序遍历获取节点,否则从尾节点开始倒序遍历获取节点
  • contains() 调用==indexof()==方法,顺序遍历节点,支持查询是否有null

vector

  • 数组实现
  • ==线程安全的==

Set接口

  • 不可重复性

HashSet

  • 不保证有序

TreeSet

  • 内部实现排序,也可以自定义排序规则

Map接口

HashMap

基于==数组+链表+红黑树==实现,

==精读源码==:https://m.toutiaocdn.com/group/6727624027327693316/?app=news_article&timestamp=1566486530&req_id=201908222308490100210420968414325&group_id=6727624027327693316

相关概念https://blog.csdn.net/fan2012huan/article/details/51087722

hashmap结构.jpg
  • ==线程不安全的==

  • 允许key,value都为null值

  • ==约定==

    约定前面的数组结构的每一个格格称为桶
    约定桶后面存放的每一个数据称为bin

  • ==size==

    size表示HashMap中存放KV的数量(为链表和树中的KV的总和)。
  • ==capacity==

    capacity译为容量。capacity就是指HashMap中桶的数量。默认值为16。一般第一次扩容时会扩容到32,之后好像是2倍。总之,容量都是2的幂。

    /**
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
    
  • ==loadFactor==

loadFactor译为装载因子。装载因子用来衡量HashMap满的程度。loadFactor的默认值为0.75f。计算HashMap的实时装载因子的方法为:size/capacity,而不是占用桶的数量去除以capacity。

/**
 * The load factor used when none specified in constructor.
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;
  • ==threshold==

    threshold表示当HashMap的size大于threshold时会执行resize扩容操作。
    threshold=capacity*loadFactor

    /**
     * The next size value at which to resize (capacity * load factor).
     */
    int threshold;
    
  • ==负载因子越小,hash冲突率越低==(泊松分布?)

    hashmap的其他构造方法都通过调用以下构造方法实现

    initialCapacity:最好输入==2的N次幂==,如果不是,会自动转化为离这个数字最近的大于此数2的N次幂

    loadFactor:大-->效率降低, 小-->空间浪费

    public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
      throw new IllegalArgumentException("Illegal initial capacity: " +                initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
      initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
      throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
     
    this.loadFactor = loadFactor;
    this.threshold = initialCapacity;
    init();
    }
    

推荐阅读:https://blog.csdn.net/fan2012huan/article/details/51088211

链表结构

此处使用==capacity为2,loadfactor为7==来进行==演示==

  • 当初始化capacity为2,loadfactor为7时,计算的临界值为==2*7=14==,

  • 未存入任何数据时,数组为空,存入第一个数据时,将==桶数设置为2,临界值设置为2*7==

  • 当存入的数据小于14时,所有数据只会存在与数组的==0或1索引==下,当存入的数据达到==15==个时,开始扩容,将容量扩为原来==2常量==倍即==4==,将新临界值赋值为 ==新容量负载因子定公式==即47

    以上注意赋值公式和顺序

    newCap = oldCap << 1 //新容量为旧容量的两倍,本代码为简化结果
    if (newCap < 1<<30 && oldCap >= 16)
        newThr = oldThr << 1;//新临界值为旧的两倍
    
  • 然后新建一个容量为4的数组,将原来的数组的内容复制过去

  • 默认形成树的值==TREEIFY_THRESHOLD==为8常量.

  • 当某个索引下的==bin个数达到第9==个时,并且总的==桶数小于64常量==,将会扩容.

  • 当某个索引下的==bin个数达到第9==个时,并且总的==桶数大于64常量==,将会形成树结构

==树结构==

推荐链接:https://www.jianshu.com/p/cd6813739cd2

  • 难受
扩容--链表
  • 遍历原数组各索引,当索引内容不为空,判断该索引下是否只有一个bin.是则直接计算该元素在新数组下的新索引,公式==(newTab[e.hash & (newCap - 1)] = e;)==.
  • 不只一个时,判断是否为树结点,是==见下个标题==
  • 当旧数组索引下为链表时,准备两个新链表,==低位链表和高位链表==
  • 由于桶数扩容两倍,一个链表中的数据会放在与原数组相同的索引下,这个为==低位链表==
  • 另一个链表放在==(原索引+旧数组容量)==即==(j + oldCap)==,这个为==高位链表==
  • 遍历该旧链表的bin,计算==((e.hash & oldCap) == 0)==时,放入低位链表,==否则==放入高位链表
    • ((e.hash & oldCap) == 0)的优点:
    • 举个例子:n = 16,二进制为10000,第5位为1,e.hash & oldCap 是否等于0就取决于e.hash第5 位是0还是1,这就相当于有50%的概率放在新hash表低位,50%的概率放在新hash表高位。
扩容--树
  • 难受

linkedhashmap

treemap

hashtable

  • 父类为dictionary

  • ==线程安全的==

  • 不允许null值

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容