Reputation: 8487
Now I have a String array,
String[] a= {"from","[email protected]","to","[email protected]","subject","hello b"};
from command line arguments.
I want to convert it to Map,
{"from":"[email protected]","to":"[email protected]","subject":"hello b"}
Does exist convenient manner in java8 to achieve this? Now my way is
Map<String,String> map = new HashMap<>();
for (int i = 0; i < args.length; i+=2) {
String key = args[i].replaceFirst("-+", ""); //-from --> from
map.put(key, args[i+1]);
}
Upvotes: 4
Views: 2973
Reputation: 393856
You can use an IntStream
to iterate on the indices of the array (which is required in order to process two elements of the array each time) and use the Collectors.toMap
collector.
The IntStream
will contain a corresponding index for each pair of elements of the input array. If the length of the array is odd, the last element will be ignored.
Map<String,String> map =
IntStream.range(0,a.length/2)
.boxed()
.collect(Collectors.toMap(i->a[2*i].replaceFirst("-+", ""),
i->a[2*i+1]));
Upvotes: 14
Reputation: 425073
The trick is to first join the string, then split it up into key/value pairs, then the task is simple:
Map<String,String> map = Arrays.stream(
String.join(",", a)
.split(",(?!(([^,]*,){2})*[^,]*$)"))
.map(s -> s.split(","))
.collect(Collectors.toMap(s -> s[0], s -> s[1]))
;
Upvotes: -1
Reputation: 1570
In Java 8 you can use Stream.iterate
to divide list to sublists of 2 elements
String[] a= {"from","[email protected]","to","[email protected]","subject","hello b"};
Map<String, String> map = Stream.iterate(
Arrays.asList(a), l -> l.subList(2, l.size()))
.limit(a.length / 2)
.collect(Collectors.toMap(
l -> l.get(0).replaceFirst("-+", ""),
l -> l.get(1))
);
Another recursive solution using simple Iterator
Map<String, String> map = buildMap(new HashMap<>(), Arrays.asList(a).iterator());
private static Map<String, String> buildMap(
Map<String, String> map, Iterator<String> iterator) {
if (iterator.hasNext()) {
map.put(iterator.next().replaceFirst("-+", ""), iterator.next());
createMap(map, iterator);
}
return map;
}
Upvotes: 1
Reputation: 8075
You can do this quite elegant with Javaslang:
String[] a= {"from","[email protected]","to","[email protected]","subject","hello b"};
Map<String, String> map = Stream.of(a).grouped(2) // use javaslang.collection.Stream here
.map(group -> group.toJavaArray(String.class))
.toJavaStream() // this is the plain old java.util.Stream
.collect(toMap(tuple -> tuple[0], tuple -> tuple[1]));
The grouped
function groups your stream in groups of 2 elements. These can be transformed to string arrays and those can be the base of a Map
. Probably Javaslang allows you to do even more elegant.
Upvotes: 1