2016-03-24 12 views
0

ZonedDateTime.hashCode()の実装がZonedDateTime.isEqual(...)と一貫していることが保証されているのでしょうか?もしそうでなければ、そのようなハッシュコードをどのように計算できますか?この質問はMETHOD isEqual、NOT ABOUT equalsうとしていることをZonedDateTime is isqual()と一貫性のあるhashCode()ですか?

EDIT

NOTE。それは私の質問の誤植ではありません。

EDIT#2

私はZonedDateTimeオブジェクトが含まれているクラスを持っているので、私はこれを求めていた理由があります。次のようにこのクラスの実装は、次のとおりです。

public class Foo { 
    private ZonedDateTime dateTime; 

    @Override 
    public boolean equals(Object obj) { 
     // Boilerplate stuff here... 
     final Foo other = (Foo)obj; 
     return (... && dateTime.isEqual(other.dateTime) && ...); 
    } 

    @Override 
    public int hashCode() { 
     // What do I need to put here so that my implementation of 
     // hashCode is consistent with my implementation of equals? 
     return Objects.hashCode(..., dateTime.?, ...); 
    } 
} 

あなたが実装によって見ることができるように、私が保存された回数が指すときに、2つのオブジェクトが等しい比較するために、私は、equalsの私の実装内isEqualメソッドを呼び出しています同じ瞬間。 hashCodeの実装では、FooクラスがhashCodeequalsと一致するという要件を満たすようにするにはどうすればよいですか?方法isEqual()に関するご質問について

+0

他に考えられる理由がありますか?それが事実なら、それは適切に文書化されるべきです。 – Tunaki

+0

あなたは本当にこれが当てはまると思われる理由を説明する必要があります。さもなければ、質問はおそらくStackOverflowのトピック外です。 –

+0

@fgeいいえ、言語仕様は 'hashCode'メソッドが' equals'と一貫していることを保証しています。私はそれが['isEqual'](https://docs.oracle.com/javase/8/docs/api/java/time/chrono/ChronoZonedDateTime.html#isEqual-java)と呼ばれる別の方法と一致するかどうかを尋ねています。 .time.chrono.ChronoZonedDateTime-)、これは 'equals'とは異なる結果を生成します。彼らは2つの異なる質問です。 –

答えて

3

isEqual()メソッドのjavadocは

これはdateTime1.toInstant().equals(dateTime2.toInstant());を使用するのと同じであると言います。

この方法と一致するハッシュコードを計算する場合は、zdt.toInstant().hashCode()を使用する必要があります。それであなたのFoo.hashCode()はあなたのFoo.equals()と一貫しています。

+0

私のupvoteをOKにしましたが、なぜOPが 'Instant'だけでなく' ZonedDateTime'で動作するのかという疑問が生じますか? ;-)プログラマーの人生はおそらく 'ZonedDateTime'なしでもっと簡単になるでしょう。 –

+0

@MenoHochschildパブリックインターフェイスを表現したい。誰かが時間を取ったり設定したりすると、タイムゾーンを明示的に知っていたり、指定したりしてほしい。私はまた、フォーマット "yyDDHHmmss"(暗黙のUTCタイムゾーン付き)の文字列に時刻をシリアル化する必要があります。私が知る限り、DateTimeクラスの1つを経由せずにインスタントをシリアル化/逆シリアル化する方法はありません。だから、私は即座にインスタントを保存することができましたが、パブリックインターフェイスとシリアライゼーション/デシリアライゼーションの両方で前後に変換する必要があります。ほとんど利益のために余分な仕事がたくさんあるようです。 –

+1

@JeffGまあ、「ZonedDateTime」は私の個人的な好みではないことを認めます。なぜなら、物事をより複雑にする強い傾向があるからです(この質問と回答の全文も参照してください)。私の経験が示すように、 'Instant'と' ZoneId'の組み合わせで十分です。ここでは、日付と時刻の文字列へのシリアライズにも十分です。あなたはそれが不可能だと思っていますが、それは - タイムゾーン情報を持つフォーマッタを設定するだけです。また、 'ZonedDateTime'はシリアル化のためのフォーマッタ(JSON?)を必要とします。複雑なものを複数の単純なコンポーネントに分割するほうが、しばしば役に立ちます。 –

2

この方法はObject -methods equals()hashCode()とは何の関係もありません。混乱を避け、インスタントオンリーの比較をより明確にするためには、おそらくisSimultaneous()に改名するほうがよいでしょう。 この類似の名前のメソッドとの整合性をhashCode()とすることは無意味です。もちろん

、2 ZonedDateTime -objectsが同じ瞬間を持っているならば、isEqual()に基づく比較はtrueを得られますが、ハッシュコードは、異なるローカルタイムスタンプに異なる場合が多いです。これをhashCode()isEqual()という矛盾として考えるかもしれませんが、それは重要ではありません。

メソッドisEqual()は、ハッシュマップルックアップを使用するコンテキストでは単に関連しません。逆に

、メソッドisEqual()を使用する場合、方法hashCode()(または任意の計算されたハッシュコード)は関連性がありません。

あなたの質問とあなたのdownvoteの私の最初の誤解は、両方の方法(equals()isEqual())が非常に似ているが非常に異なる意味を持っているという事実に混乱の可能性があることを示しています。

+0

@JeffGさて、私はすでに私の質問を更新しました。 –

+0

あなたの答えは、「いいえ、 'hashCode'は' isEqual'との一貫性が保証されていません」と要約できます。あれは正しいですか? –

+0

@JeffGもう一度私の答えを編集しました。 'hashCode()'と 'isEqual()'の一貫性を探すべきではありません。それはあなたのために今はっきりしていますか? –

1

二つの方法のソースコードを読む

  • isEqual methodは、それらが時間的に同じ瞬間(エポックすなわち等しい秒と等しいナノ秒)を表すかどうかを確認するためにZonedDateTimeインスタンスを比較します。

  • hashCode method of ZonedDateTime

    dateTimeoffsetzoneのハッシュコードをXORすることによって計算されます。

インスタンスの非常に異なるプロパティを考慮するため、これらの2つが一貫性があると期待できる方法はありません。

+1

それは私の質問の最初の部分に答えます。あなたは二番目の答えを知っていますか?例えば、 'ZonedDateTime.toInstant()。hashCode()'は 'isEqual()'で一貫したハッシュコードを生成しますか? –

+0

'Instant.hashCode()'は、秒とナノ秒のハッシュを計算します。再度、[ソースコードを読む](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/time/Instant.java#1314)で簡単に答えます。 。 'Instant'には' isEqual'メソッドがありません。 –

関連する問題