Bug 274423 - [toString] toString wizard should support nested arrays
Summary: [toString] toString wizard should support nested arrays
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.5   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-04-29 16:33 EDT by Benjamin Muskalla CLA
Modified: 2009-05-11 03:44 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Benjamin Muskalla CLA 2009-04-29 16:33:02 EDT
I20090428-0100

Currently the toString wizard only supports simple arrays and ignores nested arrays.

Snippet:
---------------
public class A {
    int[][] a = new int[1][1];

    public static void main(String[] args) {
        A x = new A();
        x.a[0][0] = 1;
        System.out.println(x);
    }

}

---------------
Comment 1 Mateusz Matela CLA 2009-05-09 13:18:09 EDT
A simple solution would be to use Arrays.deepToString() instead of Arrays.toString() and change the helper method arrayToString() a bit to support multidimensional arrays. But this way we would still ignore arrays included in collections and maps. Also, with "Limit number of items..." option it might be worth to consider collections and maps containing other collections/maps. And here things get complicated. To support all these possibilities, the helper method would have to get long and clumsy:

public String toString(Object o, List<Object> seen, int maxLen) {
	if (seen == null) {
		seen = new ArrayList<Object>();
	} else if (seen.contains(o)) {
		return ("[...]");
	}
	seen.add(o);
	Object o2 = o;
	StringBuilder buf = new StringBuilder();
	buf.append(o instanceof Map<?, ?> ? "{" : "[");
	try {
		if (o == null) {
			return "null";
		} else if (o instanceof Collection<?>) {
			o2 = ((Collection<?>) o).toArray();
		} else if (o instanceof Map<?, ?>) {
			o2 = ((Map<?, ?>) o).entrySet().toArray();
		}
		Class<?> clazz = o2.getClass();
		for (int i = 0; i < maxLen; i++) {
			if (clazz.isArray()) {
				if (clazz == byte[].class) {
					buf.append(((byte[]) o2)[i]);
				} else if (clazz == short[].class) {
					buf.append(((short[]) o2)[i]);
				} else if (clazz == int[].class) {
					buf.append(((int[]) o2)[i]);
				} else if (clazz == long[].class) {
					buf.append(((long[]) o2)[i]);
				} else if (clazz == char[].class) {
					buf.append(((char[]) o2)[i]);
				} else if (clazz == float[].class) {
					buf.append(((float[]) o2)[i]);
				} else if (clazz == double[].class) {
					buf.append(((double[]) o2)[i]);
				} else if (clazz == boolean[].class) {
					buf.append(((boolean[]) o2)[i]);
				} else {
					buf.append(toString(((Object[]) o2)[i], seen, maxLen));
				}
			} else if (o2 instanceof Entry<?, ?>) {
				Entry<?, ?> e = (Entry<?, ?>) o2;
				return toString(e.getKey(), seen, maxLen) + "="
						+ toString(e.getValue(), seen, maxLen);
			} else {
				return o2.toString();
			}
			buf.append(", ");
		}
		buf.append("...");
	} catch (IndexOutOfBoundsException e) {
		if (buf.length() >= 2) {
			buf.setLength(buf.length() - 2);
		}
	} finally {
		seen.remove(o);
	}
	return buf.append(o instanceof Map<?, ?> ? "}" : "]").toString();
}

It would be possible in some circumstances to make this method shorter (when it can be determined that arrays will not contain collections and/or vice versa), but in general I don't see any simpler way.

What do you think?
Comment 2 Dani Megert CLA 2009-05-11 03:44:57 EDT
>A simple solution would be to use Arrays.deepToString() instead of
>Arrays.toString() 
This is not available in 1.4.

There's no hurry in this bug as we won't address it for 3.5 (we're in RC mode now).