Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 更好的股票代码功能?_Java_Hash_Hashmap_Hashcode - Fatal编程技术网

Java 更好的股票代码功能?

Java 更好的股票代码功能?,java,hash,hashmap,hashcode,Java,Hash,Hashmap,Hashcode,我正在将股票对象保存在一个HashMap中,其中键是股票代码字符串(例如苹果公司的“AAPL”)。不幸的是,这是不可行的,因为Ally Financial Inc(GM1)和Global Partners LP(GLP)有冲突的哈希代码,并且会相互重写。例如:“GM1.hashCode()=”GLP.hashCode()==主要问题 股票代码字符串是否有一个hashCode,可以保证没有冲突 public Class StockTicker { public String symbol;

我正在将股票对象保存在一个
HashMap
中,其中键是股票代码
字符串(例如苹果公司的
“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”中的“.”除外。

我认为键字符串的哈希代码不会对地图本身产生任何影响(我假设您使用的是实际的ticker符号字符串作为键,而不是散列代码;如果您使用散列代码插入到映射中,那么是的,这将导致问题)。我运行了一个快速测试,运行良好

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());
}
private-Map-stockMap=new-HashMap();
@试验
公共void映射测试(){
股票发行图(“GM1”、“GM1股票”);
股票地图出售(“GLP”、“glpstock”);
assertEquals(2,stockMap.size());
}

正如Mshnik所说,Java将为您处理冲突,因此您无需担心。您能否详细说明导致问题的具体代码?

我认为键字符串的哈希代码对映射本身没有任何影响(我假设您使用的是实际的ticker符号字符串作为键,而不是散列代码;如果您使用散列代码插入到映射中,那么是的,这将导致问题)。我运行了一个快速测试,运行良好

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());
}
private-Map-stockMap=new-HashMap();
@试验
公共void映射测试(){
股票发行图(“GM1”、“GM1股票”);
股票地图出售(“GLP”、“glpstock”);
assertEquals(2,stockMap.size());
}

正如Mshnik所说,Java将为您处理冲突,因此这不是您需要担心的事情。您可以详细说明具体是什么代码导致了您的问题吗?

正如其他答案和评论所指出的,A)Java将正确处理冲突,前提是您以令人满意的方式编写了equals和hashcode;B)即使得到一个完美的hashcode函数也不能保证不会发生冲突

有了这一点,就有可能为您的规范编写一个完美的hashcode函数。您需要担心的字符正好有37个(26个字母、10个数字和
),少于64个。因此,我们可以使用6位来表示每个字符。您最多有
5个
字符,这意味着您的哈希代码最多需要30位,这适合于整数

下面是一个创建完美哈希代码的实现:

  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;
    }
  }
公共静态类股票{
//股票票据长度可能小于64个字符
私有最终静态字符串字母数字=“abcdefghijklmnopqrstuvxyz1234567890。”;
//对于给定的有效字符,将为6,但这样编码可以防止以后出现错误
私有最终静态int-shiftAmnt=(int)(Math.log(alphaNumeric.length())/Math.log(2))+1;
私人股票;
公开股{
股票=s;
}
@凌驾
公共布尔等于(对象o){
返回o股票实例&&Stock.equals((股票)o.Stock);
}
@凌驾
公共int hashCode(){
int代码=0;
for(char c:stock.toCharArray()){

code=code正如其他答案和评论所指出的,A)假设您以令人满意的方式编写了equals和hashcode,Java将正确处理冲突;B)即使获得了一个完美的hashcode函数,也不能保证不会发生冲突

话虽如此,为您的规范编写一个完美的hashcode函数是可能的。您需要担心的字符正好有37个(26个字母、10个数字和
),小于64位。因此,我们可以使用6位来表示每个字符。您最多有
5个
字符,这意味着您的哈希代码最多需要30位,这与整数相符

下面是一个创建完美哈希代码的实现:

  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;
    }
  }
公共静态类股票{
//股票票据长度可能小于64个字符
私有最终静态字符串字母数字=“abcdefghijklmnopqrstuvxyz1234567890。”;
//对于给定的有效字符,将为6,但这样编码可以防止以后出现错误
私有最终静态int-shiftAmnt=(int)(Math.log(alphaNumeric.length())/Math.log(2))+1;
私人股票;
公开股{
股票=s;
}
@凌驾
公共布尔等于(对象o){
返回o股票实例&&Stock.equals((股票)o.Stock);
}
@凌驾
公共int hashCode(){
int代码=0;
for(char c:stock.toCharArray()){

code=code如果重写哈希代码,请确保也重写了equals。可以编写一个完美的(非相等对象没有冲突)哈希代码,但您知道HashMap将正确处理冲突(尽管性能受到的影响很小)即使在冲突情况下,是吗?这是否足够糟糕,以至于不能只使用
returnsymbol.hashCode();
?@Mshnik你的意思是不可能吗?@christopher,是的。Equals很简单,所以想把问题集中在hashCode实现上。注意,除非你的集合有2^32个bucket,否则你的hashCode将减少。例如,假设你只有1024个bucket,那么hashCode将减少到只有10位,你将即使使用唯一的哈希代码也会发生冲突。如果重写哈希代码,请确保也重写equals。可以编写完美的哈希代码(对于非相等对象没有冲突),但您知道HashMap将正确处理冲突(尽管性能受到了很小的影响)即使在碰撞的情况下,是吗?这是否足够糟糕,以至于不能只使用
returnsymb