我在使用java哈希表时遇到了一些问题。以下是我的hastable键和值
{corpus \ 2.txt = [cat sparrow],corpus \ 4.txt = [elephant sparrow],corpus \ 1.txt = [elephant cow],corpus \ 3.txt = [cow cat]}
因此,如果我想访问第一个元组,我必须传递密钥“corpus \ 2.txt”来获取其值。如果我通过价值,我可以得到它的关键。但我想制作一个我传递的功能,如1 2 3 4等,同时获得关键和价值。有什么想法吗?
第二个问题: 是否可以存储具有键和值的索引?或者是否可以从现有哈希表中获取索引(0,1,2,3等)?
谢谢!
答案 0 :(得分:3)
对于初学者,我会使用HashMap,而不是(现在过时的)HashTable。如果你这样做,那么你可以使用Map.Entry返回一个键/值对(根据你的第一个问题)。
您无法使用密钥轻松存储索引。您可能希望创建一个特殊的Key对象:
public class Key {
private String name;
private int index;
....
}
使用合适的equals()
/ hashCode()
实施(如评论中所述)并将其用作HashMap
中的关键字。您必须使用此密钥执行查找,从而使用当前基于String的密钥构造一个,但我不认为这是一个大问题。
答案 1 :(得分:0)
API中没有方法可以从Java哈希表中获取特定条目。您可以使用entrySet
方法访问所有条目的集合,并对其进行迭代,您将获得所有键值对作为Map.Entry
个对象。
哈希表完全无序。它们只是从键到值的映射,并没有任何明确的索引。如果迭代entrySet
结果,则会有一个特定的顺序来处理条目,但是当您修改哈希表时,这也可能会发生变化。
答案 2 :(得分:0)
看看LinkedHashMap,一个保留输入排序的地图实现。
答案 3 :(得分:0)
而是使用Map<Integer, ValueObject>
,其中ValueObject
只是一个带有两个属性的自定义javabean类,例如filename
和description
。
基本启动示例:
public class ValueObject {
private String filename;
private String description;
public ValueObject() {
// Always keep default constructor alive.
}
public ValueObject(String filename, String description) {
this.filename = filename;
this.description = description;
}
// Add/generate public getters and setters for filename and description.
}
您可以使用如下:
Map<Integer, ValueObject> map = new HashMap<Integer, ValueObject>();
map.put(1, new ValueObject("corpus1.txt", "elephant cow"));
map.put(2, new ValueObject("corpus2.txt", "cat sparrow"));
map.put(3, new ValueObject("corpus3.txt", "cow cat"));
map.put(4, new ValueObject("corpus4.txt", "elephant sparrow"));
ValueObject vo = map.get(1); // Returns VO with corpus1.txt and elephant cow.
答案 4 :(得分:0)
无法通过索引访问Map。但是,如果您真正想要做的是逐个访问地图中的键值对,您可以这样做:
for (Map.Entry<String, List<String>> nameAndWords: hashmap) {
String name = nameAndWords.getKey();
List<String> words = nameAndWords.getValue();
// do your stuff here
}
如果您确实需要建立索引,可以通过将密钥保存在列表中来向地图添加外部订单,在编辑地图时必须更新该列表:
HashMap<String, List<String>> wordsByCorpus;
List<String> corpusNames;
public void addCorpus(String name, List<String> words) {
List<String> oldValue = wordsByCorpus.put(name, words);
if (oldValue == null) corpusNames.add(name);
}
public void removeCorpus(String name) {
wordsByCorpus.remove(name);
corpusNames.remove(name);
}
public Map.Entry<String, List<String>> getCorpus(int i) {
String name = corpusNames.get(i);
List<String> words = wordsByCorpus.get(name);
return wordsByCorpus.new SimpleImmutableEntry(name, words); // 1.6 only!
}
答案 5 :(得分:0)
您要么使用LinkedHashMap,它允许您使用添加的顺序索引访问添加到地图的值。
或者你想使用2个HashMaps。一个用字符串值索引,另一个用于将整数值转换为第一个映射的字符串值键。然后很容易从索引获取键和值:
String key = mapByIntToStringKey.get(index);
V value = mapByStringKey.get(key);
// now have both key and value, no linear searching so should be fast
因此,您的地图将包含: mapByStringKey = {corpus \ 2.txt = [cat sparrow],corpus \ 4.txt = [elephant sparrow],corpus \ 1.txt = [elephant cow],corpus \ 3.txt = [cow cat]}
mapByIntToStringKey {2 = corpus \ 2.txt,4 = corpus \ 4.txt,1 = corpus \ 1.txt}
虽然这假设您的所有密钥不仅仅是“语料库”+索引+“。txt”。
如果所有键都如上所述,那么如果索引不是稀疏的,那么你可以使用一个简单的ArrayList(前面提到的)并使用快速的get(index)(直接在数组中查找,不能快得多)比那个),然后使用上面的表达式重建字符串键。 如果索引是稀疏的(即一些缺失,则存在间隙),那么只需使用mapByIntToStringKey,但用mapByIntToValue替换,并使用先前的字符串表达式重构所需的任何字符串键。
当前的高回答对我来说似乎很奇怪,因为建议是仅使用复合键的int索引位来键入映射。除非我读错了,否则意味着你无法单独使用字符串键来查找地图中的值,或者只是意味着你总是可以从字符串键中推断出int索引。