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疑问】如果有大神知道,还望指导一二。

    推荐阅读