Чтобы напрямую ответить на вопрос, как я его сформулировал, PriorityQueue можно преобразовать в Карту с использованием потоков, например, так:
Map<Integer, Integer> map = pq.stream().collect(ConcurrentHashMap::new, (integerIntegerHashMap, integer) -> integerIntegerHashMap.put(pq.poll(), pq.size()), ConcurrentHashMap::putAll);
Это параллельный пример, но с заменой на HashMap (или любой другой не -concurrent Map) будет работать в тех сценариях ios, которые не требуют параллелизма.
Для метода collect
требуется 3 аргумента (документы: Stream.collect ):
- Это должен быть поставщик контейнера (в данном случае это ссылка на конструктор для ConcurrentHashMap)
- Это должен быть аккумулятор. Он возьмет контейнер и элемент и выполнит некоторую операцию (здесь я не использую элемент, потому что я создаю отображение, основываясь исключительно на состоянии очереди приоритетов).
- Это должен быть объединитель , Он возьмет 2 контейнера (как аргумент 1) и объединит их.
Контейнером здесь является ConcurrentHashMap
, а сумматором является метод putAll
(потому что он принимает коллекцию).
Теперь, чтобы дать ответ на реальную проблему, с которой я столкнулся: имея массив целых чисел, мне нужно было создать новый массив целых чисел, который был бы отображением исходного числа в число значений меньше, чем на входе.
Вход [1,2,3] -> Выход [0, 1, 2] Вход [8,4,4] -> Выход [2, 0, 0]
Вот как Я следовал приведенному выше описанию:
int[] nums = ... (this is the input)
PriorityBlockingQueue<Integer> pq = Arrays.stream(nums).parallel().boxed().collect(()->new PriorityBlockingQueue<>(nums.length, Comparator.reverseOrder()), PriorityBlockingQueue::add, PriorityBlockingQueue::addAll);
Map<Integer, Integer> map = pq.stream().collect(ConcurrentHashMap::new, (integerIntegerHashMap, integer) -> integerIntegerHashMap.put(pq.poll(), pq.size()), ConcurrentHashMap::putAll);
int[] out = Arrays.stream(nums).mapToObj(operand -> map.get(operand)).mapToInt(Integer::intValue).toArray();
Я установил контейнер как Максимальное количество одновременных обращений (очередь с параллельным приоритетом с обращенным компаратором).
Затем вытащим числа 1 на 1 , давая им соответствующее отображение на основе pq. Я не думаю, что этот второй шаг может быть выполнен параллельно, потому что 2 poll
вызовов могут завершаться sh последовательно, но мы должны гарантировать, что size
вызывается непосредственно после каждого poll
.
Наконец, итерируйте по входным элементам и получите соответствующее значение из карты, а затем преобразуйте в массив результатов.