在Java中,我遇到了以下行:
e.g.: (1 & Integer.MAX_VALUE) % 4
e.g.: (2 & Integer.MAX_VALUE) % 5
它做什么?我已经尝试过代码,但我无法理解它的用途或功能。试图检查的代码是什么?
基本上,它是(int & Integer.MAX_VALUE) % int
。
实际代码(来自Hadoop培训课程):
public int getPartition(StringPairWritable key, Text value, int numReduceTasks) {
return (key.getLeft().hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
答案 0 :(得分:5)
i & Integer.MAX_VALUE
与此代码完全相同:
if(i < 0) {
i = (i + Integer.MAX_VALUE + 1);
}
%
是一个常规的余数操作。
如果您不关心它的实际价值(例如,如果您想要将可以是正数和负数的随机数转换为正数),这是确保整数为正的快速方法只有正值)。
答案 1 :(得分:3)
Integer.MAX_VALUE
是0x7FFFFFFF
。因此num & Integer.MAX_VALUE
清除num
中的最高位。除以% numReduceTasks
后,numReduceTasks
为正常余数。
这样做是为了将有符号数转换为非负数,然后从0
到numReduceTasks-1
获得均匀分布的值。请注意,如果您撰写Math.abs(key.getLeft().hashCode()) % numReduceTasks
,如果hashCode()
恰好为Integer.MIN_VALUE
,Math.abs(Integer.MIN_VALUE)
仍为Integer.MIN_VALUE
,则可能会收到否定数字。所以& Integer.MAX_VALUE
是一种更安全的选择。
答案 2 :(得分:2)
这里有两个部分:
让我们首先介绍它的Java方面。它是相当简单的逐位数学运算,因为它清除符号位并将值转换为正整数。
这很容易在这里展示;我们假设我们的密钥是-128876912,即0xF8517E90
。 int的最大值为0x7FFFFFFF
。
如果我们查看实际的数学运算,符号位将被清除(在这种情况下还有很多其他位),并且我们得到一个正整数值。
1111 1000 0101 0001 0111 1110 1001 0000
0111 1111 1111 1111 1111 1111 1111 1111
---------------------------------------
0111 1000 0101 0001 0111 1110 1001 0000
如果值为正,则最终结果是我们得到相同的值。
这很重要,因为哈希码可能会返回负数;我不相信你想要一个负值,因为一个重要的原因稍晚。
对于分区位,这比我真正声称的Hadoop知识多一点,但在reading the docs之后,它会通知您该值属于哪个分区。这就是模数的来源;您确保获得[0, partition)
之间的值,从而指定处理数据的特定位的减速器。
从我的阅读中,这是默认提供的分区程序之一,可能不完全适合您的使用(例如,您可能需要group your data in a different way)。
答案 3 :(得分:0)
如果代码中的表达式确实是
(i & Integer.MAX_VALUE) % j
它计算i mod j
的残差类。注意i % j
是除法的余数,对称(w.r.t. i == 0)函数,而残差类是周期函数。