Skip to content

Commit

Permalink
/issues/146 Fixed hashCode/equals.
Browse files Browse the repository at this point in the history
  • Loading branch information
atsticks committed Jul 30, 2017
1 parent cc7860f commit e83cb97
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.javamoney.moneta;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -259,7 +260,23 @@ public String toString() {
*/
@Override
public int hashCode() {
return Objects.hash(base, conversionContext, factor, term, chain);
// Numerically equal factors should produce the same hash code, so hash a normalized
// version of the factor rather than the NumberValue object.
BigDecimal normalizedFactor = factor.numberValue(BigDecimal.class).stripTrailingZeros();

// The exchange rate chain includes a reference to "this" if the caller doesn't explicitly
// set a chain in the builder, so we can't naively hash the chain or we'll get infinite
// recursion.
int chainHash = 0;
for (ExchangeRate chainedRate : chain) {
if (chainedRate == this) {
// Use a constant to represent the presence of this object in the chain.
chainHash = Objects.hash(chainHash, "this");
} else {
chainHash = Objects.hash(chainHash, chainedRate);
}
}
return Objects.hash(base, conversionContext, normalizedFactor, term, chainHash);
}

/*
Expand All @@ -272,13 +289,11 @@ public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof DefaultExchangeRate) {
DefaultExchangeRate other = (DefaultExchangeRate) obj;
return Objects.equals(base, other.base) &&
Objects.equals(conversionContext, other.conversionContext) &&
Objects.equals(factor, other.factor) && Objects.equals(term, other.term);
}
return false;
DefaultExchangeRate other = (DefaultExchangeRate) obj;
return Objects.equals(base, other.base) &&
Objects.equals(conversionContext, other.conversionContext) &&
factor.compareTo(other.factor) == 0 &&
Objects.equals(term, other.term);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,11 @@ public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof DefaultExchangeRate) {
DefaultExchangeRate other = (DefaultExchangeRate) obj;
return Objects.equals(base, other.base) &&
Objects.equals(conversionContext, other.conversionContext) &&
factor.compareTo(other.factor) == 0 &&
Objects.equals(term, other.term);
}
return false;
DefaultExchangeRate other = (DefaultExchangeRate) obj;
return Objects.equals(base, other.base) &&
Objects.equals(conversionContext, other.conversionContext) &&
factor.compareTo(other.factor) == 0 &&
Objects.equals(term, other.term);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.javamoney.moneta;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -259,7 +260,23 @@ public String toString() {
*/
@Override
public int hashCode() {
return Objects.hash(base, conversionContext, factor, term, chain);
// Numerically equal factors should produce the same hash code, so hash a normalized
// version of the factor rather than the NumberValue object.
BigDecimal normalizedFactor = factor.numberValue(BigDecimal.class).stripTrailingZeros();

// The exchange rate chain includes a reference to "this" if the caller doesn't explicitly
// set a chain in the builder, so we can't naively hash the chain or we'll get infinite
// recursion.
int chainHash = 0;
for (ExchangeRate chainedRate : chain) {
if (chainedRate == this) {
// Use a constant to represent the presence of this object in the chain.
chainHash = Objects.hash(chainHash, "this");
} else {
chainHash = Objects.hash(chainHash, chainedRate);
}
}
return Objects.hash(base, conversionContext, normalizedFactor, term, chainHash);
}

/*
Expand All @@ -272,13 +289,11 @@ public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof DefaultExchangeRate) {
DefaultExchangeRate other = (DefaultExchangeRate) obj;
return Objects.equals(base, other.base) &&
Objects.equals(conversionContext, other.conversionContext) &&
Objects.equals(factor, other.factor) && Objects.equals(term, other.term);
}
return false;
DefaultExchangeRate other = (DefaultExchangeRate) obj;
return Objects.equals(base, other.base) &&
Objects.equals(conversionContext, other.conversionContext) &&
factor.compareTo(other.factor) == 0 &&
Objects.equals(term, other.term);
}

/**
Expand Down

0 comments on commit e83cb97

Please sign in to comment.