首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java toString() 方法深度解析:集合、Map、StringBuilder 等核心類實現原理

     編輯:Java 相關知識

問題背景

項目中需將 ArrayList<ArrayList<Integer>> 轉為格式化字符串:[[1,2,3],[2,3,5]] → "[1,2,3]#[2,3,5]"。直接調用 toString() 發現輸出為 [1, 2]#[2, 3](逗號後有空格),不符合預期。

Collection.toString() 源碼分析

@Override
public String toString() {
    if (isEmpty()) return "[]";
    
    StringBuilder buffer = new StringBuilder(size() * 16);
    buffer.append('[');
    Iterator<?> it = iterator();
    while (it.hasNext()) {
        Object next = it.next();
        if (next != this) {
            buffer.append(next);
        } else {
            buffer.append("(this Collection)");
        }
        if (it.hasNext()) {
            buffer.append(", ");  // 關鍵:逗號+空格分隔
        }
    }
    buffer.append(']');
    return buffer.toString();
}

關鍵發現

  • 元素間固定使用 ", "(逗號+空格)分隔
  • 自引用檢測:若元素是集合本身,輸出 (this Collection) 避免無限遞歸

驗證自引用行為

ArrayList<Object> c = new ArrayList<>();
c.add(1);
c.add(2);
c.add(c); // 將集合加入自身
System.out.println(c); // 輸出: [1, 2, (this Collection)]

解決方案

無法修改 JDK 源碼時,可後處理字符串:

String result = list.toString().replaceAll(" ", "");
// "[1, 2]#[2, 3]" → "[1,2]#[2,3]"

核心類 toString() 實現對比

Object 基類

public String toString() {
    return getClass().getName() + '@' + Integer.toHexString(hashCode());
}
// 輸出示例: java.lang.Object@e23e786

未重寫時返回:類全名 + @ + 哈希碼十六進制

String / StringBuilder / StringBuffer

類實現邏輯線程安全效能
String直接返回 this不可變,天然安全N/A
StringBuilder調用父類 AbstractStringBuilder.toString()非線程安全高
StringBuffer調用父類 AbstractStringBuilder.toString(),方法同步線程安全較低

選擇建議

  • 單線程大量拼接:StringBuilder
  • 多線程環境:StringBuffer

Map.toString() 實現

public String toString() {
    Iterator<Entry<K,V>> i = entrySet().iterator();
    if (!i.hasNext()) return "{}";
    
    StringBuilder sb = new StringBuilder();
    sb.append('{');
    for (;;) {
        Entry<K,V> e = i.next();
        K key = e.getKey();
        V 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(' '); // 同樣使用逗號+空格
    }
}

輸出格式:{key1=value1, key2=value2}

最佳實踐總結

  1. 理解各類 toString() 默認格式(特別是分隔符)
  2. 自定義類務必重寫 toString() 提供業務含義
  3. 需要特定格式時,後處理或手動構建字符串
  4. 調試時善用 IDE 的 toString 生成功能
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved