简体   繁体   中英

Java/Stream Help: Convert a nested list of maps to a map using streams only

I have a nested list of maps as below

Example List of Maps:

[{owner=trader1, ord_id=[ord1, ord2], watchlist=trader1_WL}, {owner=trader2, ord_id=[ord3, ord4], watchlist=trader2_WL}]  

I need to convert it into a map of ord_id:owner

Output Required:

{ord1:trader1, ord2:trader1, ord3:trader2, ord4.trader2}

Sample Code:[Doesn't work as ord_id has list of items]

import java.util.*;
import java.util.stream.Collectors;
public class Main
{
  public static void main (String[]args)
  {
    Map < String, Object > order1 = new HashMap <> ();
    order1.put ("ord_id", Arrays.asList ("ord1", "ord2"));
    order1.put ("owner", "trader1");
    order1.put ("watchlist", "trader1_WL");

    Map < String, Object > order2 = new HashMap <> ();
    order2.put ("ord_id", Arrays.asList ("ord3", "ord4"));
    order2.put ("owner", "trader2");
    order2.put ("watchlist", "trader2_WL");

    List < Map < String, Object >> open_order_list = new ArrayList <> ();
    open_order_list.add (order1);
    open_order_list.add (order2);
    System.out.println (open_order_list);
    Map < String, String > result =
      open_order_list.stream ().collect (Collectors.
                     toMap (s->(String) s.get ("ord_id"),
                        s->(String) s.get ("owner")));

    System.out.println (result);
  }
}

It's ugly, but you can do it like this:

Map<String, String> result = open_order_list.stream()
        .flatMap(obj -> {
                String owner = (String) obj.get("owner");
                @SuppressWarnings("unchecked")
                List<String> ord_id = (List<String>) obj.get("ord_id");
                return ord_id.stream().map(id -> new String[] { owner, id });
        })
        .collect(Collectors.toMap(a -> a[1], a -> a[0]));

The code would be a lot better if you parsed the JSON text into POJOs, instead of generic collection objects.

List<Order> open_order_list = Arrays.asList(
        new Order("trader1", "trader1_WL", "ord1","ord2"),
        new Order("trader2", "trader2_WL", "ord3","ord4") );
System.out.println(open_order_list);

Map<String, String> result = open_order_list.stream()
        .flatMap(ord -> ord.getOrd_id().stream().map(id -> new String[] { ord.getOwner(), id }))
        .collect(Collectors.toMap(a -> a[1], a -> a[0]));

System.out.println (result);
class Order {
    private final String owner;
    private final String watchlist;
    private final List<String> ord_id;
    public Order(String owner, String watchlist, String... ord_id) {
        this.owner = owner;
        this.watchlist = watchlist;
        this.ord_id = Arrays.asList(ord_id);
    }
    public String getOwner() {
        return this.owner;
    }
    public String getWatchlist() {
        return this.watchlist;
    }
    public List<String> getOrd_id() {
        return this.ord_id;
    }
    @Override
    public String toString() {
        return "Order[owner=" + this.owner + ", watchlist=" + this.watchlist + ", ord_id=" + this.ord_id + "]";
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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