我有一张定义为
的地图HashMap<Object, Object> hashMap;
现在我需要遍历每一对并打印键和值。执行key.toString()
和value.toString()
适用于ArrayList
等类型。但是数组上的toString()
不会给出可读字符串。
我知道Arrays.toString()
。但是我不能在我的情况下使用它,因为Arrays.toString()
期望一个对象数组,而我拥有的只是一个对象。所以我写了一个自定义代码,看起来像,
private String convertToHumanReadableFormat(Object value) {
if (value == null) return "N/A";
if (value.getClass().isArray()) {
return convertArrayToReadableFormat(value);
}
return value.toString();
}
private String convertArrayToReadableFormat(Object value) {
String output = "[";
int arrayLength = Array.getLength(value);
for (int i = 0; i < arrayLength; i++) {
Object element = Array.get(value, i);
if (element != null) {
if (element.getClass().isArray()) {
output += convertArrayToReadableFormat(element);
}
else {
output += element.toString();
}
}
if ((i + 1) < arrayLength)
output += ", ";
}
output += "]";
return output;
}
我实际上正在重复Arrays.deepToString()
所做的事情。但我看不到使用Arrays.toString()
或Arrays.deepToString()
的方法。
这是解决问题的正确方法,还是有办法让这些标准方法适合我?
任何帮助都会很棒。
答案 0 :(得分:1)
请将方法convertToHumanReadableFormat
修改为以下内容。我测试过它确实有效。
private <T> String convertToHumanReadableFormat(Object value) {
if (value == null) return "N/A";
if (value.getClass().isArray()) {
if( value instanceof int[]||value instanceof long[]){
List<T> list = new ArrayList<T>();
list.addAll((Collection<? extends T>) Arrays.asList(value));
return convertToHumanReadableFormat(list.toArray());
}else{
return Arrays.deepToString((Object[]) value);
}
}
return value.toString();
}
您可以将其他原始类型添加到if条件中。
答案 1 :(得分:0)
如果将数组转换为list然后使用toString -
,该怎么办? Arrays.asList(array)
您将需要以这种方式编写助手方法 -
private String convertToHumanReadableFormat(Object value) {
if (value == null) return "N/A";
if (value.getClass().isArray()) {
value = Arrays.asList((Object[])value);
}
return value.toString();
}
要处理原语,首先需要手动将数组转换为列表 -
private String convertToHumanReadableFormat(Object value) {
if (value == null) return "N/A";
if (value.getClass().isArray()) {
//convert array to list
int count = Array.getLength(value);
ArrayList<Object> list = new ArrayList<Object>();
for(int i=0; i<count; i++){
list.add(Array.get(value, i));
}
return list.toString(); //or value=list;
}
return value.toString();
}
答案 2 :(得分:0)
您可以考虑几种方法 -
答:如果你不是严格的格式,只想以人类可读的方式打印HashMap内容,我建议你使用JSon序列化 - 输出如果人类可读。
你可以看到我们在Ovirt开源项目中做了什么(克隆了引擎项目的git repo) - engine \ backend \ manager \ modules \ utils \ src \ main \ java \ org \ \ ovirt \ engine \ core \ utils \ serialization \ json - 查看那里的JsonObjectSerializer类。
B.如果您对格式有严格要求 - 您应该获取地图的entrySet,迭代它,然后将对象插入ArrayList。之后,您可以使用toArray()方法返回一个数组,并使用上面描述的方法。
请记住,我建议你的ArrayList是一个字符串的ArrayList,所以你必须取每个mapEntry并翻译它的字符串,考虑toString()并查看它产生的格式是否足够好。
答案 3 :(得分:0)
如果你使用case是以人类可读的形式呈现数组和其他对象图,你可以去模板解决方案(比如freemarker的速度)或者将它们转换为JSON(或XML)并且rpetty pring it - 我会推荐GSON / XStream为了这个任务。
如果您希望将其用于调试目的,那么只需坚持使用日志系统并使用那里提供的标准转换器(例如在log4j中)
答案 4 :(得分:0)
您可以使用9个instanceof语句来调用相应的toString或deepToString方法。如果您确实使用自己的代码,请记住使用StringBuilder并考虑包含对自身或父维度的引用的数组的可能性。目前你的代码会递归,直到堆栈溢出。正如我所建议的那样使用instanceof也可以避免代码中固有的原始值的装箱(从而提高性能)。九个陈述不是太多,是吗?
if (val instanceof Object[]) return Arrays.deepToString((Object[]) val);
if (val instanceof byte[]) return Arrays.toString((byte[]) val);
// Repeat for other 7 array types...