2017-08-31 42 views
-1

我已经创建了一个哈希映射,它组合了三个参数(即customer,sc和admin)的唯一键。我想用连接的服务器列表创建一个唯一的密钥列表。我已经实现了以下内容:如何迭代哈希映射的结果,其中值是列表?

public static void main(String[] args) { 

     String items = "customer1^sc1^admin1|server1~" + 
       "customer1^sc1^admin1|server2~" + 
       "customer1^sc1^admin1|server3~" + 
       "customer2^sc1^admin1|server1~" + 
       "customer3^sc1^admin1|server3~" + 
       "customer3^sc1^admin1|server2~"; 

     // Set up raw data 
     List<String> splitItems = Arrays.asList(items.split("\\s*~\\s*")); 

     // Display raw data 
     System.out.println("Raw List: " + items); 

     // Create a hash map containing customer name as key and list of logs as value 
     HashMap<String, List<String>> customerHashMap = new HashMap<>(); 

     // Loop through raw data 
     for (String item : splitItems) { 

      // Create new lists. One for customers and one for logs 
      // List<String> customerList = new ArrayList<>(); 
      List<String> logList; 

      String list[] = item.split("\\|"); 

      String customer = list[0]; 
      String log = list[1]; 

      logList = customerHashMap.get(customer); 
      if (logList == null){ 
       logList = new ArrayList<>(); 
       customerHashMap.put(customer, logList); 
      } 

      logList.add(log); 
      // System.out.println(logList); 
     } 

     // Print out of the final hash map. Customer "a" should only have "a" logs, customer "b" with "b", etc. 
     System.out.println(""); 
     List<String> hashMapList = new ArrayList<String>(); 
     Iterator it = customerHashMap.entrySet().iterator(); 
     while (it.hasNext()) { 
      Map.Entry pair = (Map.Entry) it.next(); 
      String output = pair.getKey() + "|" + pair.getValue().toString(); 
      hashMapList.add(output); 
      it.remove(); 
     } 

     String hashMapResultString = hashMapList.toString(); 
     String hashMapResultFormatted = hashMapResultString.replaceAll("[\\[\\]]", ""); 
     System.out.println(hashMapResultFormatted); 

    } 

初始名单:customer1^sc1^admin1|server1~customer1^sc1^admin1|server2~customer1^sc1^admin1|server3~customer2^sc1^admin1|server1~customer3^sc1^admin1|server3~customer3^sc1^admin1|server2~

哈希地图搜索字符串:

customer2^sc1^admin1|server1, customer3^sc1^admin1|server3, server2, customer1^sc1^admin1|server1, server2, server3 

我现在想用哈希表来创建一个字符串,将进一步解析(不要问大声笑)。所以我将哈希映射的键和值设置为一个字符串,用一个独特的分隔符|分隔它们。问题在于,因为密钥是List<String>,所以当打印时,如果其值是包含多个项目的列表,则我无法确定每个新的key的开始,即customer3^sc1^admin1|server3, server2,紧接着是customer1^sc1^admin1|server1, server2, server3。我需要一个分隔符来区分它们。

我的理想的输出应该是这样的:

customer2^sc1^admin1|server1~customer3^sc1^admin1|server3, server2~customer1^sc1^admin1|server1, server2, server3~... 

我怎样才能做到这一点?

更新:

这是我最终找到了我的特殊问题有用的答案:

StringBuilder s = new StringBuilder(); 
for(Map.Entry<String,List<String>> entry : map.entrySet()) { 
    s.append(entry.getKey() + "\n"); 
    List<String> list = entry.getValue(); 
    for(String item : list) { 
     s.append(" " + item + "\n"); 
    } 
} 
return s.toString(); 

为:

StringBuilder s = new StringBuilder(); 
     for (Map.Entry<String, List<String>> entry : customerHashMap.entrySet()) { 
      s.append(entry.getKey() + "|"); 
      List<String> list = entry.getValue(); 
      for (String item : list) { 
       if (item != list.get(list.size() - 1)) { 
        s.append(item + "^"); 
       } else { 
        s.append(item); 
       } 
      } 
      s.append("~"); 
     } 
     System.out.println(s.toString()); 
+0

你好像误解了'HashMap >'这里是List的值,而不是关键字(如标题所示) – azro

+0

抱歉。糟糕的错字。你会发现在问题本身中我更一致。 – santafebound

回答

1

您可以通过地图的条目集迭代为了更清晰的例子,我输出了与你所要求的格式不同的格式,但是这说明了如何使用列表v的地图alues。在适应您的需求时,请看java.util.StringJoiner和相关Collectors.joining();它可能很有用。


流可以很方便的位置:

String encoded = map.entrySet().stream() 
    .map(entry -> entry.getValue().stream() 
       .collect(Collectors.joining("^")) 
      + "|" + entry.getKey()) 
    .collect(Collectors.joining("~")); 

这里发生的是:

  • 我们得到的Entry<String,List<String>流出来的图
  • 的拉姆达​​转换的每个条目成val1^v2^v3^...^valN|key的形式的字符串,即我们正在将Stream<Entry<>>映射到Stream<String>
  • 最后的collect()使用~作为分隔符将字符串串连接成单个字符串。
+0

我认为这里的解决方案是在出现其他字符后去除**下一个字符**,即在每个''〜''之后移除** next **'',''。 – santafebound

+0

@santafebound你正在谈论关于逗号加入列表的一般问题。最好不要添加不需要的分隔符,比添加它们然后删除它们更好。看看StringJoiner的源代码 - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/StringJoiner.java - 它们做得很整齐办法。 – slim

+0

@santafebound但如果你只是想要的效果,使用StringJoiner而不是写自己的 - 这就是它的用途。 – slim