jdk 源码精髓(持续更新)

巧用三目运算和逻辑运算符

String 类里的两个方法。(大家对比着看,体验一下如何巧用三目运算符)

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

精髓来了,用三目运算符和逻辑 && 巧妙的代替了多个 if 判断。没错,就是这么骚。

    public boolean equalsIgnoreCase(String anotherString) {
        return (this == anotherString) ? true
                : (anotherString != null)
                && (anotherString.value.length == value.length)
                && regionMatches(true, 0, anotherString, 0, value.length);
    }

巧用 !=

public class Demo {
    static int a;
    public static void main(String[] args) {
        int t= a;
        a=2;
        System.out.println(t!=(t=a));
        System.out.println(t);
    }
}

输出结果

true
2

t!=(t=a)

分析这行代码,a 是一个共享变量,这一句话话就干了两件事

  • 将 t 这个临时变量的值修改为 a 的最新值
  • 比较 a 这个共享变量有没有被修改

大大的缩短了代码量,对应的指令少了,性能自然也就高了。

巧用数组和范围查找

int 转成 String 的方法中用来判断某个整形的位数。

final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                  99999999, 999999999, Integer.MAX_VALUE };

// Requires positive x
static int stringSize(int x) {
    for (int i=0; ; i++)
        // 在 sizeTable 中找到第一个比 x 大的数,而此时这个数的索引+1 刚好是 x 的位数。不得不说,源码的设计之精巧。
        if (x <= sizeTable[i])
            return i+1;
}

1.空间局部性: sizeTable 为数组,存储在相邻的位置,CPU 一次加载一个块数据数据到 cache 中(多个数组数据),此后访问 sizeTable 不需要访问内存。

2.基于范围的查找,是很实用的设计技术

巧用移位

位移比乘法高效:

r = i – (( q << 6) + ( q << 5) + ( q << 2));
等价于
r = i – (q * 100);

乘法比除法高效:

q = ( i * 52429) >>> (16+3);
约等于q*0.1

注:乘法配合无符号移位可以代替除法

hashCode() 和 equals() 搭档干活

hashCode()

hashCode 是根据本地方法算出来的一个整型值,它可以代表你的对象 id(也就是唯一标识)。

hashCode 一般用于 hash 函数中。

equals()

equals() 这个方法本来是没有什么意义的,它需要你去重写超类 Object 的 equals(),从而来实现自己所需要表达的语义。

为了避免一些问题的出现,建议 hashCode() 和 equals() 一起重写,把它俩绑定在一起使用。

使用场景

hashMap
当 put 的元素 hashCode 一样时,也就是定位在同一个桶时,这个时候我们就需要 equals() 的帮助了。用 equals() 来解决 hash 冲突的情况。即当多个对象 hashCode 一样时,我们可以通过 equals() 来分辨它们。(当然这个的前提是你必须同时重写 hashCode() 和 equals())

泛型的使用

ArrayList<E> ,通过使用泛型,限制了加入的元素类型,从而可以在 get 的时候,安全的转型。

transient Object[] elementData; 

public E get(int index) {
        rangeCheck(index);

        return elementData(index);
}

E elementData(int index) {
        return (E) elementData[index];
}

参考博文 http://www.hollischuang.com/archives/1058

展开阅读全文

没有更多推荐了,返回首页