Reputation: 356
I am fetching data from a database and making a map as below:
List<MyBO> data = callDatabase();
//here I am grouping the channels by run date
Map<String, List<String>> groupDatesByChannel = data .parallelStream().collect(
Collectors.groupingBy(MyBO::getChannelName,
Collectors.mapping(MyBO::getRunDate, Collectors.toList())));
Now the problem is that for one of the channels, run date is hourly i.e. the batch on channel run every hour so for that particular source run dates fetched from data base are in the form of yyyyMMddHH as opposed to yyyyMMdd.
my code works fine for channels where run date is in yyyMMdd format and example of my map above (groupDatesByChannel) is like:
Channel_2[20200101 , 20200103 , 20200107],
Channel_5[20200103 ]
Channel_7[20200102 , 20200104 ]
I want to make this mapping for the channel where run dates are hourly.
Channel_1[**2020010100,2020010101...2020010123,20200101**, 20200102, 20200104 ],
Channel_2[20200101 , 20200103 , 20200107],
Channel_5[20200103 ]
Channel_7[20200102 , 20200104 ]
to
Channel_1[**20200101**, 20200102, 20200104 ],
Channel_2[20200101 , 20200103 , 20200107],
Channel_5[20200103 ]
Channel_7[20200102 , 20200104 ]
i.e I want to merge all same dates whether its in yyyyMMddHH or yyyyMMdd fromat.
Upvotes: 0
Views: 117
Reputation: 60
The following code is tested and working fine.
public static Map<String, List<String>> mergeData(Map<String, List<String>> originalData){
Map<String, List<String>> mergedData = new HashMap<String, List<String>>();
for(String key : originalData.keySet()){
// Cleaning the key string. Removing *'s
String trimmedKey = key.replaceAll("\\*","");
// Trimming the key string. Trimming the hour digits, so that key will only contain date value
String dateOnlyKey = trimmedKey.substring(0,8);
// If mergedData already has the key, add values to the list.
if(mergedData.containsKey(dateOnlyKey)){
// Adding directly to the list may create duplicate entries. So, appending all data to HashSet and writing back to list
// If having duplicates is ok, next two lines can be ommitted and third line would be mergedData.get(dateOnlyKey).addAll(originalData.get(key));
Set<String> channels = new HashSet<String>(mergedData.get(dateOnlyKey));
channels.addAll(originalData.get(key));
mergedData.put(dateOnlyKey, new ArrayList<String>(channels));
}
// If mergedData doesn't have the key, add the new entry
else{
mergedData.put(dateOnlyKey, originalData.get(key));
}
}
System.out.println(mergedData.entrySet());
return mergedData;
}
The logic is simple
You can run the code and check for yourself. Worked fine for me.
Upvotes: 1
Reputation: 3131
The simplest way to achieve that will be to simply take only the first 8 characters of your DateTime for the grouping.
Map<String, List<String>> groupDatesByChannel = data .parallelStream().collect(
Collectors.groupingBy(myBO -> myBO.getChannelName().substring(0,8),
Collectors.mapping(MyBO::getRunDate, Collectors.toList())));
Upvotes: 0