简体   繁体   English

HashMap 的合并密钥

[英]Merging keys of a HashMap

I am fetching data from a database and making a map as below:我正在从数据库中获取数据并制作 map,如下所示:

   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 ie 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.现在的问题是,对于其中一个通道,运行日期是每小时一次,即通道上的批处理每小时运行一次,因此从数据库中获取的特定源运行日期的形式是 yyyyMMddHH,而不是 yyyyMMdd。

my code works fine for channels where run date is in yyyMMdd format and example of my map above (groupDatesByChannel) is like:我的代码适用于运行日期为 yyyMMdd 格式的频道,我上面的 map 示例(groupDatesByChannel)如下:

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 ]

ie I want to merge all same dates whether its in yyyyMMddHH or yyyyMMdd fromat.即我想合并所有相同的日期,无论是在 yyyyMMddHH 还是 yyyyMMdd fromat。

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逻辑很简单

  1. Create a new HashMap新建 HashMap
  2. Read each key-value pair from original data从原始数据中读取每个键值对
  3. Trim the key to contain only date value修剪键以仅包含日期值
  4. Insert the value into new HashMap with the trimmedKey使用 trimmedKey 将值插入新的 HashMap

You can run the code and check for yourself.您可以运行代码并自行检查。 Worked fine for me.对我来说工作得很好。

The simplest way to achieve that will be to simply take only the first 8 characters of your DateTime for the grouping.实现这一目标的最简单方法是仅将 DateTime 的前 8 个字符用于分组。

Map<String, List<String>> groupDatesByChannel = data .parallelStream().collect(
            Collectors.groupingBy(myBO -> myBO.getChannelName().substring(0,8),
                    Collectors.mapping(MyBO::getRunDate, Collectors.toList())));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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