【问题标题】:Get Map<String, List<Object>> from List<Object> where the key is one of the fields of the objects从 List<Object> 获取 Map<String, List<Object>> ,其中键是对象的字段之一
【发布时间】:2020-08-27 03:52:42
【问题描述】:

我有一个对象如下

public class Model {
    private String key;
    private String data1;
    private String data2;
    private String data3;

    // getters
}

这些模型的列表正在通过数据层返回。 现在我想创建一个Map&lt;String, List&lt;Model&gt;&gt;,其键是Modelclass 中的“键”字段。 有多个具有不同数据值的重复“键”。 我有以下现有解决方案,但需要一种更简单更好的方法。没有广泛使用 Java 8,因此对大多数方法不太熟悉,并且我没有时间研究,因此需要尽快解决。

List<Model> models = modelRepo.getAllModels();
Set<String> keys = models.stream().map(Model::getKey).collect(Collectors.toSet());

Map<String, List<Model>> result = new HashMap<>();
keys.stream().forEach(key -> {
    List<Model> modelList = new ArrayList<>();
    models.stream().forEach(model -> {
        if (model.getKey().equals(key)) {
            modelList.add(model);
        }
    });
    result.put(key, modelList);
});

【问题讨论】:

  • 你可能想要groupingBy
  • 那行得通。非常感谢@user。

标签: java dictionary lambda java-8 java-stream


【解决方案1】:

使用groupingBy 将模型按key 分组,返回地图

Map<String, List<Model>> results = models.stream()
            .collect(Collectors.groupingBy(Model::getKey));

groupingBy 方法,只接受一个函数作为参数。函数返回的值用作我们从 groupingBy 收集器获取的映射的键。

【讨论】:

  • 正确的想法,但不需要这个Collectors.mapping(d-&gt; d, Collectors.toList())
【解决方案2】:

对于初学者来说,优雅的方式是您可以在stream() 中使用groupBy。

Map<String, List<Model>> results = models.stream()
                                         .collect( Collectors.groupingBy(Model::getKey));

如果你不愿意使用stream(),而且你提到你没有广泛使用Java 8,所以对大多数方法不太熟悉。使用循环总是有传统的方法。

    Map<String,List<Model>> results = new HashMap<>(  );

    for( Model m : models )
    {
        if( results.containsKey( m.getKey() ) )
        {
            results.get( m.getKey() ).add( m );
        }
        else
        {
            results.put( m.getKey(), new ArrayList<>( Collections.singleton(m) ) );
        }
    }

【讨论】:

    【解决方案3】:

    首先,stream().forEach()可以替换成forEach(),只要不使用中间操作即可。

    您想要的是 Collectors.groupingBy 的典型用例,没有进一步的下游收集器:

    Map<String, List<Model>> result = models.stream()     // Stream<Model>
        .collect(Collectors.groupingBy(Model::getKey));   // Map<String, List<Model>>
    

    【讨论】:

      【解决方案4】:

      您可以使用 groupingBy:

      public class Test1 {
      
          public static void main(String[] args) {
              List<Model> models = new ArrayList<>();
              models.add(new Model("a", "a1", "a2", "a3"));
              models.add(new Model("a", "a4", "a5", "a6"));
              models.add(new Model("c", "c1", "c2", "c3"));
              models.add(new Model("d", "d1", "d2", "d3"));
              models.add(new Model("d", "d4", "d5", "d6"));
      
              Map<String, List<Model>> result = models.stream().collect(Collectors.groupingBy(Model::getKey));
      
              result.forEach((a, b) -> System.out.println(a + " - " + b));
          }
      
          public static class Model {
              private String key;
              private String data1;
              private String data2;
              private String data3;
      
              public Model(String key, String data1, String data2, String data3) {
                  this.key = key;
                  this.data1 = data1;
                  this.data2 = data2;
                  this.data3 = data3;
              }
      
              public String getKey() {
                  return key;
              }
      
              public void setKey(String key) {
                  this.key = key;
              }
      
              public String getData1() {
                  return data1;
              }
      
              public void setData1(String data1) {
                  this.data1 = data1;
              }
      
              public String getData2() {
                  return data2;
              }
      
              public void setData2(String data2) {
                  this.data2 = data2;
              }
      
              public String getData3() {
                  return data3;
              }
      
              public void setData3(String data3) {
                  this.data3 = data3;
              }
      
              @Override
              public String toString() {
                  return "Model{" +
                          "key='" + key + '\'' +
                          ", data1='" + data1 + '\'' +
                          ", data2='" + data2 + '\'' +
                          ", data3='" + data3 + '\'' +
                          '}';
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-22
        • 2021-04-29
        • 1970-01-01
        • 1970-01-01
        • 2019-04-06
        • 2018-04-26
        • 2020-08-01
        • 1970-01-01
        相关资源
        最近更新 更多