我想在 Java 中處理值的子集。場景就像
示例 1:
localIDA - {x, y}
localIDB - {x, y, z}
localIDC - {z}
這應該在 JSON 中如下所示,
{data : {x,y}, provider: {localIDA, localIDB }}
{data : {z}, provider: {localIDB, localIDC }}
示例 2:
localIDA - {x, y, z}
localIDB - {y, z}
localIDC - {z}
JSON結構應該是
{data : {y, z}, provider: {localIDA, localIDB }}
{data : {x}, provider: {localIDA }}
{data : {z}, provider: {localIDC }}
在這里,我想了解在 Java 中使用正確的資料結構。
注意:在給定的示例中,資料采用三個條目。但是,可能有“n”個條目。
uj5u.com熱心網友回復:
為了以所需的方式排列資料,我們可以使用幾個中間映射。
此外,我們需要一些自定義型別來執行轉換并存盤將被序列化為 JSON 的最終結果。為此,我將使用 Java 16記錄(但它們也可以作為類實作)。
Map<provider, List<data>>
| intermediate transformation:
v entry -> group of objects `provider data`
Map<data, Set<provider>>
|
v
Map<Set<provider>, List<data>>
|
v
List of custom type that would be serialized into JSON
這些是主要步驟:
將初始映射的每個條目拆分為一組自定義物件,每個物件只包含一個參考和一個參考;
dataprovider按資料對這些物件進行分組并形成型別的第一個輔助映射
Map<String, Set<String>>(按資料提供提供者)。遍歷新創建的映射的條目,并通過按value對條目進行分組來重新排列資料,該條目的型別
Set<String>(提供程式集)到 type 的第二個輔助映射中Map<Set<String>, List<String>>。第二個映射的值將包含data映射到相同提供程式集的字串(集合用于使比較對提供程式的排序不敏感)。- 請注意,在這種情況下,使用可變集合(可以通過
Collectors.toSet()- 參見下面的代碼創建)作為映射鍵是安全的,因為我們只需要它來執行中間轉換,并且我們不存盤對鍵的參考,不給地圖。但是,如果讀者想要使用下面提供的解決方案來生成一個映射,該映射將存盤為一個欄位并傳遞,那么為了避免意外更改,鍵應該由一個不可變集合表示。因此,為了使解決方案更加通用,我將Collectors.toUnmodifiableSet().
- 請注意,在這種情況下,使用可變集合(可以通過
最后一步是生成一個
List將被序列化為 JSON 的物件。為此,我們需要遍歷第二個輔助映射并將每個條目轉換為自定義物件。資料已準備好編組為 JSON。出于演示目的,我使用了Jackson(讀者可以應用他們選擇的任何其他工具)。
自定義物件:
public record DataProvider(String data, String provider) {}
public record DataProviders(Set<String> data, List<String> providers) {}
地圖邏輯:
Map<String, List<String>> dataByProvider = Map.of(
"localIDA", List.of("x", "y"),
"localIDB", List.of("x", "y", "z"),
"localIDC", List.of("z")
);
List<DataProviders> dataProviders = dataByProvider.entrySet().stream()
.flatMap(entry -> entry.getValue().stream()
.map(data -> new DataProvider(data, entry.getKey()))
)
.collect(Collectors.groupingBy(
DataProvider::data,
Collectors.mapping(DataProvider::provider,
Collectors.toUnmodifiableSet())
))
.entrySet().stream()
.collect(
HashMap::new,
(Map<Set<String>, List<String>> map, Map.Entry<String, Set<String>> entry) ->
map.computeIfAbsent(entry.getValue(), k -> new ArrayList<>()).add(entry.getKey()),
(left, right) ->
right.forEach((k, v) -> left.merge(k, v, (oldV, newV) -> {
oldV.addAll(newV);
return oldV;
}))
)
.entrySet().stream()
.map(entry -> new DataProviders(entry.getKey(), entry.getValue()))
.toList(); // for Java 16 or collect(Collectors.toList())
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT); // to make the output look nicely (can be omitted)
String json = mapper.writeValueAsString(dataProviders);
System.out.println(json);
輸出:
[ {
"data" : [ "localIDB", "localIDA" ],
"providers" : [ "x", "y" ]
}, {
"data" : [ "localIDB", "localIDC" ],
"providers" : [ "z" ]
} ]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/510073.html
上一篇:決議嵌套的JSON結構
