我尝试在 Java 8 流 API 中找到一种简单的方法来进行分组。
Path caminho = Paths.get(System.getProperty("user.dir"), "log.txt");
Files.lines(caminho, StandardCharsets.ISO_8859_1)
.map(linha -> {
return getUrl(linha);
})
.filter(url -> url != null)
.collect(
Collectors.groupingBy(Arquivo::getUrl,
LinkedHashMap::new, Collectors.counting() ),
Collectors.groupingBy(Arquivo::getStatusCode,
LinkedHashMap::new, Collectors.counting()));
这可能吗?
最佳答案
您没有描述您的用例,因此一个可能的答案是您可以将两个属性分组到一个映射中,假设这些属性没有重叠值,如果它们具有不同的类型,情况总是如此:
Path caminho = Paths.get(System.getProperty("user.dir"), "log.txt");
LinkedHashMap<Object, Long> map = Files.lines(caminho, StandardCharsets.ISO_8859_1)
.map(linha -> getUrl(linha))
.filter(Objects::nonNull)
.flatMap(arquivo -> Stream.of(arquivo.getUrl(), arquivo.getStatusCode()))
.collect(Collectors.groupingBy(Function.identity(),
LinkedHashMap::new, Collectors.counting() ));
对于生成的映射,任一键的查找都会成功,并且迭代它也会产生正确的顺序,您只需跳过您不感兴趣的类型的键。
如果两个属性具有相同的类型,例如String
,并且可能有重叠的值,包括标记会有所帮助:
Map<Boolean, LinkedHashMap<String, Long>> map
= Files.lines(caminho, StandardCharsets.ISO_8859_1)
.map(linha -> getUrl(linha))
.filter(Objects::nonNull)
.flatMap(arquivo -> Stream.of(Arrays.asList(arquivo.getUrl(), true),
Arrays.asList(arquivo.getStatusCode(), false)))
.collect(Collectors.partitioningBy(l -> (Boolean)l.get(1),
Collectors.groupingBy(l -> (String)l.get(0),
LinkedHashMap::new, Collectors.counting() )));
LinkedHashMap<String, Long> urls = map.get(true);
LinkedHashMap<String, Long> status = map.get(false);
这不仅解决了重叠问题,而且还为您提供了两个不同的映射,但不幸的是,如果两个属性具有不同的类型,它就不会那么顺利地工作。
关于java - 我尝试在 Java 8 流 API 中找到一种简单的方法来进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44081733/