java中的 toString()方法例項程式碼

NO IMAGE

前言:

      toString()方法 相信大家都用到過,一般用於以字串的形式返回物件的相關資料。

  最近專案中需要對一個ArrayList<ArrayList<Integer>> datas  形式的集合處理。

  處理要求把集合資料轉換成字串形式,格式為 :子集合1資料 “#” 子集合2資料 “#” …. 子集合n資料。

  舉例: 集合資料 :[[1,2,3],[2,3,5]]  要求轉成為 “[1,2,3]#[2,3,5]” 形式的字串

  第一次是這樣處理的:


ArrayList<ArrayList<Object>> a = new ArrayList<>();  // 打造這樣一個資料的集合 [[1,2],[2,3]] 要求 生成字串 [1,2]#[2,3]
for (int i = 0; i < 2; i  ) { 
ArrayList<Object> c = new ArrayList<>();
c.add(i 1);
c.add(i 2);
a.add(c);
//列印單個子集合的字串形式資料
Log.i("myinfo",c.toString());
}
StringBuilder builder = new StringBuilder();
builder.append(a.get(0).toString() "#" a.get(1).toString());
//列印該集合的字串形式資料
Log.i("myinfo",builder.toString());

  然後看該處理下的Log日誌:

05-12 10:29:18.485 9565-9565/com.xxx.aaa I/myinfo: [1, 2]
05-12 10:29:18.485 9565-9565/com.xxx.aaa I/myinfo: [2, 3]
05-12 10:29:18.495 9565-9565/com.xxx.aaa I/myinfo: [1, 2]#[2, 3]

   我們會發現我們想要的是[1,2]#[2,3]形式的字串,但是結果是[1, 2]#[2, 3]  ,在第二個值開始往後,前面都多了一個空格。

   接下來我們檢視 集合下的.toString()方法的原始碼:

   翻譯一下官方解釋:

   1、返回這個Collection類(Set和List的父類) 的字串表現形式

       2、這個表現形式有一個規定的格式,被矩形括號”[]”包含

       3、裡面的子元素被“, ”(逗號和空格)分割 (這是重點)


/**
* Returns the string representation of this {@code Collection}. The presentation
* has a specific format. It is enclosed by square brackets ("[]"). Elements
* are separated by ', ' (comma and space).
*
* @return the string representation of this {@code Collection}.
*/
@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();
}

  分析這個Collection下的.toString()方法原始碼,分為幾個部分:

  1、判斷集合是不是空(empty),即集合內有沒有資料。如果是空值(沒有資料)的話,直接返回字串 “[]”

      2、如果集合不是空值,說明有資料

    ①、迭代取下一個子元素(Object next = it.next()),如果這個子元素是集合本身,新增”(this Collection)”到StringBuffer類的buffer物件中

    ②、如果這個子元素不是集合本身,新增到buffer物件中

    ③、如果這個子元素下面還有子元素,則新增”, “到buffer物件中去,用於分割兩個相鄰子元素

  3、返回StringBuffer.toString()字串

  由此可見,返回[1, 2]#[2, 3]是官方正確的返回形式,那麼對於這個問題,其實在改不了原始碼的情況下 給得到的字串後面使用.replaceAll(” “,””); 把字串中的空格都去掉

  注意:原始碼中有一段程式碼:         


if (next != this) {
buffer.append(next);
} else {
buffer.append("(this Collection)");
}

  這裡可能有些同學看不懂,這裡舉個例子,還是上面的那個,我們在子集合裡面 新增程式碼 c.add(c); 將集合本身新增到集合中去,看看列印結果


ArrayList<ArrayList<Object>> a = new ArrayList<>();
for (int i = 0; i < 2; i  ) {
ArrayList<Object> c = new ArrayList<>();
c.add(i 1);
c.add(i 2);
c.add(c);
//列印單個子集合的字串形式資料
Log.i("myinfo",c.toString());
}

看日誌結果中紅色部分,是不是看懂了,如果集合中的子元素是集合本身,就將”(this Collection)” 新增到返回集合中

05-12 10:58:00.615 8424-8424/com.maiji.magkarepatient I/myinfo: [1, 2, (this Collection)]
05-12 10:58:00.615 8424-8424/com.maiji.magkarepatient I/myinfo: [2, 3, (this Collection)]  

  至此,上面這個問題解決了,下面我們看下其他類下的.toString()原始碼。

