在Java8中连接对象数组列表
我将一维数组的列表包装在一个对象中,我希望使用java-8 stream和collect将它们收集在一个数组中 具有数组的给定类项在Java8中连接对象数组列表,java,arrays,java-8,Java,Arrays,Java 8,我将一维数组的列表包装在一个对象中,我希望使用java-8 stream和collect将它们收集在一个数组中 具有数组的给定类项 class A{ int x; } class Item{ A[] parts=new A[]; public A[] getParts(){ return parts; } } 所以如果我有清单l List<Item> l=new ArrayList<>(); l.add(new Item())
class A{
int x;
}
class Item{
A[] parts=new A[];
public A[] getParts(){
return parts;
}
}
所以如果我有清单l
List<Item> l=new ArrayList<>();
l.add(new Item());
l.add(new Item());
我试着去做
l.stream().map(Item::getParts).collect(Collectors.toList()).toArray(new A[n]);
但显然它有很多问题。您想使用.flatMap而不是.map;在lambda中,只需在数组中生成一个新的项目流。您希望使用.flatMap而不是.map;在lambda中,只需在数组中生成一个新的项目流。尝试以下操作:
static void test() {
List<Item> l = new ArrayList<>();
l.add(new Item(1, 2,5));
l.add(new Item(3, 4,10));
System.out.println(l);
int totalNoOfParts = l.stream().mapToInt(item->item.getParts().length).reduce(0, Integer::sum);
A[] allParts = l.stream().map(item -> item.getParts()).collect(() -> new A[totalNoOfParts],
(c, e) -> System.arraycopy(e, 0, c, getNextPos(c), e.length),
(c1, c2) -> System.arraycopy(c2, 0, c1, getNextPos(c1), c2.length));
System.out.println(Arrays.asList(allParts));
}
static int getNextPos(A[] a) {
for (int i = 0; i < a.length; i++) {
if (a[i] == null)
return i;
}
throw new InvalidParameterException("Invalid index value");
}
我修改了您的Item类,使其具有固定长度的数组
class Item {
A[] parts = new A[3];
Item(int... values) {
Objects.requireNonNull(values, "Argument Not Valid");
for (int i = 0; i < values.length; i++) {
parts[i] = new A();
parts[i].x = values[i];
}
}
public A[] getParts() {
return parts;
}
}
请尝试以下操作:
static void test() {
List<Item> l = new ArrayList<>();
l.add(new Item(1, 2,5));
l.add(new Item(3, 4,10));
System.out.println(l);
int totalNoOfParts = l.stream().mapToInt(item->item.getParts().length).reduce(0, Integer::sum);
A[] allParts = l.stream().map(item -> item.getParts()).collect(() -> new A[totalNoOfParts],
(c, e) -> System.arraycopy(e, 0, c, getNextPos(c), e.length),
(c1, c2) -> System.arraycopy(c2, 0, c1, getNextPos(c1), c2.length));
System.out.println(Arrays.asList(allParts));
}
static int getNextPos(A[] a) {
for (int i = 0; i < a.length; i++) {
if (a[i] == null)
return i;
}
throw new InvalidParameterException("Invalid index value");
}
我修改了您的Item类,使其具有固定长度的数组
class Item {
A[] parts = new A[3];
Item(int... values) {
Objects.requireNonNull(values, "Argument Not Valid");
for (int i = 0; i < values.length; i++) {
parts[i] = new A();
parts[i].x = values[i];
}
}
public A[] getParts() {
return parts;
}
}
将每个项映射到它的A[]数组。然后,当有一个[]流时,只需将其平面映射,以获得每个数组的每个a,并使其在最后成为一个数组
A[] array = l.stream().map(x -> x.getParts())
.flatMap(x -> Arrays.stream(x))
.toArray(A[]::new); // [1, 2, 3, 4]
但是,如果您只对int值感兴趣,那么还有一个额外的步骤
int[] array = l.stream().map(x -> x.getParts())
.flatMap(x -> Arrays.stream(x))
.mapToInt(x -> x.getX())
.toArray();
将每个项映射到它的A[]数组。然后,当有一个[]流时,只需将其平面映射,以获得每个数组的每个a,并使其在最后成为一个数组
A[] array = l.stream().map(x -> x.getParts())
.flatMap(x -> Arrays.stream(x))
.toArray(A[]::new); // [1, 2, 3, 4]
但是,如果您只对int值感兴趣,那么还有一个额外的步骤
int[] array = l.stream().map(x -> x.getParts())
.flatMap(x -> Arrays.stream(x))
.mapToInt(x -> x.getX())
.toArray();
我删除了我的答案,您将通过阅读流教程了解更多信息。您的代码未编译。您的方法名为getParts,而不是getParts。和流作为方法,以及flatMap方法..为了流化数组的元素,必须使用array.streammyArray。目前,您的列表是数组列表,而不是数组中的元素列表。我删除了我的答案,您将通过阅读流教程了解更多信息。您的代码未编译。您的方法名为getParts,而不是getParts。和流作为方法,以及flatMap方法..为了流化数组的元素,必须使用array.streammyArray。当前,您的列表是数组列表,而不是数组中元素的列表。在这种情况下,我建议使用arrays.stream而不是stream.of。在这种情况下,我建议使用arrays.stream而不是stream.of。