Java:从另一个数组的属性创建数组

6

有没有一种简单的方法在Java中(不涉及编写for循环)从另一个不同对象数组的属性创建对象数组?

例如,如果我有一个类型为A 的对象数组,定义为:

public class A {
    private String p;
    public getP() {
        return p;
    }
}

我想创建一个包含每个iA[i].p值的字符串数组。

基本上,我想做的是在Java中实现以下操作:从另一个数组中的对象属性创建数组

我尝试使用Arrays.copyOf(U[] original, int newLength, Class<? extends T[]> newType)以及lambda表达式,但似乎行不通。我的尝试:

Arrays.copyOf(arrayA, arrayA.length, (A a) -> a.getP());

2
你可以使用Java 8流,但最终都会归结为for循环。 - Louis Wasserman
可能是Java复制数组的重复问题。 - Frank Puffer
@LouisWasserman 我明白,但如果可能的话,我更喜欢一行代码。 - rom58
2个回答

11

使用Java 8,您可以使用Stream API尤其是map函数:

A[] as = { new A("foo"), new A("bar"), new A("blub") };
String[] ps = Stream.of(as).map(A::getP).toArray(String[]::new);

这里的A::getPString[]::new是方法/构造函数的引用。如果你没有适合你想要的属性的方法,你也可以使用lambda函数:

String[] ps = Stream.of(as).map(a -> a.getP()).toArray(String[]::new);

1
a -> a.getP()A::getP 有什么不同? - rom58
1
不是变量,而是用于Lambda表达式的方法引用。 - Kedar Mhaswade
在这种情况下,它们是等效的,但应该优先使用方法引用,因为它更清楚地传达了它将仅使用该方法而不使用其他内容。如果需要一个没有现有方法的函数,请使用lambda,例如a -> a.getP().trim().toUpperCase()(尽管这也可以通过方法引用和三个连续的“map”来完成)。 - tobias_k

2

在功能性编程中,有一个强大的概念叫做map,它非常有用。以下是map的定义:

map :: (a -> b) -> [a] -> [b]

因此,map是一个函数,它接受一个函数(该函数接受a并返回b)和一个列表,并返回一个列表。它将给定函数应用于给定列表的每个元素。因此,map是一个高阶函数。
在Java 8中,如果您可以将数组转换为流,则可以使用这种惯用法。这可以简单地完成:
Arrays.stream(array).map(mappingFunction);

mappingFunction接受来自流的元素(例如类型为A),并将其转换为另一个元素(例如类型为B)。现在你拥有了一串B,你可以轻松地将它们收集到一个收集器中(例如列表或数组)以进行进一步处理。


这会产生一个流。要转换为数组,您需要使用Stream.toArray(),就像其他评论中使用的那样。 - Naeio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接