如何迭代哈希映射的结果,其中值是列表?
我已经创建了一个哈希映射,它组合了三个参数(即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());
您可以通过地图的条目集迭代为了更清晰的例子,我输出了与你所要求的格式不同的格式,但是这说明了如何使用列表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()
使用~
作为分隔符将字符串串连接成单个字符串。
我认为这里的解决方案是在出现其他字符后去除**下一个字符**,即在每个''〜''之后移除** next **'',''。 – santafebound
@santafebound你正在谈论关于逗号加入列表的一般问题。最好不要添加不需要的分隔符,比添加它们然后删除它们更好。看看StringJoiner的源代码 - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/StringJoiner.java - 它们做得很整齐办法。 – slim
@santafebound但如果你只是想要的效果,使用StringJoiner而不是写自己的 - 这就是它的用途。 – slim
你好像误解了'HashMap>'这里是List的值,而不是关键字(如标题所示) –
azro
抱歉。糟糕的错字。你会发现在问题本身中我更一致。 – santafebound