Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 stream to Map<Integer, List<String>>

This is Java object to handle in Java 8 stream

private static List<Person> getPersons() {
        List<Person> results = new ArrayList<Person>();

        results.add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000));
        results.add(new Person("Tamsen", "Brittany", "Java programmer", "female", 23, 1500));
        results.add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));
        results.add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));
        results.add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));
        results.add(new Person("Maude", "Jaimie", "Java programmer", "female", 27, 1900));
        results.add(new Person("Shawn", "Randall", "Java programmer", "male", 30, 2300));
        results.add(new Person("Jayden", "Corrina", "Java programmer", "female", 35, 1700));
        results.add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));
        results.add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));

        results.add(new Person("Jarrod", "Pace", "PHP programmer", "male", 34, 1550));
        results.add(new Person("Clarette", "Cicely", "PHP programmer", "female", 23, 1200));
        results.add(new Person("Victor", "Channing", "PHP programmer", "male", 32, 1600));
        results.add(new Person("Tori", "Sheryl", "PHP programmer", "female", 21, 1000));
        results.add(new Person("Osborne", "Shad", "PHP programmer", "male", 32, 1100));
        results.add(new Person("Rosalind", "Layla", "PHP programmer", "female", 25, 1300));
        results.add(new Person("Fraser", "Hewie", "PHP programmer", "male", 36, 1100));
        results.add(new Person("Quinn", "Tamara", "PHP programmer", "female", 21, 1000));
        results.add(new Person("Alvin", "Lance", "PHP programmer", "male", 38, 1600));
        results.add(new Person("Evonne", "Shari", "PHP programmer", "female", 40, 1800));

        return results;
    }

And I generate Map objects with key-value "age". This is codes

    Function<Person, Map<String, String>> nameNsalary = (Person p) -> {
                Map<Int, String> map = new HashMap<Int,String>();

                if (p.getAge()>=40)
                    map.put(40 , p.getFirstName() + " " + p.getLastName() +":" + p.getSalary());
                else if(p.getAge()>=30 && p.getAge()<40)
                    map.put(30 , p.getFirstName() + " " + p.getLastName() +":" + p.getSalary());
                else if(p.getAge()<20)
                    map.put(20 , p.getFirstName() + " " + p.getLastName() +":" + p.getSalary());
                else 
                    map.put(10 , p.getFirstName() + " " + p.getLastName() +":" + p.getSalary());

                return map;
            };

persons.stream().map(nameNsalary).forEach(System.out::println);

Output map object is successful like below,

{40=Elsdon Jaycob:2000}
{20=Tamsen Brittany:1500}
{30=Floyd Donny:1800}
{30=Sindy Jonie:1600}
{20=Vere Hervey:1200}
{20=Maude Jaimie:1900}
{30=Shawn Randall:2300}
{30=Jayden Corrina:1700}
{30=Palmer Dene:2000}
{30=Addison Pam:1300}
{30=Jarrod Pace:1625}
{20=Clarette Cicely:1260}
{30=Victor Channing:1680}
{20=Tori Sheryl:1050}
{30=Osborne Shad:1155}
{20=Rosalind Layla:1365}
{30=Fraser Hewie:1155}
{20=Quinn Tamara:1050}
{30=Alvin Lance:1680}
{40=Evonne Shari:1890}

But I fail changing output type from Map<Integer, String> to Map<Integer, List<String>>, for example,

30 = [Jayden Corrina:1700, Palmer Dene:2000, Addison Pam:1300]

I have no idea how to handle these Map object data to Map<Int, List<String>>. I made this code,

Map<Integer, List<String>> result = persons.stream().map(nameNsalary)
                .collect(Collectors.toMap(mapper -> (Integer)mapper.getKey(), mapper -> mapper.getValue()));

But this code throws the following exception

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
    Type mismatch: cannot convert from Map<Object,Object> to Map<Integer,List<String>>
    The method getKey() is undefined for the type Map<Integer,String>
    The method getValue() is undefined for the type Map<Integer,String>

I am stuck with this procedure.

like image 233
Joseph Hwang Avatar asked Sep 20 '16 12:09

Joseph Hwang


People also ask

How will you convert a List into map using streams in Java 8?

With Java 8, you can convert a List to Map in one line using the stream() and Collectors. toMap() utility methods. The Collectors. toMap() method collects a stream as a Map and uses its arguments to decide what key/value to use.

Can we use map Stream in Java 8?

Java 8 Stream's map method is intermediate operation and consumes single element forom input Stream and produces single element to output Stream. It simply used to convert Stream of one type to another. Let's see method signature of Stream's map method.


1 Answers

Your mapper is quite inefficient, it creates a new map for every entry.

It would be simpler to use the groupingBy collector.

Map<Integer, List<String>> result = persons.stream()
        .collect(Collectors.groupingBy(
            p -> (p.getAge() / 10) * 10, // some integer division trick
            Collectors.mapping(
                p -> p.getFirstName() + " " + p.getLastName() +":" + p.getSalary(),
                Collectors.toList()
            )
        ));

Which returns:

20 = [Tamsen Brittany:1500, Vere Hervey:1200, Maude Jaimie:1900, Clarette Cicely:1200, Tori Sheryl:1000, Rosalind Layla:1300, Quinn Tamara:1000]
40 = [Elsdon Jaycob:2000, Evonne Shari:1800]
30 = [Floyd Donny:1800, Sindy Jonie:1600, Shawn Randall:2300, Jayden Corrina:1700, Palmer Dene:2000, Addison Pam:1300, Jarrod Pace:1550, Victor Channing:1600, Osborne Shad:1100, Fraser Hewie:1100, Alvin Lance:1600]

You can also forgo the additional mapping step, and create a Map<Integer, List<Person>> instead:

Map<Integer, List<Person>> result = persons.stream()
    .collect(Collectors.groupingBy(p -> (p.getAge() / 10) * 10));
like image 184
Jorn Vernee Avatar answered Oct 01 '22 00:10

Jorn Vernee