Java groupingBy 和转换字符串

Java groupingBy and transform Strings

我收到了一个字符串列表,我试图用 .groupingBy() 进行分区,这将给我一个 Map<String, List<String>>,并转换将要在列表中结束的字符串在地图上。

Examples I've found 使用 Collectors.mapping ,这是我想使用的,但所有示例都使用方法引用,例如 .mapping(SomeClass::getSomething, ... ,因为我正在对字符串进行操作, 做不到。

我想我可以使用 lambda 作为映射函数,但似乎无法获得正确的语法,最终出现“类型不匹配:无法转换...”错误。

这说明了我正在尝试做的事情

import java.util.*;
import java.util.stream.Collectors;

class Main
{
  public static void main(String[] args)
  {
        List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");
        System.out.println(inputs);

        Map<String, List<String>>
        outputs = inputs.stream()
              .collect(
                  Collectors.groupingBy(s -> s.startsWith("D") ? "desperate" : "serious")
                  //,Collectors.mapping(n -> Integer.valueOf(n.replaceAll("[DS]", "")), Collectors.toList())
              )
              ;

        System.out.println(outputs);
  }
}

这将创建地图,按我的预期对输入数据进行分组,并生成输出
{desperate=[D8, D2, D15], serious=[S1, S5, S9]}

但是我想要的,正如你可能从注释掉的行中猜到的那样
Collectors.mapping(n -> Integer.valueOf(n.replaceAll("[DS]", "")), Collectors.toList())
是一个 Map<String, List<Integer>> 包含通过删除前缀从字符串中提取的值。

我的实际用例可能会将一个字符串转换为另一个字符串,或者从更复杂的字符串中提取整数,但这说明了我正在尝试做的事情。

如何在分组时使用 lambda 函数进行映射?
我也不清楚我读过的例子中 Collectors.mapping 中第二个参数 toList() 的用法。

我用这段代码创建了一个 repl

Collectors.groupingBy() 有一个版本采用另一个收集器作为值,例如:

@Test
public void streamsTest() {
    List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");
    System.out.println(inputs);

    Map<String, List<Integer>> outputs = inputs.stream()
            .collect(
                    Collectors.groupingBy(
                            s -> s.startsWith("D") ? "desperate" : "serious",
                            Collectors.mapping(
                                    s -> Integer.valueOf(s.substring(1)),
                                    Collectors.toList())));

    System.out.println(outputs);
}

这会产生:

[D8, S1, S5, D2, D15, S9]
{desperate=[8, 2, 15], serious=[1, 5, 9]}

这类似于。不同的是,转化可以发生在群体之外,可以独立进化。

流、地图、群组

  1. 流式传输元素
  2. 使用 map 转换每个元素(这可以委托给单独的函数)
  3. 定义收集策略
  4. 基于收集策略分组
  5. 根据需要收集元素
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

class TransformAndGroupBy {

  public static void main(String[] args) {
    List<String> inputs = Arrays.asList("D8", "S1", "S5", "D2", "D15", "S9");

    System.out.println(inputs);

    Function<String, SimpleEntry<String, Integer>> transform = s -> s.startsWith("D")
      ? new SimpleEntry<>("desparate", Integer.parseInt(s.substring(1)))
      : new SimpleEntry<>("serious", Integer.parseInt(s.substring(1)));

    Map<String, List<Integer>> outputs = inputs.stream() // convert to stream
      .map(transform) // do the necessary transformation
      .collect(Collectors.groupingBy(e -> e.getKey(), Collectors.mapping(e -> e.getValue(), Collectors.toList()))); // group and collect as per the transformation
    System.out.println(outputs);
  }
}