显示String和ArrayList的HashMap

时间:2013-08-09 09:37:34

标签: java arraylist hashmap

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

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

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

{ , 1.element1 2.element2 }

问题:

  1. 为什么第一个元素为空?
  2. 为什么两个元素之间没有昏迷?
  3. 功能:

    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 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

来自HashMap apidoc:

  

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

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

 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方法。

最好使用接口而不是实现适用接口的类。它使您的代码更加灵活 - 例如如果由于某种原因要将ArrayList替换为LinkedList,则只需要在初始化语句中替换,而不是在代码中全部替换。

相关方法apidoc链接:

答案 2 :(得分:0)

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

  • One List = Empty (它必须为空且不为null,否则您将获得NPE)
  • 其他清单= 1.element1,2.element2

对于HashMap,键的迭代顺序与它们的插入顺序不同。

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

如果您想按照广告订单的顺序进行迭代,请查看LinkedHashMap

至于元素之间的逗号:

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

应该这样做。虽然你可能想要一个特殊的第一个元素检查,如果你不希望你的列表打印为ele1,ele2,

答案 3 :(得分:0)

由于您正在使用错误构造的模式,因此导致空白空间。你从额外的空间" { "开始,在第一次运行中你跳过for,然后是你有下一个项目的versifier并追加","。所以你有了 ” { ,”。在下一次运行中,您输入循环并添加空间索引和值。

注意String类型用于存储文字而不是修改。请改用StringBuilder。我允许自己快速重写代码并添加针对NullPointer的修复和避免空的逻辑。

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();
}