gpt4 book ai didi

java - 组、收集器、映射(整数到字符串)、映射(映射到对象)

转载 作者:行者123 更新时间:2023-11-30 02:13:04 26 4
gpt4 key购买 nike

这是我上一个问题的延续 Group, Sum byType then get diff using Java streams .

按照建议,我应该作为单独的线程发布,而不是更新原始线程。

因此,通过我之前的一组问题,我已经实现了这一点,现在,随着继续。

背景:

我有以下数据集

Sample(SampleId=1, SampleTypeId=1, SampleQuantity=5, SampleType=ADD), 
Sample(SampleId=2, SampleTypeId=1, SampleQuantity=15, SampleType=ADD),
Sample(SampleId=3, SampleTypeId=1, SampleQuantity=25, SampleType=ADD),
Sample(SampleId=4, SampleTypeId=1, SampleQuantity=5, SampleType=SUBTRACT),
Sample(SampleId=5, SampleTypeId=1, SampleQuantity=25, SampleType=SUBTRACT)
Sample(SampleId=6, SampleTypeId=2, SampleQuantity=10, SampleType=ADD),
Sample(SampleId=7, SampleTypeId=2, SampleQuantity=20, SampleType=ADD),
Sample(SampleId=8, SampleTypeId=2, SampleQuantity=30, SampleType=ADD),
Sample(SampleId=9, SampleTypeId=2, SampleQuantity=15, SampleType=SUBTRACT),
Sample(SampleId=10, SampleTypeId=2, SampleQuantity=35, SampleType=SUBTRACT)

我目前正在使用这个:

sampleList.stream()
.collect(Collectors.groupingBy(Sample::getTypeId,
Collectors.summingInt(
sample -> SampleType.ADD.equalsIgnoreCase(sample.getSampleType())
? sample.getSampleQuantity() :
-sample.getSampleQuantity()
)));

还有这个

sampleList.stream()
.collect(Collectors.groupingBy(Sample::getSampleTypeId,
Collectors.collectingAndThen(
Collectors.groupingBy(Sample::getSampleType,
Collectors.summingInt(Sample::getSampleQuantity)),
map -> map.getOrDefault(SampleType.ADD, 0)
- map.getOrDefault(SampleType.SUBTRACT, 0))));

作为接受的答案,以将所需的输出分组到 Map<Long, Integer> 中:

{1=15, 2=10}

因此,我想知道是否可以将其扩展到更多内容。

首先,我怎样才能让它返回 Map<String, Integer>而不是原来的Map<Long, Integer> 。基本上,对于 SampleTypeId; 1 代表 HELLO,2 代表 WORLD。

所以我需要像 .map (或者可能是其他函数)通过​​调用函数(如 convertType(sampleTypeId))将数据从 1 转换为 HELLO,将 2 转换为 WORLD ?。因此预期输出将是 {"HELLO"=15, "WORLD"=10} 。是对的吗?我应该如何编辑当前建议的解决方案?

最后,我想知道是否也可以将其返回到对象而不是Map 。假设我有一个对象; SummaryResult with (String) name and (int) result 。所以它返回 List<SummaryResult>而不是原来的Map<Long, Integer> 。我如何使用.map (或其他)功能来做到这一点?或者还有其他方法可以做到这一点吗?预期的输出将是沿着这条线的。

SummaryResult(name="hello", result=15), 
SummaryResult(name="world", result=10),

非常感谢 @M 之前给出的步骤解释。普罗霍罗夫。

更新:

更新后

sampleList.stream()
.collect(Collectors.groupingBy(sample -> convertType(sample.getSampleTypeId()),
Collectors.collectingAndThen(
Collectors.groupingBy(Sample::getSampleType,
Collectors.summingInt(Sample::getSampleQuantity)),
map -> map.getOrDefault(SampleType.ADD, 0)
- map.getOrDefault(SampleType.SUBTRACT, 0))));

private String convertType(int id) {
return (id == 1) ? "HELLO" : "WORLD";
}

最佳答案

对于第一部分,考虑到你有方法

String convertType(int typeId)

您只需从此更改第一个分类器

groupingBy(SampleType::getTypeId)

到此

groupingBy(sample -> convertType(sample.getTypeId()))

其他一切保持不变。

后一种类型有点棘手,从技术上讲,它根本无法从与流相关的解决方案中受益。

您需要的是:

public List<SummaryResult> toSummaryResultList(Map<String, Integer> resultMap) {
List<SummaryResult> list = new ArrayList<>(resultMap.size());
for (Map.Entry<String, Integer> entry : resultMap.entrySet()) {
String name = entry.getKey();
Integer value = entry.getValue();

// replace below with construction method you actually have
list.add(SummaryResult.withName(name).andResult(value));
}
return list;
}

您可以使用它作为收集器组合的一部分,您的整个收集器将被包装到 collectingAndThen 中。调用:

collectingAndThen(
groupingBy(sample -> convertType(sample.getTypeId()),
collectingAndThen(
groupingBy(Sample::getSampleType,
summingInt(Sample::getSampleQuantity)),
map -> map.getOrDefault(SampleType.ADD, 0)
- map.getOrDefault(SampleType.SUBTRACT, 0))),
result -> toSummaryResultList(result))

但是,正如您所看到的,它是整个收集器被包装的,所以在我看来,上面的版本对于下面使用中间变量,但并不是一堵代码墙:

// do the whole collecting thing like before
Map<String, Integer> map = sampleList.stream()
.collect(Collectors.groupingBy(sample -> convertType(sample.getTypeId()),
Collectors.collectingAndThen(
Collectors.groupingBy(Sample::getSampleType,
Collectors.summingInt(Sample::getSampleQuantity)),
map -> map.getOrDefault(SampleType.ADD, 0)
- map.getOrDefault(SampleType.SUBTRACT, 0))));

// return the "beautified" result
return toSummaryResultList(map);

上面要考虑的另一点是:convertType方法将被调用与 sampleList 中的元素一样多的次数,所以如果 convertType调用是“重”的(例如,使用数据库或IO),那么最好将其作为 toSummaryResultList 的一部分来调用转换,而不是作为流元素分类器。在这种情况下,您将从 Map<Integer, Integer> 类型的 map 中收集数据仍然,并使用 convertType循环内。我不会添加任何考虑到这一点的代码,因为我认为此更改微不足道。

关于java - 组、收集器、映射(整数到字符串)、映射(映射到对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49541062/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com