你是否也曾有过被c=a a=b b=c支配的恐惧

先看下面这段代码

c = a;
a = b;
b = c;

刚学编程那会儿,完全不知道这段代码到底在干嘛?!现在大家应该都能看懂这段代码的意义,就是实现了a和b值的互换,c作为一个过渡变量而存在。用人的思维去理解这段代码就是:第一步,将a的值给到c。此时c就等于是a的一个备份。因为a有了备份,就可以对a进行操作,所以有第二步,将b的值给到a。此时a的值已经是b。我们完成了互换的一半。因为b的值已经给到a了,所以我们可以对b进行操作,所以有第三步,将c的值给到b。因为c的值就是a,所以此时b的值就是a。我们完成了a和b值得互换。

原本挺简单的代码,让我解释了这么多,似乎有点画蛇添足。如果你真的觉得简单,咱们再接着看。

下面是很经典的冒泡排序

       for(i=0;i<numbers.length-1;i++)
        {
            for(j=0;j<numbers.length-1-i;j++)
            {
                if(numbers[j]>numbers[j+1])
                {
                    int temp=numbers[j];
                    numbers[j]=numbers[j+1];
                    numbers[j+1]=temp;
                }
            }
        }

啊哈,好像也没什么难度。就是实现了数组numbers的j和j+1位置的互换。再接着看。

下面是JDK 1.7 HashMap transfer方法的一段代码

       for (Entry<K,V> e : table) {
            while(null != e) {
                Entry<K,V> next = e.next;
                if (rehash) {
                    e.hash = null == e.key ? 0 : hash(e.key);
                }
                int i = indexFor(e.hash, newCapacity);
                e.next = newTable[i];
                newTable[i] = e;
               e = next;
           }
       }

这段代码到底干了啥?!简单来说,就是将HashMap旧数组中的元素移动到新数组中。table是个Entry数组,e代表一个Entry,Entry又是个列表。当然这不是我们关注的重点,我们此时值关注代码3,8,9,10行。这个似乎跟我们上面的有点不一样了。不一样的地方:一是变成了四个变量,包括e,e.next,next和newTable[i];二是变量之间是有关联的;三也是最重要的不同,此时的变量存储的不再是简单的数值,而是地址引用。最后一点有什么不同呢?在这一点上就是我们不能再将等于简单理解成是赋值(当然其实还是赋值,不过赋值的是地址引用),而是应该将等于认为是引用的变更。接着我们试着去理解这段代码的意义。

当我们执行第3行代码,我们的意思是将e的下一个节点赋值给next。此时next就是e.next的备份。我们就可以对e.next做一些操作了。看第8行,我们果然将newTable[i]赋值给e.next。newTable[i]代表新数组中索引为i的Entry链表的首节点。真正的含义就是e.next的指向变成了Entry链表的首节点所指向的地址。当是第一次while循环的时候,首节点为null,也就是说将e.next指向null。之后再看,我们会知道e会变成新数组Entry链表的尾结点,它的next节点应该指向null;当是大于第一次while循环的时候,首节点为当前e节点的前一个节点。这句话有点绕,其实就是e和e.next的值进行了互换,或者说让e指向了e.next,同时让e.next指向了e。接着看第9行,我们将e赋值给newTable[i],或者说让首节点指向了e,形成了首节点->e,e.next->原首节点。这个也就是注明的头插法(1.8的时候已经弃用了),因为我们总是将新节点放在Entry链表的头结点。第11号,就是将next赋值给e,作为下次循环的开始。

是不是觉得有点难度了,我们再接着看一个。

do {
    node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);

出自AQS的shouldParkAfterFailedAcquire。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值