使用 Lambda 和 forEach 在集合中查找对象并触发布尔值 [重复]
Posted
技术标签:
【中文标题】使用 Lambda 和 forEach 在集合中查找对象并触发布尔值 [重复]【英文标题】:Using Lambda and forEach to find an Object in a Set and triggering a boolean [duplicate] 【发布时间】:2017-05-15 03:38:03 【问题描述】:假设我有这门课
public class MovieCharacter
private String name;
public String getName() return name ;
public String setName(String name) this.name = name;
我正在运行一个测试并有一个 Set,我想使用 Lambda 梳理每个对象,看看它是否包含所需的名称字符串。如果找到名称,则布尔值被触发为“真”。找到后,我不希望布尔值再次更改。
Set<MovieCharacter> mySet // assume this Set has previously been created and
// contains 1,000's of MovieCharacter
boolean hasName = false;
mySet.forEach( i -> i.getName().equals("Darth Vader")) // add here?
assertTrue(hasName);
我知道我已经接近了,但是我将如何完成 lambda 行,以便如果集合包含一个 MovieCharacter,其中 .getName() 返回“Darth Vader”,那么布尔值将设置为 true?但如果我正在检查的项目没有,它只是继续前进?
谢谢!
【问题讨论】:
将您的类命名为与 JDK 中的类相同的名称是个坏主意,尤其是来自自动导入的java.lang
包。
这点很好,我要改变它。谢天谢地,这在我的实际程序中有所不同。以后阅读本文的人请注意 - MovieCharacter 曾经只是 Character。
另见***.com/questions/23004921/…
【参考方案1】:
您所描述的行为正是 anyMatch
方法的设计目的:
boolean hasName = mySet.stream().anyMatch(c -> c.getName().equals("Darth Vader"));
【讨论】:
或者(恕我直言)无 lambdamySet.stream().map(Character::getName).anyMatch("Darth Vader"::equals);
如果我知道我的套装只有一个匹配,我还想使用它吗?
@Mureinik 的回答完美,简洁明了,谢谢!一天我可能必须将它与一百万个项目一起使用,使用 paralellStream 是否需要任何差异?
@NateH06 只需将parallelStream()
放在那里而不是stream()
就完成了。但是请注意,底层集合可能会为其返回一个顺序流,因此建议进行一些测试。
@NateH06 如果你想要一个,请选择.stream().filter(c -> c.getName.equals("Darth Vader")).count() == 1
【参考方案2】:
你需要的是过滤操作与findFirst()
的组合返回Optional
。
如果您确定您的集合中有这样的项目,那么您可以在findFirst()
之后安全地调用get()
,但一般我建议您使用orElse
提供默认值或使用orElseThrow
抛出异常在那Optional
或使用其他有用的方法之一。明智地选择适合您的情况:)
set.stream()
.filter(character -> character.getName().equals("Darth Veider"))
.findFirst()
【讨论】:
根据我对 JavaDoc 的理解,此示例将返回 Optional以上是关于使用 Lambda 和 forEach 在集合中查找对象并触发布尔值 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
在Java8的foreach()中使用return/break/continue,不会跳出循环