【问题标题】:Mixing bitwise and ordinary operations in array manipulations (java)在数组操作中混合按位和普通操作(java)
【发布时间】:2017-06-27 19:03:36
【问题描述】:

以下代码来自标准 java 库中的 ArrayDeque。我选择它有点武断,因为在整个代码中有很多这种想法的例子。

public void addFirst(E e) {
    if (e == null)
        throw new NullPointerException();
    elements[head = (head - 1) & (elements.length - 1)] = e;
    if (head == tail)
        doubleCapacity();
}

基本上,当我读到它时,head 的值减一,然后按位“与”与 elements.length 减一。此操作确定数组的哪个索引将保存新值 e,并允许循环回绕到数组的开头。到目前为止还好(希望没有错)。

但接下来我们就来了:

if (head == tail) doubleCapacity();

head 和 tail 是整数。即使它们在按位“与”之后等于数组中的相同位置(意味着数组已满并且需要扩展),这也不会使它们等于整数(这是正在测试的内容,对吗?)。

所以...我不明白这是如何工作的。

谁能帮忙?

编辑澄清我指的是数组的索引,而不是它的任何元素。

【问题讨论】:

  • 你说的不等于整数是什么意思?如果head 存储10 的值,tail 存储10 的值,它们是相等的。
  • 我的意思是 int 变量 head 和 tail 有不同的值。它们在被布尔值添加后指向数组中的相同位置......因为溢出......但它们本身没有相同的值。
  • headindex 是数组的索引,而不是数组元素。
  • 对...它们是数组的索引。不是数组中的元素。我可以编辑它,但问题没有改变。
  • 此时它们已经以数组长度为模减少了,所以这 “在按位与之后”。

标签: java arrays


【解决方案1】:

headtail 最初指的是数组的第一个索引 - 0。

后备数组的初始长度默认为 16,并且始终是 2 的幂。这对于您引用的代码的 sn-p 工作很重要。

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
^
head
tail

现在假设您将 15 个元素添加到队列的末尾。每次在末尾添加一个元素,tail 索引就会递增,因此在添加 15 次后,您会得到:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
^                                  ^
head                               tail

此时,数组中除15以外的所有索引都被占用了。

现在我们得到你引用的代码:

当您调用addFirst 时,head 应递减(必要时环绕到数组末尾),并在head 的新值的索引处添加新元素。

由于head 为0,head 的新值(head - 1) & (elements.length - 1)-1 & 15 或(转换为二进制)11111111111111111111111111111111 & 00000000000000000000000000001111,等于15,数组的最后一个索引。

此时,headtail 都包含数组的最后一个索引 - 15。

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
                                   ^
                                   head
                                   tail

这意味着数组已满,必须加倍。

这里要注意的重要一点是(head - 1) & (elements.length - 1) 等价于(head - 1) % elements.length。这只是因为elements.length 是 2 的幂。

【讨论】:

  • 哦,我明白了... head 实际上已更改为 ((head-1) & (elements.length-1)) 的值...是的,好的。
  • 不会行elements[head = (head - 1) & (elements.length - 1)] = e; head 和 tail 都是 15 时覆盖 tail 元素??
  • abstractnature--是的,我认为这就是为什么调用 doubleCapacity--来增加数组并消除该问题的原因。我基本上只是错过了一些操作顺序的东西,并没有看到 head 的值发生了比我假设的更大的变化。
  • @abstractnature 不会,因为tail 指向下一个元素将被添加到队列末尾的索引(当调用 addLast 时),这是一个未占用的索引数组。
  • double capactiy 正在创建一个两倍于其大小的数组并将数组复制到左半部分,最后将 head = 0 和 tail = 无论之前的长度是什么(如果我是正确的),那么发生了什么到尾元素? addFirst 删除并覆盖它,它消失了吗?那是我的疑问。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多