[英]Better hashCode function for stock ticker symbols?
我将股票对象保存在HashMap
,其中的关键是股票代码为String
(例如,Apple,Inc.的"AAPL"
)。 不幸的是,这是不可行的,因为Ally Financial Inc(GM1)和Global Partners LP(GLP)具有冲突的哈希码,并且会相互覆盖。 例如: "GM1".hashCode() == "GLP".hashCode()
==主要问题。
是否有用于股票行情自动收录器字符串的hashCode
,可以保证不发生冲突?
public Class StockTicker {
public String symbol;
public StockTicker(String symbol) { this.symbol = symbol; }
@Override
public int hashCode() {
// What goes here?
}
}
成功的答案可能会利用以下事实:股票代码字符串的字符数不得超过5个,并且以大写字母数字表示,但“”除外。 就像“ BRK.B”中一样。
我认为键字符串的hashCode不会对地图本身产生任何影响(我假设您使用的是实际的股票代号符号字符串,而不是哈希代码;如果您使用哈希代码插入地图,则是的,那会引起问题)。 我进行了快速测试,运行正常。
private Map<String, String> stockMap = new HashMap<String, String>();
@Test
public void mapTest() {
stockMap.put("GM1", "gm1stock");
stockMap.put("GLP", "glpstock");
assertEquals(2, stockMap.size());
}
就像Mshnik所说的那样,Java将为您处理冲突,因此您无需担心。 您能否详细说明是什么代码导致了您的问题?
正如其他答案和注释所指出的那样,A)假设您以令人满意的方式编写了equals和hashcode,Java将正确处理冲突; B)即使获得完美的hashcode函数也不能保证不会发生冲突。
话虽如此,有可能为您的规范编写完美的哈希码功能。 您完全需要担心37个字符(26个字母,10个数字和.
),它小于64。因此,我们可以使用6位来表示每个字符。 您最多可以有5
字符,这意味着您的哈希码最多需要30位,它可以容纳一个int。
这是创建完美哈希码的实现:
public static class Stock{
// The possible characters of a stock - note length is < 64
private final static String alphaNumeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.";
//Will be 6 for given valid chars, but coding it like this prevents bugs later
private final static int shiftAmnt = (int)(Math.log(alphaNumeric.length()) / Math.log(2)) + 1;
private String stock;
public Stock(String s) {
stock = s;
}
@Override
public boolean equals(Object o) {
return o instanceof Stock && stock.equals( ((Stock)o).stock);
}
@Override
public int hashCode() {
int code = 0;
for (char c : stock.toCharArray()) {
code = code << shiftAmnt;
code += alphaNumeric.indexOf(c);
}
return code;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.