我正在阅读Hashtable的代码。我对toString()
方法感到困惑,代码是这样的:
public synchronized String toString()
{
int max = size() - 1;
if (max == -1)
return "{}";
StringBuilder sb = new StringBuilder();
Iterator<Map.Entry<K,V>> it = entrySet().iterator();
sb.append('{');
for (int i = 0; ; i++)
{
Map.Entry<K,V> e = it.next();
K key = e.getKey();
V value = e.getValue();
// Is "key == this" possible ? What the "this" stands for ?
sb.append(key == this ? "(this Map)" : key.toString());
sb.append('=');
sb.append(value == this ? "(this Map)" : value.toString());
if (i == max)
return sb.append('}').toString();
sb.append(", ");
}
}
那么,如果代码没有检查“key是否等于”,那么toString()方法可能是无限循环的吗?
答案 0 :(得分:3)
当然有可能:
Hashtable table = new Hashtable();
table.put(table, table);
System.out.println("table = " + table);
输出:
table = {(this Map)=(this Map)}
但请注意,此类映射的行为可能会令人惊讶(因为其哈希码和等号将发生变化)。例如,在下面的示例中,添加另一个条目后,您无法从自身中删除地图:
Hashtable table = new Hashtable();
table.put(table, table);
System.out.println("table = " + table);
table.put("abc", "def");
System.out.println("table = " + table);
table.remove(table); //does not work as expected !!!
System.out.println("table = " + table);
输出:
table = {(this Map)=(this Map)}
table = {abc=def, (this Map)=(this Map)}
table = {abc=def, (this Map)=(this Map)}
答案 1 :(得分:1)
这样,如果你将HashTable
放入自身,你就不会得到无限循环。考虑:
final Map map = new Hashtable();
map.put(map, "test");
答案 2 :(得分:0)
// Is "key == this" possible ? What the "this" stands for ?
'this keyword'指的是对象的当前实例。 “key == this”检查key是否指向对象当前的无效。
答案 3 :(得分:0)
是的。这个
HashTable<Object, Object> maptest = new HashTable<Object, Object>();
mapTest.put(mapTest, 1);
会key == this
返回true
答案 4 :(得分:0)
有可能将map
作为密钥保存在同一map
。
HashMap<Object, Object> selfmap = new HashMap<Object, Object>();
selfmap.put(selfmap, selfmap);
答案 5 :(得分:0)
如果key
和this
对象(如您所说的HashTable)引用等于,那么条件key == this
为true