Produce a Map from an IntStream of keys

北战南征 提交于 2020-04-17 22:10:07

问题


I know I can initialize a Map, and then fill it using a stream. For example, here I use an IntStream of random numbers to populate the key of the predefined map.

int initialCapacity = 3; 
Map < Integer, UUID > map = new HashMap <>( initialCapacity );
IntStream numbers = ThreadLocalRandom.current().ints( initialCapacity );
numbers.forEach( number -> map.put( number , UUID.randomUUID() ) );

Dump to console.

System.out.println( "map = " + map );

map = {-14054365=ee739423-1200-45e6-80da-d167ce2e2b98, -1079671217=ba0096fe-b32f-4ebf-a163-114fcb679992, -404094411=f900052b-8a8d-4e66-b808-618fbc7e115f}

➥ I wonder if there is a way to have the stream produce the Map object, rather than filling a pre-existing map.

I do not care about if this is a wise approach or not. I am just curious about the syntax and how to use a Collector.

I know about the Collectors.toMap methods. But I cannot seem to get the syntax or semantics done properly. I am guessing that Function.identity() is the right way to use each number produced by our IntStream as the key. Then I tried UUID.randomUUID() or p -> UUID.randomUUID() to generate the value for each map entry.

int initialCapacity = 3;
Map < Integer, UUID > map =
        ThreadLocalRandom
                .current()                              // Returns a random number generator.
                .ints( initialCapacity )                // Returns an `IntStream`. 
                .collect(
                        Collectors.toMap(
                                Function.identity() ,   // Generate map key (?)
                                x -> UUID.randomUUID()  // Generate map value (?)
                        )
                );

But I get an error in the IDE saying:

Expected 3 arguments but found 1

I found examples of Collectors.toMap with two arguments, one for the key, and one for the value, to produce each map entry. So I do not see why the insistence on a third argument to the method call.


回答1:


IntStream only has one collect method, which takes 3 parameters. I suspect you are looking for the 1-parameter overload in Stream.

Understand that IntStream produces a stream of primitive int numbers, not Integer objects.

Calling .boxed() invokes auto-boxing (see tutorial) to wrap each primitive int as an Integer object. This makes a Stream<Integer> rather than IntStream.

Map < Integer, UUID > map =
    ThreadLocalRandom
            .current()
            .ints( initialCapacity )
            .boxed()                                // Add this call
            .collect(
                    Collectors.toMap(
                            Function.identity() ,
                            x -> UUID.randomUUID()
                    )
            );


来源:https://stackoverflow.com/questions/61217270/produce-a-map-from-an-intstream-of-keys

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!