Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Structuring List data using Java 8 and normalizing it into a map structure

So, I am still new to Java 8 and still struggling to correlate the streams API with traditional iteration and collections.

So I have a List of object "UserData" which has 3 properties, the list is all denormalized data.

 public class UserData {

        private String primaryAccountNumber;
        private String subAccountNumber;
        private String currency;
}

Sample Input Data would be like

PrimaryAccNumber     SubAccNumber   Currency
PA00                 US00           USD
PA01                 US01           USD
PA01                 US02           USD
PA02                 EU00           EUR
PA03                 EU01           EUR
PA04                 CA00           CAD
PA04                 CA01           CAD
null                 IN00           INR
null                 IN01           INR

The expected output should be something like

USD  -> PA00 -> [US00]
        PA01 -> [US01,US02]
EUR  -> PA02 -> [EU00]
     -> PA03 -> [EU01]
CAD  -> PA04 -> [CA00,CA01]
INR  -> null (or dummykey)->[IN00,IN01]

So, i want it to be normalized in a way such that the out come is a Map keyed with currency and the value should be another Map keyed with primary Acc and value with List of sub Accounts.

Map<String, Map<String,List<String>>> normalizedData = //logic

I was thinking of doing this oldschool way basically

  1. Sort the data based on currency.
  2. Iterate the list and put the data in Map ( since the data is sorted and till i get the duplicate keys will start putting the corresponding data ( primary account in a new Map)
  3. Repeat the above process basically at primary account level and start putting the duplicate key corresponding value data (sub accounts in a list object)

As for my thought process i have to create 2 list copies (1 sort at Currency for first iteration) , 2 nd sort at Primary account for nested map. It seems little inefficient, then i looked at the streams but could not visualize how i can use them but any guidance or thoughts would be appreciated.

like image 691
user1697113 Avatar asked Jun 19 '19 23:06

user1697113


1 Answers

It's pretty straightforward with streams. You need a couple of nested groupings and a mapping at the end. For the sake of brevity, I'll assume you have a static import of java.util.stream.Collectors.*.

Map<String, Map<String, List<String>>> normalizedData = users.stream().collect(
        groupingBy(UserData::getCurrency,
                groupingBy(UserData::getPrimaryAccountNumber,
                        mapping(UserData::getSubAccountNumber, toList()))));

Note that groupingBy() doesn't allow null keys, so you may indeed have to use a dummy key.

like image 136
shmosel Avatar answered Oct 23 '22 09:10

shmosel