Java Stream:在多个列表上进行嵌套流查找会抛出NPE

时间:2018-10-02 14:49:23

标签: java list collections java-8 java-stream

我在Java 7中具有以下代码:

USE [test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[SP_GetSeqVal]
@result int output
as
begin
    declare @NewSeqValue int

    set NOCOUNT ON

    insert into SEQ_SERIAL_NO(seqval) values ('a')

    set @NewSeqValue = scope_identity()

    set @NewSeqValue = Convert(char(4),Getdate(),112) + right('000000'+CAST(scope_identity() AS varchar(5)),5)

    delete from SEQ_SERIAL_NO WITH (READPAST)

    set @result=@NewSeqValue
    return @NewSeqValue  
end

Declare @NewSeqVal int,@myResult   int
Exec @NewSeqVal=GetSeqVal @myResult output
Print @myResult
print @NewSeqVal

我正在尝试将其更改为流

List<Integer> idMappers= new ArrayList<>();

//getting information from a Map<String, List<String>>
List<String> ids= idDataStore.lookupId(id); 

 for (int i = 0; i < ids.size(); i++) {

 //getting information from a Map<String, List<Integer>>
  List<Integer> mappers= idDataStore.lookupMappers(ids.get(i));

  if (mappers!= null) {
    for (int j = 0; j < x.size(); j++) {
      idMappers.add(mappers.get(j));
    }
  }
}

我的问题是List<Integer> idMappers= new ArrayList<>(); idDataStore.lookupIdMappings(id).forEach(id-> { idDataStore.lookupSegments(id).forEach(mapper->{ idSegments.add(segment); }); }); 有时会抛出null,因此我的信息流中断了。如何在Stream中进行空值检查?

2 个答案:

答案 0 :(得分:2)

首先,在方法完全相同的范围内,在lambda中使用的变量(id)不能与变量具有相同的名称。

  

Lambda表达式的参数ID无法重新声明在封闭范围内定义的另一个局部变量。

我看到您使用嵌套循环,为什么不使用Stream::flatMap

idDataStore.lookupIdMappings(id).stream()
                                .map(i -> idDataStore.lookupSegments(id))
                                .filter(Objects::nonNull)
                                .flatMap(List::stream)
                                .collect(Collectors.toList());

答案 1 :(得分:1)

只需将idDataStore.lookupSegments(id).stream().filter(Objects::notNull)添加到嵌套循环中即可。

但是,您拥有的是side effect(请参见副作用部分),不建议您填充idMappers列表。让我尝试使用flatMap

进行转换
List<Integer> idMappers = idDataStore.lookupIdMappings(id)
           .stream() // stream of LookupId's
           .flatMap(idMapping -> idDataStore
                                .lookupSegments(id)
                                .stream()
                                .filter(Objects::notNull)
                                // get stream of corresponding lookupSegments
                                // and filter out all nulls
           )
           .collect(Collectors.toList());

我希望这会有所帮助。