3 回答
TA贡献1851条经验 获得超5个赞
要实现这一点,有两种方法:
如果存在具有相同名称的条目,则继承
ArrayList
并覆盖添加方法并添加逻辑以求和权重。
@JsonDeserialize
在反序列化 JSON 时使用。首选哪个选项,为什么?
顺便说一下,您不应该使用这些方法中的任何一种。见下文:
add()
应避免覆盖执行计算的方法。您可以利用流来处理已添加到列表中的数据。Jackson 应该只用于 JSON 解析,而不用于执行业务逻辑。
事实上,您应该做的是在控制器层接收 JSON,将其解析为列表,然后委托给服务层,您将在服务层执行分组和求和操作。
此外,重要的是要提到您必须避免在计算中同时使用Float
和Double
类型,因为它们在精度方面存在问题。改用BigDecimal
。
最后,这是您的分组和求和方法BigDecimal
:
public List<B> groupByNameAndSumWeight(List<B> list) {
return list.stream()
.collect(groupingBy(B::getName, reducing(BigDecimal.ZERO, B::getWeight, BigDecimal::add)))
.entrySet().stream()
.map(entry -> new B(entry.getKey(), entry.getValue()))
.collect(toList());
}
并确保您具有以下静态导入:
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.reducing;
import static java.util.stream.Collectors.toList;
TA贡献1801条经验 获得超8个赞
您可以处理服务中的对象列表或创建解释器来处理对象列表,而不是使用自定义实现来添加或使用 @JsonDeserialize。您可以将以下代码添加到进程列表中,
objects = objects.stream().collect(Collectors.groupingBy(B::getName, Collectors.summingDouble(B::getWeight))) .entrySet().stream().map(ele-> new B(ele.getKey(), ele.getValue())) .collect(Collectors.toList());
希望能帮助到你。
TA贡献1810条经验 获得超4个赞
这听起来像是区分控制器和服务层的基本原因。让控制器接受纯列表并将其交给进行处理的服务。
@Controller class MyController {
@Autowired MyService service;
@PostMapping(..) void postList(@Body List<B> items) {
service.accept(items);
}
}
在服务中,您可以添加权重。
@Service class MyService {
JpaRepository<B> repository;
public void accept(List<B> items) {
List<B> summed =
items.stream().collect(groupingBy(B::getName, summarizingDouble(B::getWeight)))
.entrySet().stream().map(e -> new B(e.getKey(), e.getValue()))
.collect(toList());
repository.save(summed);
}
}
添加回答
举报