我可以使用 lambda 表达式返回集合的单个值吗?

问题描述 投票:0回答:1

我有一个集合,我想制作一个简单的过滤器来获取T值,例如

getById( int idOfT)

我试过这个:

return (T) stream.filter( t -> t.getId().equals(id));

但它不起作用并显示此错误

Exception in thread "main" java.lang.ClassCastException: class java.util.stream.ReferencePipeline$2 cannot be cast to class T
java filter lambda
1个回答
0
投票

流中缺少终端操作

流由三个部分组成:

  • 源,例如对象集合。
  • 中间操作。
  • 终端操作。

您错过了第三个,即终端操作。您定义了一个过滤器,但从未对结果执行任何操作。而且,流是惰性的,因为在应用终端操作之前不会进行任何处理。

这是我们在过滤后应用终端操作的示例。

定义一个 record 作为我们的自定义类,

Pet
。顺便说一句,请注意,可以在本地定义记录 - 对于构建报告等非常方便。

record Pet( String species , String name ) { }

一些样本数据。

List < Pet > pets =
        List.of(
                new Pet( "Dog" , "Boo" ) ,
                new Pet( "Cat" , "Fluffy" ) ,
                new Pet( "Cat" , "Spot" ) ,
                new Pet( "Bird" , "Bucky" )
        );

现在是主要事件:创建一个流,过滤我们想要的元素,并在找到任何元素时停止。我们通过调用

Stream#findAny
来执行该停止。

小提示:我们使用

findAny
而不是
findFirst
来为流实现提供以任何顺序过滤流的任何部分的灵活性。我们不关心名为 Spot 的第一个宠物,我们想要名为 Spot 的任何宠物。您应该选择适合您的需求和逻辑的终端操作。 Optional < Pet > optionalPetNamedSpot = pets .stream( ) .filter( ( Pet pet ) -> pet.name.equalsIgnoreCase( "Spot" ) ) .findAny( ); 我们得到了

Optional

Optional

 是一个包装器,它要么携带我们所需类型的对象(此处为 
Pet),要么不携带任何内容(如果根本没有宠物被命名为 Spot)。使用
Optional
就可以避免
null
悲剧。
转储到控制台。
System.out.println( "optionalPetNamedSpot = " + optionalPetNamedSpot );

运行时:

optionalPetNamedSpot = Optional[Pet[species=Cat, name=Spot]]

如果您需要实际的

Pet
 对象,请测试 
Optional

有一个(不为空),然后调用

Optional#get
等方法之一。
if( optionalPetNamedSpot.isPresent() )
{
    Pet petNamedSpot = optionalPetNamedSpot.get() ;
    …
} 
else
{
    … handle situation where no Pet was found to have a name of "Spot". 
}
    

© www.soinside.com 2019 - 2024. All rights reserved.