I often need to print lists or maps, but I don't like the output of their default toString()
methods. For example HashMap#toString()
outputs something like this:
{key-1=value-1, key-2=value-2, key-3=value-3}
But I would like the output to be like this:
key-1 = value-1, key-2 = value-2, key-3 = value-3
I created a custom class that extends HashMap
and wrote my own toString()
method, which leads to my real problem:
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();
}
}
As you can see, I have repeating code, because the ,
part has to be omitted once. So how can I rewrite this as an fast and efficient method without duplicate code?
That can be easily solved with a boolean :
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());
}
Another option is to use 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();
Don't extends HashMap
rather use String.subString()
method on 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));
Output: -key-1=value-1, key-2=value-2, key-3=value-3
Or
Create method to remove last comma
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();
}
Another option Using a variable-
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();
}
I just checked the source of AbstractCollection
and there it is done like this:
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(", ");
}
}
}
This looks very clever and there is only one check in the loop.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.