一、Object


/**
* Returns a string containing a concise, human-readable description of this
* object. Subclasses are encouraged to override this method and provide an
* implementation that takes into account the object's type and data. The
* default implementation is equivalent to the following expression:
* <pre>
*  getClass().getName()   '@'   Integer.toHexString(hashCode())</pre>
* <p>See <a href="{@docRoot}reference/java/lang/Object.html#writing_toString">Writing a useful
* {@code toString} method</a>
* if you intend implementing your own {@code toString} method.
*
* @return a printable representation of this object.
*/
public String toString() {
return getClass().getName()   '@'   Integer.toHexString(hashCode());
}

  翻譯一下官方解釋:

  1、返回一個對於這個Object 簡明的、可讀的 的字串

  2、Object類的子類被鼓勵去重寫這個方法來提供一個實現用於描述物件的型別和資料

  3、預設的執行形式和下面這個例子一致


getClass().getName()   '@'   Integer.toHexString(hashCode())</pre>

  綜上:當你的一個類中沒有重寫.toString()方法的時候就會執行根類Object的這個.toString()方法。

     返回形式:物件的類名 @ 雜湊值的16進位制


getClass().getName()返回物件所屬類的類名
hashCode()返回該物件的雜湊值
Integer.toHexString(hashCode())將物件的雜湊值用16進製表示

 舉例:


Object d = new Object();
Log.i("myinfo",d.toString());

05-12 11:23:00.758 17406-17406/com.maiji.magkarepatient I/myinfo: [email protected]

二、String,StringBuilder,StringBuffer

  三個都是字串的表現形式,但是有區別的

  ①、String.toString()  , 直接返回本身


/**
* Returns this string.
*/
@Override
public String toString() {
return this;
}

  ②、StringBuilder

   官方解釋:以字串的形式 返回這個builder物件的內容


/**
* Returns the contents of this builder.
*
* @return the string representation of the data in this builder.
*/
@Override
public String toString() {
/* Note: This method is required to workaround a compiler bug
* in the RI javac (at least in 1.5.0_06) that will generate a
* reference to the non-public AbstractStringBuilder if we don't
* override it here.
*/
return super.toString();
}

  追溯到super.toString()實現


/**
* Returns the current String representation.
*
* @return a String containing the characters in this instance.
*/
@Override
public String toString() {
if (count == 0) {
return "";
}
return StringFactory.newStringFromChars(0, count, value);
}

  ③、StringBuffer


@Override
public synchronized String toString() {
return super.toString();
}

  追溯到super.toString()


/**
* Returns the current String representation.
*
* @return a String containing the characters in this instance.
*/
@Override
public String toString() {
if (count == 0) {
return "";
}
return StringFactory.newStringFromChars(0, count, value);
}

  綜上我們發現,StringBuffer和StringBuilder最終都呼叫了父級  “AbstractStringBuilder” 中的toString()方法

  但是他們本身的toString()卻有所不同,我們由此可以總結

  1、StringBuilder:執行緒非安全的

     StringBuffer:執行緒安全的

      2、StringBuilder 處理速度要比 StringBudiler 快的多

  3、單執行緒大量資料操作,用StringBuilder  ,因為 StringBuilder速度快 , 因為單執行緒所以不考慮安全性

      多執行緒大量資料操作,用StringBuffer   ,  因為StringBuffer安全

三、Map

  先看原始碼:

  可以看到返回的形式是{key1=value1, key2=value2}

  注意   1、當Map集合中沒有資料的時候 返回{}

     2、每兩個資料之前用”, “分割,和Collection一致,一個逗號、一個空格

       3、當鍵值是集合本身的時候,新增  (this Map)


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(' ');
}
}

  舉例:    


Map<String,String> map = new HashMap<>();
map.put("keyA","valueA");
map.put("keyB","valueB");
map.put("keyC","valueC");
Log.i("myinfo",map.toString());

列印結果:


05-12 11:41:30.898 4490-4490/com.maiji.magkarepatient I/myinfo: {keyA=valueA, keyB=valueB, keyC=valueC}

以上所述是小編給大家介紹的java中的 toString()方法例項程式碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對指令碼之家網站的支援!

您可能感興趣的文章:

Java中區別.toString() ,(String),valueOf()方法java中的equals()和toString()方法例項詳解淺談Java程式設計ToString()方法重寫的意義