Home > Enterprise >  delete from parent hashmap from a nested hashmap condition
delete from parent hashmap from a nested hashmap condition

Time:02-04

I have the following structure

HashMap<String, HashMap<String, String>> h = new HashMap<>();

HashMap<String, String>> h1 = new HashMap<>();

h1.put("key10", "value10")
h1.put("key11", "value11")
h1.put("date", "2018-10-18T00:00:57.907Z")
h.put("1#100", h1)

HashMap<String, String>> h2 = new HashMap<>();

h2.put("key20", "value20")
h2.put("key21", "value21")
h2.put("date", "2023-02-03T10:00:00.907Z")
h.put("2#000", h2)

Imagine I have many entries like the examples above. In certain moment (scheduler) i have this requirement:

  • check all nested hash maps (for each/stream)
  • see if date condition is true
  • find parent key and delete from main hash map

In this exemple the final hash map will be

h2.put("key20", "value20")
h2.put("key21", "value21")
h2.put("date", "2023-02-03T10:00:00.907Z")
h.put("2#000", h2)

h2 => {key20 => value20, key21 => value21, date => 2023-02-03T10:00:00.907Z}

i have this code right now

 h.forEach((k,v) -> {
            v.entrySet()
            .stream()
            .filter(e -> e.getKey().equals("date"))
            .filter(t -> Timestamp.from(Instant.now()).getTime() - Timestamp.valueOf(t.getValue()).getTime() > milisDiff)
            //need now to access parent and delete with by k key

Can do in one step (lambda) or i need to have extra structure to collect parent keys and after proceed to delete within for each ?

CodePudding user response:

This may do what you want. Just filter out bad elements and assign to the same map.

HashMap<String, HashMap<String, String>> h = new HashMap<>();

HashMap<String, String> h1 = new HashMap<>();

h1.put("key10", "value10");
h1.put("key11", "value11");
h1.put("date", "2018-10-18T00:00:57.907Z");
h.put("1#100", h1);

HashMap<String, String> h2 = new HashMap<>();

h2.put("key20", "value20");
h2.put("key21", "value21");
h2.put("date", "2023-02-04T10:00:00.907Z");
h.put("2#000", h2);

     


// any instant after `now` will pass the filter and be put in the map
Predicate<String> check = str -> Instant.parse(str)
.isAfter(Instant.now());


h = h.entrySet().stream()
        .filter(e -> check.test(e.getValue().get("date")))
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue,
                (a,b)->a,
                HashMap::new));

h.values().forEach(m -> {
    m.entrySet().forEach(System.out::println);
});
     

prints

date=2023-02-04T10:00:00.907Z
key21=value21
key20=value20

My predicate simply deleted the date if it expired. Yours was a tighter threshold.

Updated

Here is another option in case building a new map takes too long. It uses an iterator to run thru the loop and modify the existing map by removing Maps with old dates.

Iterator<Entry<String,Map<String,String>>> it = h.entrySet().iterator();
while (it.hasNext()) {
    Entry<String,Map<String, String>> e = it.next();
    if (!check.test(e.getValue().get("date"))) {
        it.remove();
    }
} 
  • Related