流上的groupingBy
操作是否可以生成一个映射,其中值是数组而不是列表或其他集合类型?
例如:我有一个类Thing
。事物有所有者,所以Thing
有一个getOwnerId
方法。在一个事物流中,我想按所有者ID对事物进行分组,以便具有相同所有者ID的事物最终在一个数组中。换句话说,我想要一个像下面这样的映射,其中键是所有者ID,值是属于该所有者的事物数组。
Map<String, Thing[]> mapOfArrays;
在我的例子中,因为我需要将映射值传递给一个需要数组的库方法,所以收集到一个< code >映射中是最方便的
将整个流收集到一个数组中很容易(甚至不需要显式收集器):
Thing[] arrayOfThings = Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
.toArray(Thing[]::new);
[属于所有者1,属于所有者2,属于所有者1]
通过所有者ID进行摸索也很容易。例如,要分组到列表中:
Map<String, List<Thing>> mapOfLists = Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
.collect(Collectors.groupingBy(Thing::getOwnerId));
{owner1=[屬於 owner1, 屬於 owner1], owner2=[屬於 owner2]}
只有这个例子给了我一个列表图。有2-arg和3-arg groupingBy
方法可以提供其他集合类型(如集合)的映射。我想,如果我可以将收集到数组中的收集器(类似于上面第一个代码片段中收集到数组中的收集器)传递给two-arg 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;
}
}
可能很明显,但您可以通过以下方式完成:
Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
.collect(Collectors.toMap(
Thing::getOwnerId,
x -> new Thing[]{x},
(left, right) -> {
Thing[] newA = new Thing[left.length + right.length];
System.arraycopy(left, 0, newA, 0, left.length);
System.arraycopy(right, 0, newA, left.length, right.length);
return newA;
}
))
您可以先分组,然后使用后续的toMap:
Map<String, Thing[]> result = source.stream()
.collect(groupingBy(Thing::getOwnerId))
.entrySet()
.stream()
.collect(toMap(Map.Entry::getKey,
e -> e.getValue().toArray(new Thing[0])));
使用Thomas Pliakas的这个答案中的收集器:
Map<String, Thing[]> mapOfArrays = Stream.of(new Thing("owner1"), new Thing("owner2"), new Thing("owner1"))
.collect(Collectors.groupingBy(Thing::getOwnerId,
Collectors.collectingAndThen(Collectors.toList(),
tl -> tl.toArray(new Thing[0]))));
想法是首先收集到一个列表中(这是一个明显的想法,因为数组有固定的大小),然后在返回到collector分组之前转换为一个数组。< code >收集然后可以通过其所谓的整理器来完成。
打印结果以供检查:
mapOfArrays.forEach((k, v) -> System.out.println(k + '=' + Arrays.toString(v)));
owner1=[Belongs to owner1, Belongs to owner1]
owner2=[Belongs to owner2]
编辑:感谢Aomine的链接:使用< code>new Thing[0]作为< code>toArray的参数是受古人智慧阵列的启发。似乎在英特尔CPU上使用< code>new Thing[0]比使用< code>new Thing[tl.size()]要快。我很惊讶。
我试图将请求体从邮递员映射到spring boot实体,
问题 你有一个对象数组,想把这些对象映射到另一个数组中,就像 Ruby 的映射一样。 解决方案 使用 map() 和匿名函数,但不要忘了还有列表推导。 electric_mayhem = [ { name: "Doctor Teeth", instrument: "piano" }, { name: "Janice", instrument: "lead g
我正在尝试将我的对象[]数组映射并过滤到int[]数组。如果对象是int,效果很好,但如果不是int,则抛出强制转换异常。我想知道我是否可以在lambda表达式中附加一个try/catch?这是我的代码: 或者更好的方法是试着抓住整个街区?
我有一个需要过滤的对象。 我需要输入“数据”,只有“isEnabled”为真的值的ID。
问题内容: 我将Spring JPA与Hibernate和Postgres一起使用 在实体中,我尝试使用List和integer [] 在数据库中,我有一列类型: 有什么JPA使用方式吗? 问题答案: JPA无法直接将数组持久化到单独的表或数据库数组(例如,映射到的数组)。因此,您有两种方法: 1)用于将该列另存为BLOB或CLOB 2)使用而不是数组
问题内容: 我有两个数组,一个带有url,一个带有内容。他们看起来像这样: 如何同时映射两个数组,并在新创建的元素中使用它们的值? 我需要使用我的reactplayer的url值和内容的值作为播放器下方的文本。 所以它应该看起来像这样: 这可能吗?更好的设置方法是什么? 问题答案: 使用的第二个参数(即当前元素的索引),可以访问第二个数组的正确元素。 如果您的项目中有其中一种库,那么这是该库中各种