zhuguowei
zhuguowei

Reputation: 8487

java8 convert string array to map(odd index is key, even index is value)

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

Answers (4)

Eran
Eran

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

Bohemian
Bohemian

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

Yuriy Tumakha
Yuriy Tumakha

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

CoronA
CoronA

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

Related Questions