Создать карту из IntStream ключей - PullRequest
1 голос
/ 15 апреля 2020

Я знаю, что могу инициализировать Map, а затем заполнить его потоком. Например, здесь я использую IntStream случайных чисел для заполнения ключа предопределенной карты.

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

Дамп на консоль.

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

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

➥ Интересно, есть ли способ заставить поток создать объект Map, а не заполнять уже существующую карту.

Меня не волнует, является ли это мудрым подходом или не. Мне просто интересно узнать о синтаксисе и о том, как использовать Collector.

Я знаю о Collectors.toMap методах. Но я не могу понять синтаксис или семантику правильно. Я предполагаю, что Function.identity() - это правильный способ использовать каждое число, полученное нашим IntStream, в качестве ключа. Затем я попытался UUID.randomUUID() или p -> UUID.randomUUID() сгенерировать значение для каждой записи карты.

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 (?)
                        )
                );

Но в IDE появляется ошибка:

Ожидается 3 аргумента но нашел 1

Я нашел примеры Collectors.toMap с двумя аргументами, один для ключа и один для значения, для создания каждой записи карты. Поэтому я не понимаю, почему настаивает на третьем аргументе вызова метода.

1 Ответ

2 голосов
/ 15 апреля 2020

IntStream имеет только один collect метод , который принимает 3 параметра. Я подозреваю, что вы ищете перегрузку 1-параметра в Stream.

. Поймите, что IntStream создает поток примитивных int чисел, а не Integer объектов.

Вызов .boxed() вызывает автобокс (см. учебное пособие ), чтобы обернуть каждый примитив int в Integer объект. Это делает Stream<Integer>, а не IntStream.

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