How do you convert Map<String, Person> to Map<String, Integer> in java streams inside collect?

convert map to list java 8
convert map to object java 8
map to array java
java map
how to convert map to set in java
how to get arraylist values from hashmap in java
arraylist to map
how to convert a map to arraylist

Imagine you have a list of people, Roberts, Pauls, Richards, etc, these are people grouped by name into Map<String, List<Person>>. You want to find the oldest Paul, Robert, etc... You can do it like so:

public static void main(String... args) {
        List<Person> people = Arrays.asList(
                new Person(23, "Paul"),
                new Person(24, "Robert"),
                new Person(32, "Paul"),
                new Person(10, "Robert"),
                new Person(4, "Richard"),
                new Person(60, "Richard"),
                new Person(9, "Robert"),
                new Person(26, "Robert")
        );

        Person dummy = new Person(0, "");
        var mapping = people.stream().collect(groupingBy(Person::getName, reducing(dummy, (p1, p2) -> p1.getAge() < p2.getAge() ? p2 : p1)));
        mapping.entrySet().forEach(System.out::println);
    }

Say, I want to get a mapping in the form of Map<String, Integer> instead of Map<String, Person>, I can do it like so:

var mapping = people.stream().collect(groupingBy(Person::getName, mapping(Person::getAge, reducing(0, (p1, p2) -> p1 < p2 ? p2 : p1))));

The steps above are:

  • Group by name into Map<String/*Name*/, List<Person>>
  • Map that List<Person> into List<Integer>
  • Find maximum Integer in those lists.

I was wondering how to do:

  • Group by name into Map<String, List<Person>>
  • Find the oldest person in each group name, getting Map<String, Person>
  • Convert Map<String, Person> into Map<String, Integer>. And I want to do all that inside that chain of groupingBy's, reducing's and mapping's.

This is the "pseudocode":

var mapping = people.stream().collect(groupingBy(Person::getName, reducing(dummy, (p1, p2) -> p1.getAge() < p2.getAge() ? p2 : p1 /*, have to write some other collector factory method here*/)));

How can I achieve this?

If you really want to use groupingBy as mentioned in the problem statement, you can still do it like this:

final Map<String, Integer> oldestPersonByName = people.stream()
        .collect(Collectors.groupingBy(Person::getName, Collectors.reducing(0, Person::getAge, Integer::max)));

For the reduction you have to pass an identity element, mapping function and a binary operator used to reduce, which is max in this case.

Java Stream map() example, First, let's look at converting the values of the Map into an array, using plain java: ? 1. 2. 3. 4. 5. 6. Best way to convert your MAP to PDF file in seconds. 100% free, secure and easy to use! Convertio — advanced online tool that solving any problems with any files.

It is more straightforward to do this with the 3-argument version of toMap collector:

people.stream().collect(toMap(
        Person::getName, 
        Person::getAge, 
        Integer::max
    ));

Convert a Map to an Array, List or Set in Java, In this post, we will see how to convert Map to an Array in Java. We can easily get an object array of Map.Entry using Map.entrySet() You should understand the logic behind how these are used and how they should appear on real topographic maps. On your upcoming lab exam, you should also be able to convert one type of map scale into another, and calculate size differences (scale factor, area factor) between different maps.

I think it would be like the following, also using maxBy instead of reducing.

people.stream().collect(
    groupingBy(
        Person::getName,
        collectingAndThen(
            maxBy(Comparator.comparing(Person::getAge)),
            (Optional<Person> max) -> max.get().getAge()
        )
    )
);

Convert Map to an Array in Java, Below are various method to convert Map to Stream in Java: Converting complete Map<Key, Value> into Stream: This can be done with the help of Map. We know that Map contains key-value pairs, whereas a list contains only objects. Since Entry class contains both key-value pair, Entry class will helps us to convert from Map (HashMap) to List (ArrayList). By using Map.entrySet() you will get Set object, which intern you can use it to convert to list object.

Program to convert a Map to a Stream in Java, Few Java examples to convert a Map to a List Map<String, String> map = new HashMap<>(); // Convert all Map keys to a List List<String> result  This short article will show how to convert the values of a Map to an Array, a List or a Set using plain Java as well as a quick Guava based example. This article is part of the “Java – Back to Basic” series here on Baeldung. Learn different ways of iterating through the entries of a Map in Java. Learn about the differences between map

Java 8 – Convert Map to List – Mkyong.com, Map and List are two common data structures available in Java and in this article we will see how can we convert Map values or Map keys into  On the Open Project dialog box, under Portal, click All Portal. At the top of the dialog box, in the Search box, type Convert a map to a scene tutorial and press Enter. In the list of search results, click Convert a map to a scene to select the project package.

How to Convert a Map to a List in Java Example, Conventional Method. To convert, Java Map to Set , we can use the conventional constructor with HashSet , however, there are few  This article shows 2 ways to convert Java Map to String. Approach 1: simple, lightweight – produces query string like output, but restrictive.

Comments
  • Looks like collectingAndThen is the only way? I just googled that method.
  • Do you actually need 3 maps? Or are you asking how to end up with Map<String, Integer>?
  • @shmosel I don't need 3 maps, look at my code to see what type it returns. I don't create 3 maps anywhere.
  • Your breakdowns aren't very accurate. None of the examples actually produce any lists. Either way, I don't understand the point of this question. What's the problem with the first way?
  • @POrekhov The fact that this question is about the Stream API is already given by the [java-stream] tag. There is no requirement to acknowledge the fact that this API was introduced in Java 8 by tagging every [java-stream] question with [java-8]. The version specific tags are there to state that you want a version specific answer. Since APIs may change, most notably, they get extended and there might be simpler solutions using the new API version, that’s a restriction. But restricting the API to one version but actively using newer features in the example code is confusing.
  • I wonder if -1 can be considered a valid identity if we know age is at least 0.
  • That makes sense. Let me change my answer accordingly.
  • I wasn't suggesting 0 is better. My issue is that an identity i for a function f must be a value such that f(i, x) returns x for any x. But I'm not sure if that's any possible x, or any x in the stream. If it's the former, the only valid identity would be Integer.MIN_VALUE.
  • Yeah, finding the identity element for a reduction is sometimes tricky, and a wrong identity element would lead to subtle bugs which are hard to figure out.
  • @shmosel well, if we can be sure that age is always non-negative, -1 would be a valid identity for max. Further, even if negative age values show up due to an error, max(-1, negative number) would still be negative, indicating that there is some error.
  • Thought so, thanks, unfortunately I didn't know about collectingAndThen when I posted this.
  • You are redundantly calling getAge(). In such a case, it makes more sense to map to the age first, then determine the maximum. collectingAndThen(mapping(Person::getAge, maxBy(naturalOrder())), Optional::get) or mapping(Person::getAge, reducing(-1, Math::max)), which has the handy abbreviation reducing(-1, Person::getAge, Math::max)