亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將 json 對象反序列化為具有與 ArrayList 不同行為的列表的最佳方法是什么

將 json 對象反序列化為具有與 ArrayList 不同行為的列表的最佳方法是什么

月關寶盒 2023-06-14 16:01:31
我的 REST 服務正在接受一個class A包含objects B. 所需對象的行為是,如果有一些重復的條目,則需要添加權重。使用jackson序列化/反序列化要實現這一點,有兩種方法:如果存在具有相同名稱的條目,則繼承ArrayList并覆蓋添加方法并添加邏輯以求和權重。@JsonDeserialize在反序列化 JSON 時使用。首選哪個選項,為什么?class A {  List<B> objects;  // Getters and Setters}class B {  String name;  Float weight;  boolean equals() {    // compares name.  }}示例 JSON{objects:[{name:"X", weight:10.2},{name:"Y",weight:12.5},{name:"X", weight:20}]}這應該產生一個大小為 2 的對象列表,其值為name:X,weight:30.2 and name:Y,weight:12.5.
查看完整描述

3 回答

?
江戶川亂折騰

TA貢獻1851條經驗 獲得超5個贊

要實現這一點,有兩種方法:

  1. 如果存在具有相同名稱的條目,則繼承ArrayList并覆蓋添加方法并添加邏輯以求和權重。

  2. @JsonDeserialize在反序列化 JSON 時使用。

首選哪個選項,為什么?

順便說一下,您不應該使用這些方法中的任何一種。見下文:

  1. add()應避免覆蓋執行計算的方法。您可以利用流來處理已添加到列表中的數據。

  2. Jackson 應該只用于 JSON 解析,而不用于執行業務邏輯。

事實上,您應該做的是在控制器層接收 JSON,將其解析為列表,然后委托給服務層,您將在服務層執行分組和求和操作。

此外,重要的是要提到您必須避免在計算中同時使用FloatDouble類型,因為它們在精度方面存在問題。改用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;


查看完整回答
反對 回復 2023-06-14
?
蝴蝶刀刀

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());

希望能幫助到你。


查看完整回答
反對 回復 2023-06-14
?
蝴蝶不菲

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);

    }

}


查看完整回答
反對 回復 2023-06-14
  • 3 回答
  • 0 關注
  • 152 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號