使用Java的lambda和流将文本文件映射到Map上

问题描述 投票:0回答:1

所以我的文本文件包含5个字段,我想在我的文本文件中创建一个新的字段。Map<Pair<String, String>,List<List<String>>>的一个实例,其中Pair是Apache的 ImmutablePair5个字段中的2个字段为键,该Map的值将是一个 List<List<String>> 其中每个 List<String> 为键,将包含剩余的3个字段,所以如果文件会像。

A,B,1,2,3
A,C,4,5,9
A,B,3,4,5
A,C,5,6,7

结果Map会是这样的:

K:(A,B)
 V:((1,2,3),(3,4,5))
K:(A,C)
 V:((4,5,9),(5,6,7))

我试图通过尽可能多的使用lambdas和流来实现这个目标, 这是我的临时代码, 它的工作原理, 但它返回的值是整行:

  private Map<Pair<String, String>, List<List<String>>> createMultimapFromFile() {
    Map<Pair<String, String>, List<List<String>>> map = new BufferedReader(
        new InputStreamReader(getClass().getResourceAsStream(MAPING_FILENAME)))
        .lines()
        .map(line -> Arrays.asList(line.split(COMMA)))
        .filter(lineAsList -> lineAsList.size() == REQUIRED_FILE_LINE_LENGTH)
        .collect(Collectors.groupingBy(filteredLine ->
            ImmutablePair.of(filteredLine.get(1), filteredLine.get(2))));
    return map;
  }

这个调用 Collectors.groupingBy 利用 这个 植入,默认返回地图值为 List<T>但我希望但我找不到的是返回一个子列表,以节省内存空间。我的印象是 这个 是正确的方法,正如描述中所说... ... "然后使用指定的下游收集器对与给定键相关的值进行还原操作。" 只是找不到一个预制的收集器,我可以指定代码来最终确定列表。谁有什么提示?

java collectors
1个回答
1
投票

Collectors#mapping 会为你做工作。

try(BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(MAPING_FILENAME), "utf-8"))) {
  return reader.lines()
    .map(line -> line.split(","))
    .filter(lineAsList -> lineAsList.length == REQUIRED_FILE_LINE_LENGTH)
    .map(data -> Pair.of(ImmutablePair.of(data[0], data[1]), Arrays.asList(data[2], data[3], data[4])))
    .collect(Collectors.groupingBy(p -> p.getLeft(), Collectors.mapping(p -> p.getRight(), Collectors.toList())));
} catch (Exception e) {}

而Output会是这样的。

{(A,C)=[[4, 5, 9], [5, 6, 7]], (A,B)=[[1, 2, 3], [3, 4, 5]]}

Pair 是来自apache commons-lang库的元组。在这里使用只是为了保存值。你可以使用任何其他对象来实现这个目的。

或者,也可以这样写道

.map(data -> Pair.of(ImmutablePair.of(data[0], data[1]), Arrays.asList(data[2], data[3], data[4])))
.collect(Collectors.groupingBy(p -> p.getLeft(), Collectors.mapping(p -> p.getRight(), Collectors.toList())));

//without pair
.collect(Collectors.groupingBy(data -> ImmutablePair.of(data[0], data[1]), Collectors.mapping(data -> Arrays.asList(data[2], data[3], data[4]), Collectors.toList())));
© www.soinside.com 2019 - 2024. All rights reserved.