use*_*861 25 java collections hash hashmap
我想在一个hashmap中存储一组对象,其中key应该是两个字符串值的组合.有没有办法实现这个目标?
我可以简单地连接两个字符串,但我确定有更好的方法来做到这一点.
Tud*_*dor 41
您可以拥有一个包含两个字符串的自定义对象:
class StringKey {
private String str1;
private String str2;
}
Run Code Online (Sandbox Code Playgroud)
问题是,您需要确定两个此类对象的相等性测试和哈希码.
平等可以是两个字符串上的匹配,并且哈希码可以是连接成员的哈希码(这是有争议的):
class StringKey {
private String str1;
private String str2;
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof StringKey) {
StringKey s = (StringKey)obj;
return str1.equals(s.str1) && str2.equals(s.str2);
}
return false;
}
@Override
public int hashCode() {
return (str1 + str2).hashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
Tho*_*nti 10
public int hashCode() {
return (str1 + str2).hashCode();
}
Run Code Online (Sandbox Code Playgroud)
这似乎是一种生成hashCode的可怕方法:每次计算哈希码时创建一个新的字符串实例都很糟糕!(即使生成一次字符串实例并缓存结果也是不好的做法.)
这里有很多建议:
public int hashCode() {
final int prime = 31;
int result = 1;
for ( String s : strings ) {
result = result * prime + s.hashCode();
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
对于一对字符串,它变为:
return string1.hashCode() * 31 + string2.hashCode();
Run Code Online (Sandbox Code Playgroud)
这是一个非常基本的实现.通过链接提供了大量建议,以提出更好的调整策略.
为什么不创建一个(说)Pair对象,其中包含两个字符串作为成员,然后使用它作为键?
例如
public class Pair {
private final String str1;
private final String str2;
// this object should be immutable to reliably perform subsequent lookups
}
Run Code Online (Sandbox Code Playgroud)
不要忘记equals()和hashCode().有关HashMaps和密钥的更多信息,请参阅此博客条目,其中包括有关不变性要求的背景知识.如果您的密钥不是不可变的,那么您可以更改其组件,并且后续查找将无法找到它(这就是为什么不可变对象,如String密钥的良好候选者)
你认为串联并不理想是正确的.在某些情况下它会起作用,但它通常是一个不可靠和脆弱的解决方案(例如AB/C是否与A/BC不同?).
我有一个类似的情况。我要做的是将由波浪号(〜)分隔的两个字符串连接起来。
因此,当客户端调用服务函数从地图中获取对象时,它看起来像这样:
MyObject getMyObject(String key1, String key2) {
String cacheKey = key1 + "~" + key2;
return map.get(cachekey);
}
Run Code Online (Sandbox Code Playgroud)
这很简单,但是有效。
小智 5
我看到很多人使用嵌套映射。也就是说,要映射Key1 -> Key2 -> Value(我使用计算机科学/又名 haskell curring 符号进行(Key1 x Key2) -> Value映射,它有两个参数并产生一个值),首先提供第一个键——这会返回一个(部分)映射 Key2 -> Value,你在下一步。
例如,
Map<File, Map<Integer, String>> table = new HashMap(); // maps (File, Int) -> Distance
add(k1, k2, value) {
table2 = table1.get(k1);
if (table2 == null) table2 = table1.add(k1, new HashMap())
table2.add(k2, value)
}
get(k1, k2) {
table2 = table1.get(k1);
return table2.get(k2)
}
Run Code Online (Sandbox Code Playgroud)
我不确定它是否比普通的复合键结构更好。你可以对此发表评论。
您不需要重新发明轮子。使用时只需将番石榴的HashBasedTable<R,C,V>执行Table<R,C,V>接口,为您的需要。这是一个例子
Table<String, String, Integer> table = HashBasedTable.create();
table.put("key-1", "lock-1", 50);
table.put("lock-1", "key-1", 100);
System.out.println(table.get("key-1", "lock-1")); //prints 50
System.out.println(table.get("lock-1", "key-1")); //prints 100
table.put("key-1", "lock-1", 150); //replaces 50 with 150
Run Code Online (Sandbox Code Playgroud)
编码愉快!
| 归档时间: |
|
| 查看次数: |
37081 次 |
| 最近记录: |