- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我决定创建自己的 WritableComparable 类来了解 Hadoop 如何使用它。因此,我创建了一个带有两个实例变量 (orderNumber cliente) 的 Order 类并实现了所需的方法。我还为 getters/setters/hashCode/equals/toString 使用了 Eclipse 生成器。
在 compareTo 中,我决定只使用 orderNumber 变量。
我创建了一个简单的 MapReduce 作业,仅用于计算数据集中订单的出现次数。我的一个测试记录错误地是 Ita 而不是 Itá,正如你在这里看到的:
123 Ita
123 Itá
123 Itá
345 Carol
345 Carol
345 Carol
345 Carol
456 Iza Smith
据我所知,第一条记录应该被视为不同的顺序,因为记录 1 的 hashCode 与记录 2 和 3 的 hashCode 不同。
但是在reduce阶段,3条记录被组合在一起。正如您在这里看到的:
Order [cliente=Ita, orderNumber=123] 3
Order [cliente=Carol, orderNumber=345] 4
Order [cliente=Iza Smith, orderNumber=456] 1
我认为它应该有一行用于计数为 2 的 Ita 记录,而 Ita 应该有计数为 1。
因为我在 compareTo 中只使用了 orderNumber,所以我尝试在这个方法中使用 String cliente(在下面的代码中注释)。然后,它按照我的预期工作。
那么,这是预期的结果吗? hadoop 不应该只使用 hashCode 来对键和它的值进行分组吗?
这是 Order 类(我省略了 getters/setters):
public class Order implements WritableComparable<Order>
{
private String cliente;
private long orderNumber;
@Override
public void readFields(DataInput in) throws IOException
{
cliente = in.readUTF();
orderNumber = in.readLong();
}
@Override
public void write(DataOutput out) throws IOException
{
out.writeUTF(cliente);
out.writeLong(orderNumber);
}
@Override
public int compareTo(Order o) {
long thisValue = this.orderNumber;
long thatValue = o.orderNumber;
return (thisValue < thatValue ? -1 :(thisValue == thatValue ? 0 :1));
//return this.cliente.compareTo(o.cliente);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cliente == null) ? 0 : cliente.hashCode());
result = prime * result + (int) (orderNumber ^ (orderNumber >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Order other = (Order) obj;
if (cliente == null) {
if (other.cliente != null)
return false;
} else if (!cliente.equals(other.cliente))
return false;
if (orderNumber != other.orderNumber)
return false;
return true;
}
@Override
public String toString() {
return "Order [cliente=" + cliente + ", orderNumber=" + orderNumber + "]";
}
这是 MapReduce 代码:
public class TesteCustomClass extends Configured implements Tool
{
public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Order, LongWritable>
{
LongWritable outputValue = new LongWritable();
String[] campos;
Order order = new Order();
@Override
public void configure(JobConf job)
{
}
@Override
public void map(LongWritable key, Text value, OutputCollector<Order, LongWritable> output, Reporter reporter) throws IOException
{
campos = value.toString().split("\t");
order.setOrderNumber(Long.parseLong(campos[0]));
order.setCliente(campos[1]);
outputValue.set(1L);
output.collect(order, outputValue);
}
}
public static class Reduce extends MapReduceBase implements Reducer<Order, LongWritable, Order,LongWritable>
{
@Override
public void reduce(Order key, Iterator<LongWritable> values,OutputCollector<Order,LongWritable> output, Reporter reporter) throws IOException
{
LongWritable value = new LongWritable(0);
while (values.hasNext())
{
value.set(value.get() + values.next().get());
}
output.collect(key, value);
}
}
@Override
public int run(String[] args) throws Exception {
JobConf conf = new JobConf(getConf(),TesteCustomClass.class);
conf.setMapperClass(Map.class);
// conf.setCombinerClass(Reduce.class);
conf.setReducerClass(Reduce.class);
conf.setJobName("Teste - Custom Classes");
conf.setOutputKeyClass(Order.class);
conf.setOutputValueClass(LongWritable.class);
conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);
FileInputFormat.setInputPaths(conf, new Path(args[0]));
FileOutputFormat.setOutputPath(conf, new Path(args[1]));
JobClient.runJob(conf);
return 0;
}
public static void main(String[] args) throws Exception {
int res = ToolRunner.run(new Configuration(),new TesteCustomClass(),args);
System.exit(res);
}
}
最佳答案
默认的分区器是HashPartitioner
,它使用hashCode
方法来确定将K、V 对发送到哪个reducer。
一旦在 reducer 中(或者如果您使用的是在 map 端运行的 Combiner),compareTo
方法用于对键进行排序,然后(默认情况下)还用于比较是否顺序键应组合在一起,并在同一迭代中减少它们的关联值。
如果您不使用 cliente
键变量,而只在您的 compareTo
方法中使用您的 orderNumber
变量,那么任何具有相同键值的键orderNumber
的值将一起减少 - 无论 cliente
值如何(这是您当前观察到的)
关于hadoop - Hadoop 不应该仅基于 hashCode 在 reducer 中分组 <key, (list of values) 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16988036/
class UserScoring implements Comparable { User user; int score; UserScoring(
当重写 Java 中的 equals() 和 hashcode() 方法时,为什么不经常使用它: public int hashCode() { return (int) this.hashC
给定java Object#hashCode文档快照: As much as is reasonably practical, the hashCode method defined by class
下面的代码(sign.hashCode())是给我签名的hashCode还是内存中对象的hash? try { PackageInfo packageInfo = getPackageMana
考虑: String[] segments = {"asdf", "qwerty", "blahblah", "alongerstring", "w349fe3434"}; String fullSt
在审查大型代码库时,我经常遇到这样的情况: @Override public int hashCode() { return someFieldValue.hashCode(); } 程序员不
在以下情况下,与下面的函数发生 HashCode 冲突的可能性有多大。 key[0]、key[1]、key[2]、key[3] 的随机整数值 使用具有以下约束的随机键值 键[0] <1,000,000
从 Java 7 开始,我们有了 o.hashCode(); Objects.hashCode(o); Objects.hash(o); 前两个与空检查大致相同,但最后一个是什么? When a si
这个问题已经有答案了: Objects.hash() vs Objects.hashCode(), clarification needed (3 个回答) 已关闭 6 年前。 一个简单、简短的问题:
我是否需要使用super.hashcode()来计算this.hashcode()? IDE(例如 IntelliJ Idea)可以生成 equals 和 hashcode。它可以使用 java.ut
class A { } class B extends A { void m1(){ System.out.println(this.hashCode());
我查看了Arrays.hashCode(char[] c)的源代码 我不太确定它适用的算法是否在所有情况下都能正常工作。 public static int hashCode(int a[])
我有两个表具有一对一的关系,如下所示: @Entity @Data @NoArgsConstructor @AllArgsConstructor public class Book { @Id
为什么stringObject的hashcode是我提供的字符串? String s = new String(); // here the hascode is 0. 但是当我获得我创建的某个对象的
public abstract class HolidayPackageVariant { private HolidayPackage holidayPackage; private String
这两个代码片段有什么区别? 片段 1: Object o = new Object(); int i = Objects.hashCode(o); 片段 2: Object o = new Objec
在 Java 8 中有一个类 java.util.Objects,其中包含 hashCode() 方法。同时 Google Guava 19 包含 com.google.common.base.Obj
我的一个类(class)中有以下方法。它只是 HashMap 的公共(public)包装器(名为 teamOfPlayer,具有 Player 对象的键和 Integer 对象的值),仅此而已。 pu
我在这里做错了什么? @Override public int hashCode() { HashCodeBuilder has
我有以下程序。 Employee employee1 = new Employee("Raghav1", 101); Employee employee2 = new Employee("Raghav
我是一名优秀的程序员,十分优秀!