String-hashcode疑问

今天闲来没事看String的源码,在看到hashCode方法里的实现,总感觉有点问题,以前就是看看了实现并没有太在意效率,下面就是StringhashCode方法代码。h = 31 * h + val[i]要执行n次,时间复杂度为O(n)。时间复杂度上我们不能减少,但是为什么不把h = 31 * h + val[i]用位运算代替呢。比如:

int tmp = val[i] - h;
h <<= 5;
h += tmp;

本来以为可能是三行代码会导致代码的效率反而降低,但是通过测试后发现,位运算效率还是比较高些
下面是jdkStringhashCode源码:

public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

为了进行检验,编写下面的程序,初步估计等下面程序跑完,已经是我毕业了,所以放到服务器上去跑了,等我毕业再来重写这篇文章吧

import java.time.Duration;
import java.time.Instant;
import java.util.Random;

public class Main {
    public static void main(String[] args) {
        int one = 0;
        int two = 0;
        int balance = 0;
        System.out.println("开始计算");
        for (int i = 1; i < Integer.MAX_VALUE; i++) {
            int c = new Random().nextInt(128);
            int result = compareTest(i, (char) c);
            if (result == 0)
                balance++;
            else if (result < 0)
                one++;
            else
                two++;
        }
        System.out.printf("one耗时少的次数:%d\ntwo耗时少的次数:%d\nbalance平衡次数:%d", one, two, balance);
    }

    private static int compareTest(int n, char c) {
        Instant start01 = Instant.now();
        int oneTime = testOne(n, c);
        Instant end01 = Instant.now();
        int nano01 = Duration.between(end01, start01).getNano();

        Instant start02 = Instant.now();
        int twoTime = testTwo(n, c);
        Instant end02 = Instant.now();
        int nano02 = Duration.between(end02, start02).getNano();
        if (oneTime != twoTime) {
            throw new RuntimeException("当前n=" + n + ",c=" + c + ",oneTime=" + oneTime + ",twoTime=" + twoTime);
        }
        return nano01 - nano02;
    }

    private static int testOne(int n, char c) {
        char[] val = {c};
        int h = 0;
        for (int i = 0; i < n; i++) {
            h = h * 31 + val[0];
        }
        return h;
    }

    private static int testTwo(int n, char c) {
        char[] val = {c};
        int h = 0;
        for (int i = 0; i < n; i++) {
            int tmp = val[0] - h;
            h <<= 5;
            h += tmp;
        }
        return h;
    }
}

如果有大神知道,还望指导一二。

你可能感兴趣的:(String-hashcode疑问)