繁体   English   中英

放<Object>到地图<String, Set<Long> &gt; java8

[英]Set<Object> to Map<String, Set<Long>> java8

假设我有下一个类结构:

@Getter
@Setter
public class Section {

    private Long id;
    
    private Set<Grid> grids;
}

@Getter
@Setter
public class Grid {

    private Long id;
    
    private Set<Row> rows;
}

@Getter
@Setter
public class Row {
    private Long id;
    
    private String email;
}

我有这组对象:

Set<Section> sections;

让我们想象本节将值设置为下一个结构中的 JSON:

[
  {
    "id": 1,
    "grids": [
      {
        "id": 10,
        "rows" [
          {
            "id": 50,
            "email": "email1@test.com"
          },
          {
            "id": 51,
            "email": "email2@test.com"
          }
        ]
      }  
    ]
  },
  {
    "id": 2,
    "grids": [
      {
        "id": 11,
        "rows" [
          {
            "id": 60,
            "email": "email1@test.com"
          }
        ]
      }  
    ]
  }  
]

想象一下我有多个部分,这些部分有多个网格,每个网格有多行,每行中的电子邮件属性可以存在于不同的网格中。

现在我需要将此Set转换为 java.util。 Map<String, Set>和此映射将 Row 对象电子邮件表示为键,将 Section id 组表示为该映射键的值。 所以我需要像Map<email, Set<section1Id, section2id, etc...>>这样的结果在 JSON 中(这只是为了澄清这个想法):

[
  {
    "key": "email1@test.com",
    "value": [1, 2] // Section ids
  },
  {
    "key": "email2@test.com",
    "value": [1] // Section ids
  }
]

OR like that (whatever)

[
  "email1@test.com": {1, 2},
  "email2@test.com": {1}
]

我如何使用 Java 8 流实现这一目标?

尝试这样的事情:

import static java.util.stream.Collectors.*;
import org.apache.commons.lang3.tuple.Pair;
// ...snip...
sections.stream()
        .flatMap(section->section.getGrids()
                                 .stream()
                                 .map(Grid::getRows)
                                 .flatMap(Set::stream)
                                 .map(row->new Pair(row.getEmail(), section.getId())))
        .collect(groupingBy(Pair::getKey, mapping(Pair::getValue, toSet())));

如果您使用的是 Java 9 或更新版本,则无需第三方库即可以非常简洁的方式进行操作:

import java.util.Map;
import java.util.Set;

import static java.util.Map.Entry;
import static java.util.Map.entry;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toSet;

Map<String, Set<Long>> result = sections.stream()
        .flatMap(section -> section.getGrids().stream()
                .flatMap(grid -> grid.getRows().stream())
                .map(row -> entry(row.getEmail(), section.getId())))
        .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toSet())));

这与流媒体无关。 它可以通过一个简单的 foreach 来实现:

public static void main(String[] args) {
        Set<Section> sections = Set.of(....);
        Map<String, Set<Long>> result = new HashMap<>();
        sections.forEach(section -> 
                                 section.getGrids()
                                         .forEach(grid -> 
                                                          grid.getRows().forEach(row -> {
                                                            if (result.containsKey(row.getEmail()))
                                                                result.get(row.getEmail()).add(section.getId());
                                                                else result.put(row.getEmail(), Set.of(section.getId()));
                                                          })));
    }

这是获得所需输出格式的两步操作。 看看它,如果适合您的用例

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javafx.util.Pair;

public class P5 {

  public static void main(String[] args) {

    Row r1 = new Row(50L, "email1@test.com");
    Row r2 = new Row(51L, "email2@test.com");
    Row r3 = new Row(60L, "email1@test.com");
    Row[] arr1 = {r1, r2};
    Row[] arr2 = {r3};

    Grid[] g1 = {new Grid(10L, new HashSet<>(Arrays.asList(arr1)))};
    Grid[] g2 = {new Grid(11L, new HashSet<>(Arrays.asList(arr2)))};

    Set<Section> sections = new HashSet<>();
    sections.add(new Section(1L, new HashSet<>(Arrays.asList(g1))));
    sections.add(new Section(2L, new HashSet<>(Arrays.asList(g2))));

    Map<Long, List<String>> minify = sections.stream()
        .collect(Collectors.toMap(section -> section.id,
            section -> section.grids.stream().flatMap(grid -> grid.rows.stream())
                .map(row -> row.email)
                .collect(Collectors.toList())));

    Map<String, Set<Long>> result = minify.keySet().stream()
        .flatMap(key -> minify.get(key).stream().map(email -> new Pair<>(
            key, email))).collect(Collectors.groupingBy(
            Pair::getValue, Collectors.mapping(Pair::getKey, Collectors.toSet())));

    System.out.println(result);
  }

  static class Section {
    private Long id;
    private Set<Grid> grids;
    public Section(Long id, Set<Grid> grids) {
      this.id = id;
      this.grids = grids;
    }
  }

  static class Grid {
    private Long id;
    private Set<Row> rows;
    public Grid(Long id, Set<Row> rows) {
      this.id = id;
      this.rows = rows;
    }
  }

  static class Row {
    private Long id;
    private String email;
    public Row(Long id, String email) {
      this.id = id;
      this.email = email;
    }
  }

}

结果

{email2@test.com=[1], email1@test.com=[1, 2]}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM