Может ли операция groupingBy
в потоке создать карту, в которой значения являются массивами , а не списками или каким-либо другим типом коллекции?
Например: у меня есть класс Thing
.У вещей есть владельцы, поэтому Thing
имеет метод getOwnerId
.В потоке вещей я хочу сгруппировать вещи по идентификатору владельца, чтобы вещи с одинаковым идентификатором владельца попали в массив вместе.Другими словами, мне нужна карта, подобная следующей, где ключи - это идентификаторы владельца, а значения - это массивы вещей, принадлежащих этому владельцу.
Map<String, Thing[]> mapOfArrays;
В моем случае, поскольку мне нужно передать значения карты вбиблиотечный метод, который требует массив, было бы наиболее удобно собирать в Map<String, Thing[]>
.
Собрать весь поток в один массив легко (даже не требуется явный сборщик):
Thing[] arrayOfThings = Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
.toArray(Thing[]::new);
[Принадлежит владельцу1, Принадлежит владельцу2, Принадлежит владельцу1]
Также легко найти идентификатор владельца.Например, чтобы сгруппировать в списки:
Map<String, List<Thing>> mapOfLists = Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
.collect(Collectors.groupingBy(Thing::getOwnerId));
{owner1 = [принадлежит владельцу1, принадлежит владельцу1], владельцу2 = [принадлежит владельцу2]}
Только этот пример дает мне карту списков .Существуют методы 2-arg и 3-arg groupingBy
, которые могут дать мне карту других типов коллекций (например, наборов).Я подумал, что если я смогу передать сборщик, который собирает в массив (аналогично сбору в массив в первом фрагменте выше), в два аргумента Collectors.groupingBy(Function<? super T,? extends K>, Collector<? super T,A,D>)
, я был бы установлен.Однако ни один из предопределенных сборщиков в классе Collectors
, похоже, ничего не делает с массивами.Я пропускаю не слишком сложный путь?
Ради полного примера, вот класс, который я использовал в приведенных выше фрагментах:
public class Thing {
private String ownerId;
public Thing(String ownerId) {
this.ownerId = ownerId;
}
public String getOwnerId() {
return ownerId;
}
@Override
public String toString() {
return "Belongs to " + ownerId;
}
}