简体   繁体   中英

Filter Map<String,List<Object>> Using Java Streams

class Custom{
   String itemId,
   long createdTS
   //constructor
   public Custom(String itemId,long createdTS)
}

I have two maps which are

Map<String,Long> itemIDToFilterAfterTS;
Map<String,List<Custom>> itemIDToCustoms;

I want to filter 2nd map itemIDToCustoms values using 1st map itemIDToTimestampMap value for item using java streams. eg.

itemIDToFilterAfterTS = new HashMap();
itemIDToFilterAfterTS.put("1",100);
itemIDToFilterAfterTS.put("2",200);
itemIDToFilterAfterTS.put("3",300);

itemIDToCustoms = new HashMap();
List<Custom> listToFilter = new ArrayList();
listToFilter.add(new Custom("1",50));
listToFilter.add(new Custom("1",90));
listToFilter.add(new Custom("1",120));
listToFilter.add(new Custom("1",130));
itemIDToCustoms.put("1",listToFilter)

Now I want to use java streams and want the filtered result map for which getKey("1") gives filtered list of Custom object which has createdTS > 100 (100 will be fetched from itemIDToFilterAfterTS.getKey("1"))

Map<String,List<Custom>> filteredResult will be 
Map{
   "1" : List of (Custom("1",120),Custom("1",130))
}  

You can use Map#computeIfPresent method like this:

which allows you to compute value of a mapping for specified key if key is already associated with a value

public Object computeIfPresent(Object key,BiFunction remappingFunction)

So you can perform it like:

itemIDToFilterAfterTS.forEach((key, value) ->
            itemIDToCustoms.computeIfPresent(key, (s, customs) -> customs.stream()
                    .filter(c -> c.getCreatedTS() > value)
                    .collect(Collectors.toList())));

The stream syntax here is a bit too much

itemIDToCustoms = itemIDToCustoms.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(),
            e -> e.getValue().stream().filter(val -> val.createdTS > itemIDToFilterAfterTS.get(e.getKey())).collect(Collectors.toList())));

More readable with a for loop + stream

for (Map.Entry<String, List<Custom>> e : itemIDToCustoms.entrySet()) {
    long limit = itemIDToFilterAfterTS.get(e.getKey());
    List<Custom> newValue = e.getValue().stream().filter(val -> val.createdTS > limit).collect(Collectors.toList());
    itemIDToCustoms.put(e.getKey(), newValue);
}

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