flink 中自定义类的 hashCode() 和 equals() 方法

Posted

技术标签:

【中文标题】flink 中自定义类的 hashCode() 和 equals() 方法【英文标题】:hashCode() and equals() method for custom classes in flink 【发布时间】:2020-08-31 19:31:42 【问题描述】:

我怀疑 Flink 中的 Java 自定义类是否需要覆盖 hashCode()equals() 方法,因为我在 this page 中读到 hashCode() 绝不能在分布式系统中实现,而 Apache Flink 是其中之一。

示例:我有这个课程:

public class EventCounter 
    public String Id;
    public long count;
    public Timestamp firstEvent;
    public Timestamp lastEvent;
    public Date date;

    public EventCounter() 
    

我是否需要在 Flink 中为此类类实现 hashCode()equals() 或者让 Flink 自己管理这些方法对性能更好?

亲切的问候!

【问题讨论】:

【参考方案1】:

你想在 Flink 中用作键的类型(即作为从 KeySelector 返回的值)必须具有 hashCode 和 equals 的有效实现。特别是,hashCode 必须在 JVM 之间具有确定性(这就是为什么数组和枚举在 Flink 中不能作为键工作的原因)。

【讨论】:

让我们为上面的同一个类假设这种情况:DataStream<EventCounter> stream = env.addSource(...); KeyedStream<EventCounter, String> keyed = stream.keyby(k->k.id); keyed.flatMap(new customRichFlatMapClass()) or keyed.window(TumblingEventTimeWindows).process(new ProcessFunctionClass()); 这些类customRichFlatMapClassProcessFunctionClass 与状态一起使用,我有一个final TypeInformation<EventCounter> info = Types.POJO(EventCounter.class); 将对象序列化为状态。 EventCounter 中是否需要 hashCode()equals() ?谢谢 不,你没有。您需要考虑的唯一情况是您是否想做stream.keyBy(k -> k) 非常感谢@David,这是我对相关信息进行长期研究后的理解,但我想确定它是如何工作的,否则我会有额外的 CPU无需创建这些哈希值。再次感谢您。 我同意大卫的回答。但是,在 Java 中,总是最好覆盖任何业务 POJO 的 hashcode/equals 方法,这是一个很好的做法。注册I'm having an extra CPU utilization without been needed to create those hashes - 我认为只有当您(或内部代码)调用这些方法时才会使用这些方法。只有在调用这些方法时覆盖这些方法,您才能获得期望的结果。【参考方案2】:

在写这两个方法之前,想想你的类需要是symmetric还是transitive还是consistent

它专为基于哈希的算法而设计。因此,您需要确保它们以正确的方式进行,并且附带说明创建哈希码是一项 CPU 密集型任务。

【讨论】:

【参考方案3】:

hasCode()equals() 方法只有在对象/类将用作 Flink 的键的情况下才需要实现,例如:

DataStream<EventCounter> stream = env.addSource(...);
KeyedStream<EventCounter, String> keyed = stream.keyby(k->k); /*Where k is the class object type!*/

【讨论】:

以上是关于flink 中自定义类的 hashCode() 和 equals() 方法的主要内容,如果未能解决你的问题,请参考以下文章

WCF c#中自定义类的传输问题

Jmeter中自定义JavaSamplerClient类的编写

支持嵌套类型中自定义类的默认序列化

python中自定义函数类的引用(最全)

Qt中自定义类的方法

重写java类的equals()和hashCode方法