当有全局变量赋值时,如何将带有嵌套ifs的for循环映射到Java8流

当有全局变量赋值时,如何将带有嵌套ifs的for循环映射到Java8流,java,for-loop,foreach,java-8,java-stream,Java,For Loop,Foreach,Java 8,Java Stream,我一直在尝试学习Java8.stream(),并将其转换为for循环。我找不到合适的方法来做这件事。地图,还有,forEach在这里似乎帮不了什么忙 我的主要问题是,我试图将DateFormat releaseDate分配给已解析的records.getReleaseDate()对象,然后将其与set beforeDate对象进行比较。有什么想法吗 DateFormat sourceFormat = new SimpleDateFormat("yyyy.MM.dd"); Date release

我一直在尝试学习Java8.stream(),并将其转换为for循环。我找不到合适的方法来做这件事。地图,还有,forEach在这里似乎帮不了什么忙

我的主要问题是,我试图将DateFormat releaseDate分配给已解析的records.getReleaseDate()对象,然后将其与set beforeDate对象进行比较。有什么想法吗

DateFormat sourceFormat = new SimpleDateFormat("yyyy.MM.dd");
Date releaseDate = new Date();
Date beforeDate;

beforeDate = sourceFormat.parse("2001.01.01");

Records records = (Records) obj;

for (Record recs : records.getRecordsList()) {
    try {
        releaseDate = sourceFormat.parse(((Record) recs).getReleaseDate());
    } catch (ParseException e) {
        System.err.println("PARSE EXCEPTION. Unable to parse record.getReleaseDate()");
        e.printStackTrace();
    }

    if (((Record) recs).getTrackListing().size() > 10) {
        if (releaseDate.before(beforeDate)) {
            Release release = new Release();
            release.setName(((Record) recs).getName());
            release.setTrackCount(((Record) recs).getTrackListing().size());
            data.add(release);
        }
    }
}
这是我对.stream()的最初方法:


我还没有真正测试代码,我希望这个想法是明确的。我会这样做:

final DateFormat sourceFormat = new SimpleDateFormat("yyyy.MM.dd");
final Date beforeDate = sourceFormat.parse("2001.01.01");

((Records) obj).getRecordsList()
        .stream()
        .filter(rec -> rec.getTrackListing().size() > 10)
        .filter(rec -> {
            try {
                return sourceFormat.parse(rec.getReleaseDate()).before(beforeDate));
            } catch (ParseException e) {
                System.err.println("PARSE EXCEPTION. Unable to parse record.getReleaseDate()");
                e.printStackTrace();
                return null;
            }
        })
        .filter(Objects::nonNull)
        .map(rec -> {
            Release release = new Release();
            release.setName(rec.getName());
            release.setTrackCount(rec.getTrackListing().size());
            return release;
        })
        .collect(Collectors.toList());

顺便说一句,如果您使用Java 8,我建议您使用它来避免
ParseException
和空检查,这将是一种更干净的方法。

我理解您的问题,您不知道如何使用
.map
forEach
流函数
.map
用于使“流”保持活动状态,并将流经流的实际对象/值映射(在您的示例中,从
Record
的实例映射到
Release
的实例)
.forEach
是一个接收器,因此流始终以
forEach
结束。因此,您需要使用
.map
(请参阅)

您的源代码已经存在一些问题:

  • 如果解析了
    releaseDate
    并引发异常,该怎么办?
    releaseDate
    的值不会改变(可能是
    new Date()
    或上一条记录的值)
  • 如果只在
    getTrackListing().size()>10
    时使用
    releaseDate
    ,为什么还要解析它呢?我只会在条件被选中
    true
    后才解析它
  • 要使用lambdas,您的“外部变量”必须是
    final
    ,才能在流中使用
  • 这就是说,为了让你的东西正常工作,你走上了正确的轨道,但你仍然必须
    将你的
    记录映射到
    发布

    // see 3.
    final Date beforeDate = sourceFormat.parse("2001.01.01");
    
    records.getRecordsList().stream()       
        .filter(r -> r.getTrackListing().size() > 10)
        .filter(r - {
           // if the parsedDate is invalid we don't want to process, see 1. and 2.
           Date parsedDate;
           try {
              parsedDate = sourceFormat.parse(r.getReleaseDate());
           } catch (ParseException e) {
              System.err.println("...");
              e.printStackTrace();
              parsedDate = null;
           }
    
           return parsedDate != null && parsedDate.before(beforeDate);
        })
        .map(r -> {
           // map the records to an release
           Release release = new Release();
           release.setName(r.getName());
           release.setTrackCount(r.getTrackListing().size());
           return release;
        })
        .collect(Collectors.toList()));
    

    我只是复制并粘贴了您的代码(并修复了明显的语法错误),请仔细查看!

    您已经展示了您迄今为止的尝试,但还没有告诉我们问题所在。这可能与我脑海中的第二个.filter()中的函数完全相同方法。感谢您提供的简明示例和详细的解释。此外,您对我的逻辑的评论非常准确,说得很好!总是很乐意提供帮助,如果您能提供“标记为解决方案”,我们将不胜感激,谢谢!
    // see 3.
    final Date beforeDate = sourceFormat.parse("2001.01.01");
    
    records.getRecordsList().stream()       
        .filter(r -> r.getTrackListing().size() > 10)
        .filter(r - {
           // if the parsedDate is invalid we don't want to process, see 1. and 2.
           Date parsedDate;
           try {
              parsedDate = sourceFormat.parse(r.getReleaseDate());
           } catch (ParseException e) {
              System.err.println("...");
              e.printStackTrace();
              parsedDate = null;
           }
    
           return parsedDate != null && parsedDate.before(beforeDate);
        })
        .map(r -> {
           // map the records to an release
           Release release = new Release();
           release.setName(r.getName());
           release.setTrackCount(r.getTrackListing().size());
           return release;
        })
        .collect(Collectors.toList()));