/** Partition keys by their {@link Object#hashCode()}. */
@InterfaceAudience.Public
@InterfaceStability.Stable
public class HashPartitioner<K, V> extends Partitioner<K, V> {
/** Use {@link Object#hashCode()} to partition. */
public int getPartition(K key, V value, int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
}
在mapreduce中 分区过程中通过类HashPartitioner<K,V> implements Partitioner<K,V> 来实现相同的key 的value 会分配到同一个reduceTask中
HashPartitioner 类就是负责处理分配的类
(key.hashCode() & 2147483647) % numReduceTasks
hasCode()是返回一个哈希值,hashCode()源码是:
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;
}
返回值是int类型,Integer.MIN_VALUE=2147483647 转换成二进制值是1111111111111111111111111111111
key.hashCode() & 2147483647 可以保证结果是非负数,HashPartitioner类返回的int值就是一个逻辑的分区数值。
个人理解· 如有错误,请指出 不胜感激
怎么保证非负数呢?
这个int类型的最大值
转换成二进制是32位
第一位是011111111…然后是一串1
它与int型的任意负数 因为负数首位是1符号位
不管怎么样与完了 这个结果的第32位还是符号位0 一直是正数
如果hashCode返回了一个负数 拿-4来说 1100 四位的 首位符号位 然后取反加1 还是1100 与上最大值 结果仍然为正数 就算是最小的负数 第32位符号位为1 它与0与还是0 这就保证了一直为正数
转换成二进制它的首位为符号为1
01111111111.。。。。1111
与
1
参考博客:https://blog.csdn.net/qq_35573689/article/details/98513062