拆分字符串并将其存储到 HashMap java 8
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41483398/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
split string and store it into HashMap java 8
提问by Sangam Belose
I want to split below string and store it into HashMap.
我想拆分下面的字符串并将其存储到 HashMap 中。
String responseString = "name~peter-add~mumbai-md~v-refNo~";
first I split the string using delimeter hyphen (-) and storing it into ArrayList as below:
首先,我使用分隔符连字符 (-) 拆分字符串并将其存储到 ArrayList 中,如下所示:
public static List<String> getTokenizeString(String delimitedString, char separator) {
final Splitter splitter = Splitter.on(separator).trimResults();
final Iterable<String> tokens = splitter.split(delimitedString);
final List<String> tokenList = new ArrayList<String>();
for(String token: tokens){
tokenList.add(token);
}
return tokenList;
}
List<String> list = MyClass.getTokenizeString(responseString, "-");
and then using the below code to convert it to HashMap using stream.
然后使用以下代码使用流将其转换为 HashMap。
HashMap<String, String> = list.stream()
.collect(Collectors.toMap(k ->k.split("~")[0], v -> v.split("~")[1]));
The stream collector doesnt work as there is no value against refNo.
流收集器不起作用,因为没有针对 refNo 的值。
It works correctly if I have even number of elements in ArrayList.
如果我在 ArrayList 中有偶数个元素,它就可以正常工作。
Is there any way to handle this? Also suggest how I can use stream to do these two tasks (I dont want to use getTokenizeString() method) using stream java 8.
有没有办法处理这个?还建议我如何使用流 java 8 使用流来完成这两个任务(我不想使用 getTokenizeString() 方法)。
采纳答案by Holger
Unless Splitter
is doing any magic, the getTokenizeString
method is obsolete here. You can perform the entire processing as a single operation:
除非Splitter
做任何魔术,否则该getTokenizeString
方法在这里已过时。您可以将整个处理作为单个操作执行:
Map<String,String> map = Pattern.compile("\s*-\s*")
.splitAsStream(responseString.trim())
.map(s -> s.split("~", 2))
.collect(Collectors.toMap(a -> a[0], a -> a.length>1? a[1]: ""));
By using the regular expression \s*-\s*
as separator, you are considering white-space as part of the separator, hence implicitly trimming the entries. There's only one initial trim
operation before processing the entries, to ensure that there is no white-space before the first or after the last entry.
通过使用正则表达式\s*-\s*
作为分隔符,您将空格视为分隔符的一部分,因此隐式修剪条目。trim
在处理条目之前只有一个初始操作,以确保在第一个条目之前或最后一个条目之后没有空格。
Then, simply split the entries in a map
step before collecting into a Map
.
然后,map
在收集到一个Map
.
回答by Eran
First of all, you don't have to split the same String
twice.
Second of all, check the length of the array to determine if a value is present for a given key.
首先,您不必将相同的内容拆分String
两次。
其次,检查数组的长度以确定给定键是否存在值。
HashMap<String, String> map=
list.stream()
.map(s -> s.split("~"))
.collect(Collectors.toMap(a -> a[0], a -> a.length > 1 ? a[1] : ""));
This is assuming you want to put the key with a null
value if a key has no corresponding value.
这是假设null
如果键没有对应的值,您想为键放置一个值。
Or you can skip the list
variable :
或者您可以跳过list
变量:
HashMap<String, String> map1 =
MyClass.getTokenizeString(responseString, "-")
.stream()
.map(s -> s.split("~"))
.collect(Collectors.toMap(a -> a[0], a -> a.length > 1 ? a[1] : ""));
回答by Mohamed.Abdo
private final String dataSheet = "103343262,6478342944, 103426540,84528784843, 103278808,263716791426, 103426733,27736529279,
103426000,27718159078, 103218982,19855201547, 103427376,27717278645,
103243034,81667273413";
final int chunk = 2;
AtomicInteger counter = new AtomicInteger();
Map<String, String> pairs = Arrays.stream(dataSheet.split(","))
.map(String::trim)
.collect(Collectors.groupingBy(i -> counter.getAndIncrement() / chunk))
.values()
.stream()
.collect(toMap(k -> k.get(0), v -> v.get(1)));
result:
结果:
pairs =
"103218982" -> "19855201547"
"103278808" -> "263716791426"
"103243034" -> "81667273413"
"103426733" -> "27736529279"
"103426540" -> "84528784843"
"103427376" -> "27717278645"
"103426000" -> "27718159078"
"103343262" -> "6478342944"
We need to group each 2 elements into key, value pairs, so will partion the list into chunks of 2, (counter.getAndIncrement() / 2) will result same number each 2 hits ex:
我们需要将每 2 个元素分组为键、值对,因此将列表分成 2 个块, (counter.getAndIncrement() / 2) 将导致每 2 个命中相同的数字,例如:
IntStream.range(0,6).forEach((i)->System.out.println(counter.getAndIncrement()/2));
prints:
0
0
1
1
2
2
You may use the same idea to partition list into chunks.
您可以使用相同的想法将列表分成块。
回答by Vishwa Ratna
Another short way to do :
另一种简短的方法:
String responseString = "name~peter-add~mumbai-md~v-refNo~";
Map<String, String> collect = Arrays.stream(responseString.split("-"))
.map(s -> s.split("~", 2))
.collect(Collectors.toMap(a -> a[0], a -> a.length > 1 ? a[1] : ""));
System.out.println(collect);
First you split the String on basis of -
, then you map like map(s -> s.split("~", 2))
it to create Stream<String[]>
like [name, peter][add, mumbai][md, v][refNo, ]
and at last you collect it to toMap
as a[0]
goes to key and a[1]
goes to value.
首先,您根据 拆分字符串-
,然后将map(s -> s.split("~", 2))
它映射为创建Stream<String[]>
like [name, peter][add, mumbai][md, v][refNo, ]
,最后将其收集到toMap
asa[0]
转到键和a[1]
转到值。