我有一个集合,我想制作一个简单的过滤器来获取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
流由三个部分组成:
您错过了第三个,即终端操作。您定义了一个过滤器,但从未对结果执行任何操作。而且,流是惰性的,因为在应用终端操作之前不会进行任何处理。
这是我们在过滤后应用终端操作的示例。
定义一个 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".
}