如何将String []转换为Map,并将数组索引转换为java lambda中的求和值?

时间:2017-10-25 21:56:54

标签: arrays algorithm lambda java-8 hashmap

我有以下

new ConstructStateMachine(new String[] {
      "a", "b", "c", "aa", "d", "b"
}, 1, 5);

我想将此数组转换为 Map<String, Integer>

这样字符串将数组中的字符串元素作为我的映射中的键,并且该值将作为整数列表作为值的数组的索引。

我还需要保留重复键,但当然这在Map中是不可能的,但解决方案是我们忽略重复键,但我们将重复键的值总结为,而不是使用List而是将Integer作为值使用重复键的所有值的总和。

假设我们有这张表:

indices | 0 | 1 | 2 | 3  | 4 | 5 |
item    | a | b | c | aa | d | b |
value   | 1 | 2 | 3 | 4  | 5 | 6 |

所以我们的地图应该保留以下内容:

// pseudo-code
Map<String, Integer> dictionary = new HashMap<>(
   ("b"  => 8) // because "b" appeared in index 1 and 5
   ("c"  => 3)
   ("aa" => 4)
   ("d"  => 5)
);

我的不完整解决方案:

Map < String, List < Integer >> table = new HashMap < > ();


// I thought of doing an intersection of two arrays and get the value from there
// but that just made things more complicated
String[] a = (Arrays.stream(dictionary)
  .filter(x - > Arrays.stream(newDis)
    .anyMatch(y - > Objects.equals(y, x))
  )
).toArray(String[]::new);


// in here, I tried looping and created the value that starts from 1 to 6, rather than
// from 0 to 5
IntStream.range(0, this.newDis.length).forEach(idx - > {
  List<Integer> currentValue = table.computeIfAbsent(newDis[idx], k - > new ArrayList<>());
  currentValue.add(idx + 1);
});

但我只是无法将我的字符串数组转换为Map<String, Integer>

1 个答案:

答案 0 :(得分:5)

String[] array = new String[] {"a", "b", "c", "aa", "d", "b"};
Map<String, Integer> result =
    IntStream.range(0, array.length)
             .boxed()
             .collect(Collectors.toMap(i -> array[i], i -> i + 1, Integer::sum));

或者,通过一个简单的循环,使代码更加直观,直观,IMO:

Map<String, Integer> result = new HashMap<>();
for (int i = 0; i < array.length; i++) {
    result.merge(array[i], i + 1, Integer::sum);
}