在我的应用程序中,我将自定义Price
类型定义如下
public final class Price {
private BigDecimal cash;
private Currency currency;
...
}
使用默认的Object#equals
和Object#hashCode
方法,因为它不是必需的(我从不检查Price
个对象的逻辑相等性。)
此外,还有订单收据,表示订单中商品的总价。如果订单中有3个商品的价格为2 USD
,3 USD
和2 GBP
,则收据应包含实体5 USD
和2 GBP
。
现在,我使用java.util.Currency
键
Map<Currency, BigDecimal> receipt;
我的问题是,将它更改为
是否是一个好的设计Set<Price> receipt;
并重复使用已覆盖的Price
和Object#equals
方法的自定义Object#hashCode
类型
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Price price = (Price) o;
return currency.equals(price.currency);
}
@Override
public int hashCode() {
return currency.hashCode();
}
这样
Price usd_2 = new Price(new BigDecimal(2), Currency.getInstance("USD"));
Price usd_3 = new Price(new BigDecimal(3), Currency.getInstance("USD"));
usd_2.equals(usd_3); // true
以这种方式覆盖平等方法以及未来可能导致的陷阱是不是一个糟糕的选择?
答案 0 :(得分:1)
您可以进行一些设计改进,我肯定会在评论中弹出,但我会忽略这些并专注于您的具体问题。
所以,在评论中,你说一个&#34;收据&#34;是:
它是要支付货物的收据。如果客户购买2件物品,价格为2美元和3美元,则收据包含5美元。
它表示项目的总成本,它不跟踪单个项目。
引用同一收据的商品可能具有不同的货币,这就是我使用地图的原因。 F.e,收据可能包含5美元和4英镑。
关于将其从Map
更改为Set
的问题,请将其保留为Map
。这是有道理的。您的收据是各种货币总计的集合,每种货币一个。您可以将其更改为Set<Price>
但是,正如您所发现的那样,您必须使用equals
和hashCode
的奇怪,违反直觉的实现,并且Set
并不能真实地代表您正在做的事情:您的收据不是任意价格的集合,而是将货币映射到该货币的总计。< / p>
如果你真的想要在其上使用所有OO,你可以制作一个Receipt
类,例如:
public class Receipt {
private Map<Currency,Price> totals;
...
}
然后添加各种getter和setter,隐藏您在内部
至于 以这种方式覆盖平等方法以及将来可能导致的陷阱是不是一个糟糕的选择? 当然这将是一个糟糕的选择。两个对象不应该相等,除非相等,并且只比较一个价格的货币单位是没有意义的,因为$ 3 USD和$ 400 USD不相等。根据您的实际业务规则实施 正因为如此,使用 希望有所帮助。Map
使用List<Currency> getCurrencies ()
的事实(例如Price getTotal (Currency c)
和equals
等等)。但是,除了学习经验之外,你在中 hashCode
中的Price
和equals
:
hashCode
和equals
:
hashCode
,除非它们的金额和货币单位相等,否则两个价格不相等。所以比较两者。equals()
它稍微宽松一点,唯一真正的限制是如果true
为两个对象返回hashCode()
,那么它们的hashCode()
应该是相同的。但是,如果两个不相等的对象产生相同的哈希码,那也没关系。通常你选择一个cash.hashCode()
可以很好地分配哈希码,所以对于你的情况,我要么返回,例如cash
,或currency
和Set
哈希码的某种组合。equals()
并不是一个好主意 - 这样做意味着你必须拥有一个viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener(){
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
conterchange.setText(""+(1+position));
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
实施,而不是java.awt.Component
真的和现实一致。