簡體   English   中英

Java-8:流還是更簡單的解決方案?

[英]Java-8: stream or simpler solution?

我有兩個模型,一個List<ModelA> ,我想將它轉換為List<ModelB> 這是我的模特:

class ModelA {

    private Long id;
    private String name;
    private Integer value;

    public ModelA(Long id, String name, Integer value) {
        this.id = id;
        this.name = name;
        this.value = value;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Integer getValue() {
        return value;
    }
}

class ModelB {
    private Long id;
    private Map<String, Integer> valuesByName;

    public ModelB(Long id, Map<String, Integer> valuesByName) {
        this.id = id;
        this.valuesByName = valuesByName;
    }

    public Long getId() {
        return id;
    }

    public Map<String, Integer> getValuesByName() {
        return valuesByName;
    }
}

實際解決方案

public static List<ModelB> convert(List<ModelA> models) {
        List<ModelB> toReturn = new ArrayList<>();
        Map<Long, Map<String, Integer>> helper = new HashMap<>();
        models.forEach(modelA -> {
            helper.computeIfAbsent(modelA.getId(), value -> new HashMap<>())
                    .computeIfAbsent(modelA.getName(), value -> modelA.getValue());
        });
        helper.forEach((id, valuesByName) -> toReturn.add(new ModelB(id,valuesByName)));
        return toReturn;
    }

但我認為有一個更簡單的解決方案,您是否知道如何在單個流中執行此操作,或以某種方式簡化它?

編輯 :我想澄清我不能使用java9,我需要通過Id-s然后按名稱對它們進行分組。 如果在ModelB中我有4個具有相同id的元素,我不想要ModelA的新實例。

我已將兩個操作組合在一起,但仍構建中間映射,因為您需要為給定的id 分組所有名稱,值對。

models.stream()
        .collect(Collectors.groupingBy(model -> model.getId(), //ModelA::getId - Using method reference
                Collectors.toMap(model -> model.getName(), model -> model.getValue(), (map1, map2) -> map1)))
        .entrySet()
        .stream()
        .map(entry -> new ModelB(entry.getKey(), entry.getValue()))
        .collect(Collectors.toList());

編輯:

我錯過了(map1, map2) -> map1初始答案中的(map1, map2) -> map1 這是需要避免覆蓋已經存在的valueidname (第二個相當於computeIfAbsent在你的代碼),您需要選擇其中一個(或米格它們),因為默認情況下它會拋出IllegalStateException時,發現重復鍵。

使用Stream中map函數很容易實現:

public static List<MobelB> convert(List<ModelA> models) {
  Map<Long, Map<String, Integer>> modelAMap = models.stream()
    .collect(Collectors.toMap(ModelA::getId, modelA -> computeMap(modelA)));

  return models.stream()
    .map(modelA -> new ModelB(modelA.getId(), modelAMap.get(modelA.getId())))
    .collect(Collectors.toList());
}

private static Map<String, Integer> computeMap(ModelA model) {
  Map<String, Integer> map = new HashMap<>();
  map.put(model.getId(), model.getName());
  return map;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM