Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 re-map with modified value

Tags:

I'm about to get a grasp on the new Java 8 stream and lambda options, but there are still a few subtleties that I haven't yet wrapped my mind around.

Let's say that I have a map where the keys are the names of people. The value for each name is a map of ages and Person instances. Further assume that there does not exist more than one person with the same name and age.

Map<String, NavigableMap<Long, Person>> names2PeopleAges = new HashMap<String, NavigableMap<Long, Person>>(); 

After populating that map (elsewhere), I want to produce another map of the oldest person for each name. I want to wind up with a Map<String, Person> in which the keys are identical to those in the first map, but the value for each entry is the value of the value map for which the key of the value map has the highest number.

Taking advantage of the fact that a NavigableMap sorts its keys, I can do this:

Map<String, Person> oldestPeopleByName = new HashMap<String, Person>(); names2PeopleAges.forEach((name, peopleAges) -> {   oldestPeopleByName.put(name, peopleAges.lastEntry().getValue()); }); 

Question: Can I replace the last bit of code above with a single Java 8 stream/collect/map/flatten/etc. operation to produce the same result? In pseudo-code, my first inclination would be:

Map<String, Person> oldestPeopleByName = names2PeopleAges.forEachEntry().mapValue(value->value.lastEntry().getValue()); 

This question is meant to be straightforward without any tricks or oddities---just a simple question of how I can fully leverage Java 8!

Bonus: Let's say that the NavigableMap<Long, Person> above is instead merely a Map<Long, Person>. Could you extend the first answer so that it collects the person with the highest age value, now that NavigableMap.lastEntry() is not available?

like image 713
Garret Wilson Avatar asked Aug 23 '14 21:08

Garret Wilson


People also ask

How do I change the value of an existing Map in Java?

hashmap. put(key, hashmap. get(key) + 1); The method put will replace the value of an existing key and will create it if doesn't exist.

Can we update value in Map?

The Combination of containsKey and put Methods. The combination of containsKey and put methods is another way to update the value of a key in HashMap. This option checks if the map already contains a key. In such a case, we can update the value using the put method.

How do you add value to an existing Map?

put() method of HashMap is used to insert a mapping into a map. This means we can insert a specific key and the value it is mapping to into a particular map. If an existing key is passed then the previous value gets replaced by the new value. If a new pair is passed, then the pair gets inserted as a whole.


1 Answers

You can create a Stream of the entries and collect it to a Map :

Map<String, Person> oldestPeopleByName =      names2PeopleAges.entrySet()                     .stream()                     .collect (Collectors.toMap(e->e.getKey(),                                                e->e.getValue().lastEntry().getValue())                              ); 

Now, without lastEntry :

Map<String, Person> oldestPeopleByName =      names2PeopleAges.entrySet()                     .stream()                     .collect (Collectors.toMap(e->e.getKey(),                                                e->e.getValue().get(e.getValue().keySet().stream().max(Long::compareTo)))                              ); 

Here, instead of relying on lastEntry, we search for the max key in each of the internal Maps, and get the corresponding Person of the max key.

I might have some silly typos, since I haven't actually tested it, by in principle it should work.

like image 57
Eran Avatar answered Oct 21 '22 14:10

Eran