目录
1.String、StringBufer、StringBuilder
1.2 StringBuffer、StringBuilder
2. Interface and abstract class
框架学再多,基础甚至底层都不会有什么用哟。面试的时候就只能说我会用框架,一问理论、底层就懵逼了。原来我只是会用,仅仅会用。自学了那么多框架,结果面试都过不了。多么嘲讽的。大学刚毕业的那时候,没有人告诉你需要做什么?虽然之前在某公司IT部独立负责三个项目的二次开发,依旧没能遇到引路人。就这样当条咸鱼,偶尔学学框架敲敲代码,甚至连BAT也没有想过。没有一点点的挣扎就随便选了一家公司然后开始了。
现在想来甚是后悔,就应该在大一的时候开始想要做什么?要学什么?要去哪里?然后开始准备了。
那就从现在开始,开始复习开始刷题吧!希望一年后能遇到更好的自己。
1.String、StringBufer、StringBuilder
String是只读字符串,典型的Immutable对象,对它的任何改动。起手都是创建一个新对象,再把引用指向该对象。String对象赋值操作后,会在常量池中进行缓存。如果下次引用的时候,该对象已经存在就会直接调用缓存池中。StringBuffer则是可以在原对象上进行修改,是线程安全的。StringBuffer和StringBuilder都是继承了AbstractStringBuilder。该抽象类也是以字符数组的形式存储字符串。StringBuilder线程不安全,但是效率比StringBuffer高。
1.1 String
String对象是不可变,也是不可继承的。如下源码中String是被final所修饰的。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Omit resource code …… . */
}
String 为不可变对象,一旦被创建,就不能修改它的值. . 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
String中的对象是不可变的,也就可以理解为常量, 显然线程安全 。
1.2 StringBuffer、StringBuilder
StringBuffer、StringBuilder都是继承AbstractStringBuilder类。
在AbStaractStringBuiler中使用字符数组保存字符串。可知这两种对象都是可变的。
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
/** Omit resource code …… . */
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
/** --------StringBuffer Resource code-------------- */
public StringBuffer(int capacity) {
super(capacity);
}
public StringBuffer() {
super(16);
}
StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立, 如: StringBuffer sb = new StringBuffer();
不能通过赋值符号对他进行付值. , 如 sb = "welcome to here!";//error
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法. sb.append("hello");
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
/** --------StringBuffer Resource code-------------- */
@Override
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return value.length;
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
/** --------Omit Resource code-------------- */
StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
使用场景:1. 操作少量数据: String 2. 操作大量数据、单线程: StringBuilder 3. 操作大量数据、多线程: StringBuffer
1.3 Efficiency
如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。
效率比较String < StringBuffer < StringBuilder,但是在String S1 =“This is only a”+“simple”+“test”时,String效率最高。
2. Interface and abstract class
参考CSDN文档:https://blog.csdn.net/aptentity/article/details/68942916
参考CSDN文档:https://blog.csdn.net/Speed_Pig/article/details/71628368?locationNum=3&fps=1(1.8特性)
类型 | abstract class | interface |
定义 | abstract class 关键词 | Interface关键字 |
继承 | 抽象类可以继承一个类或者实现多个接口。子类只能实现一个抽象类 | 接口类只可以继承接口(一个或者多个)。子类可以实现多个接口 |
访问修饰符 | 抽象方法可以有public、protected和default这些修饰符 JDK1.8以前 抽象类的方法默认访问权限为protected,JDK1.8后,默认访问权限变为default. | 接口方法默认修饰符是public abstract。你不可以使用其它修饰符。1.8版本允许定义static 、default 接口中的变量隐式声明为public static final |
方法实现 | 可以定义构造方法,抽象方法,具体方法 | 接口完全抽象,没有方法体。1.8后允许在接口里面定义default,static方法体 |
实现方式 | 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的抽象方法的实现,可以选择所需的非抽象方法的实现。通过super去调用抽象类中的方法参数。 | 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现 |
作用 | 把相同的东西提取出来,即重用 | 为了把程序模块进行固化的契约,是为了降低偶合 |
3. 运算符
3.1. 移位运算符
用最有效率的方式计算2乘以8
2 〈〈 3
常见的JDK源码里面HashMap默认容量 16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 = 1 * 2^4
直接二进制操作,表示1 左移4位,低位补0,即10000转化二进制位16。
在代码编写中,尽量使用移位运算符。虽然 DEFAULT_INITIAL_CAPACITY =16可能更直观!
栗子:
<< :左移运算符,num<< 1,不区分正负数,低位补0,相当于num*2
4 << 1 // aka 4 * 2^1 = 8
5<< 4 // aka 5 * 2^4 = 64
>> :右移运算符,num>>1,如果该数为正,则高位补0,若为负数,则高位补1
64 >> 1 // aka 64 / 2 32
64 >> 2 // aka 64 / ( 2 ^ 2) 16
4. List
4.1. ArrayList的扩容机制
注意:JDK1.7之前ArrayList默认大小是10,JDK1.7后是0
未指定集合容器,默认为0。若已指定大小则为所指定集合大小。当集合第一次添加元素时候,集合大小扩容为10。ArrayList的元素个数大于其容器,扩容的大小 = 原始大小 + 原始大小/2
首先认识ArrayList的重要变量:
数组每次新增时候,都会使用ensureCapacityInternal确保数组容量,使用该方法进行容量判断。之后将新增的元素添加到数组中,size++。
ensureCapacityInternal将判断委托给calculateCapacity获取当前容器所需最小的容量。(一般我写代码都是用放一起然后接收,再传参给下个函数,没有多处使用,这样想来一点都不好。要抽出公共代码模块)
扩容的实现方法grow方法: