1

我得到了一个 String 和 arraylist 的 hashmap 作为值;当值为:

<StringA: {element1,element2}, StrinbB: {null}>

值的显示(即 ArrayList)总是从空元素开始。所以它看起来像:

{ , 1.element1 2.element2 }

问题:

  1. 为什么第一个元素是空的?
  2. 为什么两个元素之间没有昏迷?

功能:

public String printTableNames(HashMap<String, ArrayList<String>> Map) {

        HashMap<String, ArrayList<String>> map = Map;  
        String s="\n\t\t Tables: ";
        Iterator<Entry<String, ArrayList<String>>> iter = map.entrySet().iterator();

        s= s + " { ";
        while (iter.hasNext()) {
            Entry<String, ArrayList<String>> entry = iter.next();

            List<String> l = new ArrayList<String>();

            l = entry.getValue();
            String temp="";
            for (int i=1; i<=l.size(); i++){

                temp= temp +" "+ Integer.toString(i)+"."+l.get(i-1);
            }               
            s = s + temp;

            if (iter.hasNext()) {
                s=s+",";
            }
            else s=s+" }";
        }
        return s;

    }
4

4 回答 4

2

来自HashMapapidoc:

此类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

这就是为什么不按插入顺序打印值的原因。关于您的代码示例的一些评论,请考虑以下代码:

 Map<String, List<String>> map = new HashMap<String, List<String>>() {{
        put("a", Arrays.asList(new String[]{"1","2"}));
        put("b", Arrays.asList(new String[]{"4","3"}));
 }};

 System.out.println(Arrays.deepToString(map.entrySet().toArray()));

它输出:

[b=[4, 3], a=[1, 2]]

不需要写那么多循环:)(除非你坚持打印每个元素的序数,但在这种情况下还有其他解决方案)

请注意,我List在声明中使用了接口,HashMap它允许我Arrays.asList在初始化中使用该方法。

在适用的情况下,最好使用接口而不是实现接口的类。它使您的代码更加灵活 - 例如,如果您出于某种原因想要替换您ArrayListLinkedList,您只需要在初始化语句中替换,而不是整个代码。

相关方法apidoc链接:

于 2013-08-09T11:26:14.943 回答
1

它正在打印出你要求它做的事情。

一个关键点 - HashMap 在理论上被定义为没有设置顺序 - 您希望您的结果按照您插入的顺序打印出来,Java 实际上是以相反的顺序遍历它们。因此,您的打印输出显示“null”(未打印,以空字符串形式给出),然后是逗号,然后是下一个元素。

数组元素之间没有逗号,因为您没有在代码中放入逗号,而是在 HashMap 条目之间为逗号编码。为此更改此行:

temp= temp +" "+ Integer.toString(i)+"."+l.get(i-1);
if (i !=l.size()) temp += ',';
于 2013-08-09T09:59:33.233 回答
0

The empty space is cause because of wrongly constructed pattern that you are using. You start with additional space " { ", in first run you skip the for, then you versifier that has next item and append ",". So you have " { ,". In next run you enter to loop and add space index and value.

Note the String type was used to store literals not modify. Use StringBuilder instead. I allow myself to fast rewrite your code and added a fix against NullPointer and the logic to avoid empty.

public String printTableNames(Map<String, List<String>> map) {

    StringBuilder builder = new StringBuilder("\n\t\t Tables:");

    builder.append(" { "); 

    for(Iterator<Entry<String, List<String>>> mapIterator = map.entrySet().iterator(); mapIterator.hasNext();) {

        List<String> values = mapIterator.next().getValue();

        if(values != null && !values.isEmpty()) { //We do not operate on null and empty list 
            int i=0; //As we have if block we enclose this so we do not need expensive values.get(i-1) to fetch value. 
            for(String value : values) {
                builder.append(' ');
                builder.append(i++);
                builder.append(value);
            }

        } else { 
            continue; //We skip the empty comma 
        }

        if(mapIterator.hasNext()) {
            builder.append(',');
        } 

    }

    builder.append(" }");

    return builder.toString();
}
于 2013-08-09T11:00:42.980 回答
0

Output = { , 1.element1 2.element2 }告诉你有:

  • 一个列表 = 空(它必须为空且不为空,否则您将获得 NPE)
  • 其他列表 = 1.element1, 2.element2

因为HashMap键的迭代顺序与插入的顺序不同。

在您的情况下,首先迭代空列表,然后是第二个列表。

如果您想按插入顺序进行迭代,请查看LinkedHashMap

至于你的元素之间的逗号:

   temp= temp +" "+ Integer.toString(i)+"."+l.get(i-1) + ",";

应该做。虽然您可能想要放置一个特殊的第一个元素检查您是否不希望您的列表打印为ele1,ele2,

于 2013-08-09T09:41:15.797 回答