[英]How to implement toString() for collections?
我經常需要打印列表或地圖,但我不喜歡其默認toString()
方法的輸出。 例如HashMap#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();
}
}
正如你所看到的,我已經重復的代碼,這是因為,
部分需要進行一次省略。 那么,如何在沒有重復代碼的情況下將其重寫為一種快速有效的方法呢?
使用布爾值可以輕松解決:
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();
不要擴展HashMap
而是在HashMap.toString()
上使用String.subString()
方法
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 = value-1,key-2 = value-2,key-3 = value-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();
}
我只是檢查了AbstractCollection
的來源,就這樣完成了:
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(", ");
}
}
}
這看起來很聰明,循環中只有一個檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.