首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java HashSet 直接列印輸出內容的原理:AbstractCollection.toString 實作解析

     編輯:程式設計疑難解答

現象

Set<String> set = new HashSet<>();
set.add("A"); set.add("B");
System.out.println(set); // 輸出: [A, B]

開發者疑惑:HashSet 未覆寫 toString(),為何能直接列印內容?

繼承鏈追蹤

HashSet → AbstractSet → AbstractCollection → Object
  • HashSet、AbstractSet 均未覆寫 toString()。
  • AbstractCollection 提供預設實作:
// java.util.AbstractCollection
public String toString() {
    Iterator<E> it = iterator();
    if (!it.hasNext()) return "[]";
    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = it.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (!it.hasNext()) return sb.append(']').toString();
        sb.append(',').append(' ');
    }
}

關鍵點

  1. 依賴 iterator():所有 Collection 子類必須實作 iterator(),AbstractCollection.toString() 透過迭代器遍歷元素。
  2. 遞迴防護:e == this 檢測自我引用,避免無限遞迴(如 list.add(list))。
  3. 格式固定:[elem1, elem2, ...],元素間以 , 分隔。

Map 同理

AbstractMap.toString() 同樣提供預設實作,格式為 {key1=value1, key2=value2},依賴 entrySet().iterator()。

實務建議

  • 大型集合直接 toString() 可能產生超大字串導致 OOM,除錯時建議用 set.stream().limit(100).collect(Collectors.toList()) 截取前 N 筆。
  • 自訂集合類別若繼承 AbstractCollection,免費獲得合理的 toString();若繼承 Object 需自行實作。

總結

HashSet 能直接列印,是因為繼承自 AbstractCollection,後者提供了基於 Iterator 的通用 toString() 實作。這是集合框架「模板方法模式」的經典應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved