1. 編寫一個單元測試類
@Test
public void tt() {
Map<Object, Object> map = new HashMap<>();
map.put("11", "aaaa");
map.put("22", "bbbb");
map.put("33", "cccc");
map.put("44", "dddd");
System.out.println(map);
System.out.println("--------------- 改裝map.toString方法測試 start ---------------");
long btime1 = System.currentTimeMillis();
String str = toString2(map);
System.out.println(str);
long etime1 = System.currentTimeMillis();
System.out.println("共花費了: "+(etime1-btime1) + " milliseconds");
System.out.println("--------------- 改裝map.toString方法測試 end ---------------");
System.out.println("--------------- map.toString 源碼方法測試 start ---------------");
long etime2 = System.currentTimeMillis();
String str2 = toString3(map);
System.out.println(str2);
long btime2 = System.currentTimeMillis();
System.out.println("共花費了: "+(etime2-btime2) + " milliseconds");
System.out.println("--------------- map.toString 源碼方法測試 end ---------------");
}
2.通過源碼我們找到了代碼實現(如下:)
通過源碼解讀,我們可以知道,map.toString()方法主要是
通過map的迭代器判斷集合是否有值,如果沒有值就直接返回,如果有值我們就通過for(;;) 死循環 和
StringBuilder (不需要考慮線程安全問題, 並且考慮到效率,所以使用StringBuilder 不使用StringBuffer)
字符串緩衝區的拼接,最後加一個判斷,當遊標遍歷到最後一個說明沒有值了,直接返回字符串數據.
4 思考:於是看到這裏,我們就去想源碼拿出來 再把for(;;) 死循環 換成 while(true)進行測試
(最終代碼實現)
@Test
public void tt() {
Map<Object, Object> map = new HashMap<>();
map.put("11", "aaaa");
map.put("22", "bbbb");
map.put("33", "cccc");
map.put("44", "dddd");
System.out.println(map);
System.out.println("--------------- 改裝map.toString方法測試 start ---------------");
long btime1 = System.currentTimeMillis();
String str = toString2(map);
System.out.println(str);
long etime1 = System.currentTimeMillis();
System.out.println("共花費了: "+(etime1-btime1) + " milliseconds");
System.out.println("--------------- 改裝map.toString方法測試 end ---------------");
System.out.println("--------------- map.toString 源碼方法測試 start ---------------");
long etime2 = System.currentTimeMillis();
String str2 = toString3(map);
System.out.println(str2);
long btime2 = System.currentTimeMillis();
System.out.println("共花費了: "+(etime2-btime2) + " milliseconds");
System.out.println("--------------- map.toString 源碼方法測試 end ---------------");
}
public String toString2(Map<Object, Object> map) {
Iterator<Map.Entry<Object, Object>> i = map.entrySet().iterator();
if (!i.hasNext()) return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
while (true) {
Map.Entry<Object, Object> e = i.next();
Object key = e.getKey();
Object value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (!i.hasNext()) return sb.append('}').toString();
sb.append(',').append(' ');
}
}
/**
* @param map
* @return
*/
public String toString3(Map<Object, Object> map) {
Iterator<Map.Entry<Object, Object>> i = map.entrySet().iterator();
if (!i.hasNext())
return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
for (; ; ) {
Map.Entry<Object, Object> e = i.next();
Object key = e.getKey();
Object value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (!i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
}
5.測試結果如下:
測試結果:失敗
總結: (1) map.toString 是通過 迭代器 和 StringBuilder(字符串緩衝區) 和 for(;;) 死循環實現的;
(2) for(;;) 死循環的效率 比 white(true) 死循環的效率高;