Java - 从列表/数组中的每个对象获取单个属性的最简单方法?
Posted
技术标签:
【中文标题】Java - 从列表/数组中的每个对象获取单个属性的最简单方法?【英文标题】:Java - Easiest way to get single property from each object in a list/array? 【发布时间】:2017-09-01 19:30:43 【问题描述】:假设我有一个具有name
、hair color
和eye color
等属性的人员对象。我有以下数组Person[] people
,其中包含人员对象的实例。
我知道我可以使用
获得Person
对象之一的 name
属性
// create a new instance of Person
Person george = new Person('george','brown','blue');
// <<< make a people array that contains the george instance here... >>>
// access the name property
String georgesName = people[0].name;
但是如果我想在不使用索引的情况下访问每个人的name
属性怎么办?例如,要创建一个仅包含名称或头发颜色的数组或列表?我是否必须手动遍历我的 people
数组?或者在 Java 中有什么很酷的东西,比如 String[] peopleNames = people.name
?
【问题讨论】:
几乎你必须迭代。您可以使用流,但对于小型列表,它们效率不高。 您使用的是命令式语言。因此,显式迭代是可行的方法。如果您不喜欢编写循环,请使用函数式语言,例如 Scala。在那里,您可以使用简单的单线并拥有它。 您能否详细说明两者之间的区别,或许可以作为答案? @MatthiasFax,如果使用 Java 8 的流式 API,则无需显式迭代,这在本质上是函数式的。 @MatthiasFax,我同意你的观点,流式 API 是围绕核心语言而不是自下而上构建的,但它确实允许你使用函数式习语,因此不必显式迭代. “显式迭代”是我要解决的唯一问题。 【参考方案1】:两种选择:
-
迭代
流 (Java 8)
迭代
List<String> names = new ArrayList<>();
for (Person p : people)
names.add(p.name);
流
String[] names = Arrays.stream(people).map(p -> p.name).toArray(size -> new String[people.length]);
【讨论】:
因为 OP 会接受List
作为结果类型(“例如,创建一个仅包含名称或头发颜色的数组或 列表” ),为了完整起见,添加到 List<String>
的 for-each 循环将是另一个不错的选择,即 for (Person p : people) names.add(p.name);
@Andreas 啊是的!我最初打算做一个List<String>
,但在问题中没有注意到这一点【参考方案2】:
Java 8:
String[] names = Arrays.asStream(people).map(Person::getName).asArray(String[]::new);
【讨论】:
【参考方案3】:您正在寻找一种最初只支持命令式的 Java 语言的功能特性。正如其他答案中已经提到的那样,从 Java 8 开始,您还拥有功能元素(例如,流)。但是,尚不建议使用它们。这个blog post 解释了流优于循环的缺点(即性能、可读性、可维护性)。
如果您正在寻找没有这些重大影响的功能性和安全代码,请尝试使用 Scala:
case class Person(name: String)
val persons = Array(Person("george"), Person("michael"), Person("dexter"))
val personNames = persons.map(_.name)
主要区别在于该 Scala 代码易于阅读,并且其性能与使用循环的 Java 代码相当,因为翻译后的 Scala 到 Java 代码在内部使用了一个 while 循环。
【讨论】:
以上是关于Java - 从列表/数组中的每个对象获取单个属性的最简单方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何从对象数组中获取具有属性的列表,除非它包含具有特定值的另一个项目?