簡體   English   中英

給定 Map 類型的 map <k, list<v> &gt;,如何更新列表中的值<v>使用 Java 流?</v></k,>

[英]Given a map of type Map<K, List<V>>, how to update value within List<V> using Java streams?

我收到了一些 API 的回復,其類型為:

public class Response {

    private String role;
    private String permission;
  
    // Setters and getters
}

Role的值可以是"Admin""User"等,permission 的值可以是"R-4""C-44"等。 "R-"表示地區, "C-"表示國家。 所以最初我通過以下方式構造了 Map<String, Set>:

Map<String, Set<String>> initialMap= responseList.stream().collect(
    Collectors.groupingBy(Reponse::getRole, HashMap::new, 
    Collectors.mapping(Reponse::getPermission, Collectors.toSet()))
);

但是對於我的應用程序,我希望 map 是Map<String, Set<Long>> ,它表示角色以及與該角色相關的各個國家。 基本上,我想從 Set 中刪除"R-""C-" ,這是hashmap的值。 當值類似於"R-4"時,我想刪除"R-"並使用在本例中為4的 id 並將此 id 傳遞到數據庫以獲取List<Long> countries並將其添加到hashmap的值中。 當值類似於"C-44"時,我想刪除"C-"並將該 id 添加到hashmap的值中。 一種方法是手動迭代initialMap的每個條目,然后獲取其對應的Set<String>值,然后再次迭代Set<String>以獲取String值,然后將其轉換為Long 我在想有沒有更好的方法來使用 Streams 做到這一點? 我可以直接從我的初始reponseList構造Map<String, Set<Long>>嗎?

你可以試試這個

Map<String, Set<String>> initialMap= responseList.stream().collect(
    Collectors.groupingBy(Response::getRole, HashMap::new, 
    Collectors.mapping((Response res) -> Long.parseLong(res.getModifiedPermission()), Collectors.toSet()))
);

getModifiedPermission()是一個 function 從權限中刪除前綴。

您可以將 static 方法添加到Response class:

private static long toLong(Response response) {
    String[] arr = response.getPermission().split("-");
    String str = arr.length == 1 ? arr[0] : arr[1];
    return Long.parseLong(str);
}

然后您可以創建一個方法將List轉換為Map

public static Map<String, Set<Long>> toMap(List<Response> response) {
    return response.stream().collect(Collectors.groupingBy(Response::getRole, 
                Collectors.mapping(Response::toLong, Collectors.toSet())));
}

例子:

List<Response> responseList = List.of(
        new Response("AAA","R-4"), 
        new Response("BBB","C-44"),
        new Response("CCC","444"));

Map<String, Set<Long>> map = toMap(responseList);

System.out.println(map);

Output:

{AAA=[4], BBB=[44], CCC=[444]}

似乎這里的主要問題不是解析地區/國家/地區的 id,而是結合List<Long>包含從某些數據庫/存儲庫檢索到的每個 regionId的多個國家/地區 ID,以及來自權限C-###的單個國家/地區 ID C-### .

這可以使用 Java 9+ 中提供的Collectors.flatMapping來解決。 此外,需要將單獨的 function streamOfCountryIDs實現到 map 響應的權限進入此收集器的Stream<Long>

Map<String, Set<Long>> converted = responses.stream()
        .collect(Collectors.groupingBy(
                Response::getRole,
                Collectors.flatMapping(MyClass::streamOfCountryIDs, Collectors.toSet())
        ));

System.out.println(converted);
// MyClass
private static Stream<Long> streamOfCountryIDs(Response response) {
    String permission = response.getPermission().toUpperCase();
    if (permission.startsWith("R-")) {
        return countryRepo.getCountriesByRegion(Long.parseLong(permission.substring(2)))
            .stream();
    } else if (permission.startsWith("C-")) {
        return Stream.of(Long.parseLong(permission.substring(2)));
    }
    // log bad permission and return empty stream or throw an exception if needed
    System.out.println("Bad permission: '" + permission + "'");
    return Stream.empty();
}

如何轉換列表<object>至 Map<k, v> 使用 java stream<div id="text_translate"><p> 我想將List&lt;ObjectInList&gt;轉換為Map&lt;K, V&gt;</p><pre> class ObjectInList { List&lt;Long&gt; listWithLong; Map&lt;String, Object&gt; dataMap; // there is 'id' key, and i want to use this id as key in map to be converted }</pre><p> 新的 map 格式如下</p><pre>String type; // this type is value of dataMap. List&lt;Long&gt; contents</pre><p> List&lt;Object&gt;中的每個 Object 都可以有重復的類型</p><p>例如</p><pre>///////// before converted //////////// [ { list: [1,2,3], dataMap: { type: "a", } }, { list: [4,5,6], dataMap: { type: "b", } }, { list: [7,8], dataMap: { type: "a", } }, ] ///////////// after converted ////////// { "a": [1,2,3,7,8], "b": [4,5,6] }</pre></div></k,></object>

[英]How to convert LIst<Object> to Map<K, V> with using java stream

暫無
暫無

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

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