2014-09-03 68 views
0

我經常需要打印列表或地圖,但我不喜歡其默認方法toString()的輸出。例如HashMap#toString()輸出是這樣的:如何爲集合實現toString()?

{key-1=value-1, key-2=value-2, key-3=value-3} 

但我想輸出是這樣的:

key-1 = value-1, key-2 = value-2, key-3 = value-3 

我創建的延伸HashMap自定義類和寫我自己toString()方法,這導致我真正的問題:

public final class CustomMap<K, V> extends HashMap<K, V> { 

    private static final long serialVersionUID = 1493227382148892732L; 

    @Override 
    public String toString() { 
     final StringBuilder builder = new StringBuilder(); 

     final Iterator<Map.Entry<K, V>> entryIterator = entrySet().iterator(); 

     if (entryIterator.hasNext()) { 
      final Map.Entry<K, V> entry = entryIterator.next(); 

      builder.append(entry.getKey()); 
      builder.append(" = "); 
      builder.append(entry.getValue()); 
     } 

     while (entryIterator.hasNext()) { 
      final Map.Entry<K, V> entry = entryIterator.next(); 

      builder.append(", "); 
      builder.append(entry.getKey()); 
      builder.append(" = "); 
      builder.append(entry.getValue()); 
     } 

     return builder.toString(); 
    } 

} 

正如你所看到的,我已經重複的代碼,因爲,面值噸必須被省略一次。那麼我怎樣才能將它重寫爲無重複代碼的快速有效的方法呢?

回答

0

我只是檢查了源程序的AbstractCollection e和那裏就像下面這樣:

public final class CustomMap<K, V> extends HashMap<K, V> { 

    /** 
    * Serial version UID. 
    */ 
    private static final long serialVersionUID = 1493227382148892732L; 

    @Override 
    public String toString() { 
     final Iterator<Map.Entry<K, V>> entryIterator = entrySet().iterator(); 

     if (!entryIterator.hasNext()) { 
      return ""; 
     } 

     final StringBuilder builder = new StringBuilder(); 

     for (;;) { 
      final Map.Entry<K, V> entry = entryIterator.next(); 

      builder.append(entry.getKey()); 
      builder.append(" = "); 
      builder.append(entry.getValue()); 

      if (!entryIterator.hasNext()) { 
       return builder.toString(); 
      } 

      builder.append(", "); 
     } 
    } 

} 

這看起來很聰明,也只有一個迴路檢查。

2

,可以用布爾迎刃而解:

final Iterator<Map.Entry<K, V>> entryIterator = entrySet().iterator(); 
    boolean first = true; 
    while (entryIterator.hasNext()) { 
     final Map.Entry<K, V> entry = entryIterator.next(); 
     if (!first) 
      builder.append(", "); 
     else 
      first=false; 
     builder.append(entry.getKey()); 
     builder.append(" = "); 
     builder.append(entry.getValue()); 
    } 

另一種選擇是使用Java 8 StringJoiner:

StringJoiner sj = new StringJoiner(","); 
    while (entryIterator.hasNext()) { 
     final Map.Entry<K, V> entry = entryIterator.next(); 
     sj.add(entry.getKey() + " = " + entry.getValue()); 
    } 
    return sj.toString(); 
+0

但是,每個循環都有一個額外的檢查。難道它不會讓大集合變慢嗎? – stevecross 2014-09-03 12:39:37

+0

@feuerball這可以忽略不計。 – Eran 2014-09-03 12:42:53

+0

另一種方法是,每次添加逗號時都會包括第一個逗號,然後在循環播放集合項目的同時,刪除最後一個逗號。 – Atul 2014-09-03 12:45:36

0

不要延伸HashMap而使用String.subString()方法上HashMap.toString()

String s=yourMap.toString();//eg-"{key-1=value-1, key-2=value-2, key-3=value-3}" 
System.out.println(s.substring(1,s.length()-1)); 

輸出: -key-1 =值1,鍵2 =值2,鍵3 =值-3

或者

創建方法來刪除最後一個逗號

public StringBuilder removeComma(StringBuilder sbf) { 
       if (sbf.charAt(sbf.length() - 1) == ',') { 
        sbf.deleteCharAt(sbf.length() - 1); 
       } 
       return sbf; 
      } 


public String toString() { 
     final StringBuilder builder = new StringBuilder(); 
     final Iterator<Map.Entry<K, V>> entryIterator = entrySet().iterator(); 
     while (entryIterator.hasNext()) { 
      final Map.Entry<K, V> entry = entryIterator.next(); 
      builder.append(entry.getKey()).append(" = ").append(entry.getValue()).append(","); 
     } 
     return removeComma(builder).toString(); 
     } 

另一個選項使用可變

public String toString() { 
       String comma="";//initaly empty 
       final StringBuilder builder = new StringBuilder(); 
       final Iterator<Map.Entry<K, V>> entryIterator = entrySet().iterator(); 
       while (entryIterator.hasNext()) { 
        final Map.Entry<K, V> entry = entryIterator.next(); 
        builder.append(comma).append(entry.getKey()).append(" = ").append(entry.getValue()); 
        comma=",";//set value of comma 
       } 
       return removeComma(builder).toString(); 
       }