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 包装类

线程
六种状态(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://blog.csdn.net/fan2012huan/article/details/51087722

==线程不安全的==
允许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值