Fix circular reference support in toString of collection classes (#552)

This commit is contained in:
Ivan Hetman 2021-01-11 20:32:44 +02:00 committed by GitHub
parent 66ce993019
commit 8122095193
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 77 additions and 4 deletions

View File

@ -56,6 +56,10 @@ class TAbstractStringBuilder extends TObject implements TSerializable, TCharSequ
length = value.length();
}
public TAbstractStringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
protected TAbstractStringBuilder append(String string) {
return insert(length, string);
}

View File

@ -32,6 +32,11 @@ public class TStringBuffer extends TAbstractStringBuilder implements TAppendable
super(value);
}
@Override
public TStringBuffer append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public TStringBuffer append(String string) {
super.append(string);

View File

@ -32,6 +32,11 @@ public class TStringBuilder extends TAbstractStringBuilder implements TAppendabl
super(value);
}
@Override
public TStringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public TStringBuilder append(String string) {
super.append(string);

View File

@ -142,15 +142,17 @@ public abstract class TAbstractCollection<E> extends TObject implements TCollect
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append('[');
TIterator<E> iter = iterator();
if (iter.hasNext()) {
sb.append(String.valueOf(iter.next()));
E e = iter.next();
sb.append(e == this ? "(this Collection)" : iter.next());
}
while (iter.hasNext()) {
sb.append(", ").append(String.valueOf(iter.next()));
E e = iter.next();
sb.append(", ").append(e == this ? "(this Collection)" : iter.next());
}
sb.append("]");
sb.append(']');
return sb.toString();
}
}

View File

@ -265,6 +265,28 @@ public abstract class TAbstractMap<K, V> extends TObject implements TMap<K, V> {
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('{');
TIterator<TMap.Entry<K, V>> iter = entrySet().iterator();
if (iter.hasNext()) {
TMap.Entry<K, V> e = iter.next();
sb.append(e.getKey() == this ? "(this Map)" : e.getKey());
sb.append('=');
sb.append(e.getValue() == this ? "(this Map)" : e.getValue());
}
while (iter.hasNext()) {
sb.append(", ");
TMap.Entry<K, V> e = iter.next();
sb.append(e.getKey() == this ? "(this Map)" : e.getKey());
sb.append('=');
sb.append(e.getValue() == this ? "(this Map)" : e.getValue());
}
sb.append('}');
return sb.toString();
}
@Override
protected Object clone() throws TCloneNotSupportedException {
TAbstractMap<?, ?> copy = (TAbstractMap<?, ?>) super.clone();

View File

@ -195,4 +195,19 @@ public class TArrayList<E> extends TAbstractList<E> implements TCloneable, TSeri
action.accept(array[i]);
}
}
@Override
public String toString() {
if (size == 0) {
return "[]";
}
int length = size - 1;
StringBuilder buffer = new StringBuilder(size * 16);
buffer.append('[');
for (int i = 0; i < length; i++) {
buffer.append(array[i] == this ? "(this Collection)" : array[i]).append(", ");
}
buffer.append(array[length] == this ? "(this Collection)" : array[length]);
return buffer.append(']').toString();
}
}

View File

@ -174,4 +174,14 @@ public class ArrayListTest {
assertEquals("A1", list.get(0));
assertEquals("B1", list.get(1));
}
@Test
public void testToString() {
List list = new ArrayList<>();
list.add(list);
list.add("A");
assertEquals("[(this Collection), A]", list.toString());
assertEquals("[]", new ArrayList().toString());
}
}

View File

@ -550,4 +550,14 @@ public class LinkedHashMapTest {
}
assertTrue("Entries left to iterate on", !it2.hasNext());
}
@Test
public void test_to_String() {
LinkedHashMap lhm = new LinkedHashMap();
lhm.put("A", lhm);
lhm.put("B", "C");
assertEquals("{A=(this Map), B=C}", lhm.toString());
assertEquals("{}", new LinkedHashMap().toString());
}
}