我的hashmap初始化如下:
Hashmap<String[][], Boolean> tests = new Hashmap<String [][], Boolean>();
我想插入测试而无需初始化密钥:
tests.put({{"a"}, {"a"}}, true);
但是,Java似乎不允许我这样做。如果我这样做就行了:
String[][] hi = {{"a"}, {"a"}};
tests.put(hi, true);
有没有办法避免后者让前者工作?
有人也可以解释这个错误背后的原因吗?
由于
答案 0 :(得分:4)
是的,你可以这样写:
tests.put(new String[][] {{"a"}, {"a"}}, true);
这通常被称为匿名数组或实时数组。
答案 1 :(得分:4)
在您的情况下,您必须使用
tests.put(new String[][]{{"a"}, {"a"}}, true);
因为您注意到{{"a"}, {"a"}}
String[][] hi = {{"a"}, {"a"}};
只能在创建对数组的引用时使用。
答案 2 :(得分:1)
您可以使用
tests.put(new String[][]{{"hello", "goodbye"},{"hi", "bye"}}, true);
答案 3 :(得分:1)
这几乎肯定是不是你想要的。
Java中的数组从Object
获取它们的相等和哈希码 - 也就是说,基于它们的引用标识。所以:
String[] a = { "hello" }; // create one array
String[] b = { "hello" }; // create a different array with the same contents
assert a != b; // the two references are to different objects
assert ! a.equals(b); // they're not equal
assert a.hashCode() != b.hashCode(); // neither are their hashes (probably)
a
和b
将不相等,并且它们的哈希码几乎肯定不相等,因为它们是不同的对象。这意味着如果您使用数组作为哈希映射的键,您将无法使用键来检索值,而是使用您创建它的确切值:任何其他数组将具有不同的哈希代码并且将是不平等的,因此不会被视为等同的关键。
解决方案是将String[][]
替换为List<List<String>>
。列表根据其内容定义相等和哈希码,因此包含[ "hello" ]
的列表等于包含[ "hello" ]
的任何其他列表:
List<String> x = Arrays.asList("hello");
List<String> y = Arrays.asList("hello");
assert x != y; // the two lists are different objects
assert x.equals(y); // but they're equal
assert x.hashCode() == y.hashCode(); // and so are their hash codes
现在您可以将列表用作键。请记住,一旦列表是地图的关键,就不允许更改值。这样做可能会破坏哈希映射,因为列表的哈希代码会发生变化,但是地图不会知道它,所以地图会在错误的哈希桶中查找它。
这里最简单的选择是:
对于第二个选项,它类似于:
// copy the outer list
List<List<String>> outerCopy = new ArrayList<List<String>>( originalList );
ListIterator<List<String>> listIterator = outerCopy.listIterator();
while (listIterator.hasNext()) {
// make a copy of the inner list
List<String> innerCopy = new ArrayList<String>( listIterator.next() );
listIterator.set(innerCopy);
}