如何在lambda过滤器中使用多个声明?

时间:2016-11-27 00:27:40

标签: lambda java-8

我对Lambdas很新,我试图以下列方式使用它,但它似乎不起作用。是否有可能有多个声明,其中 ONE 是条件?

ArrayList<Message> msgs = new ArrayList<>(ms.values());
Calendar cal = Calendar.getInstance();

msgs.stream().filter( m -> {
    cal.setTime(m.getCreated());
    cal.get(Calendar.YEAR) == year
});

我知道它的作用如下:

collection.stream().filter(x -> 1 == x);

但是因为我需要设置Date并将其与Calendar一起使用来获得年份,所以我必须在两个声明中这样做。

我知道这有效:

msgs.forEach(m -> {
    cal.setTime(m.getCreated());
    if (cal.get(Calendar.YEAR) != year) {
        msgs.remove(m);
    }
});

但我想知道是否可以按照我想要的方式或类似的方式来做这件事?

2 个答案:

答案 0 :(得分:3)

如果使用花括号,则需要返回一个值。它期望一个布尔返回值。它只是假设没有大括号。

return cal.get(Calendar.YEAR) == year;

答案 1 :(得分:1)

  

但我想知道是否可以按照我想要的方式或类似的方式来做这件事?

您甚至不需要使用旧的Calendar API。由于您使用的是旧Date,因此需要将其转换为具有ZonedDateTime的Java 8 a simple method to get the year

您的过滤器将如下所示(为了清晰起见,提取到方法):

List<Message> filterOnYear(int year, List<Message> msgs) {
  return msgs.stream()
      .filter(msg -> msg.getCreated().toInstant().atZone(ZoneId.systemDefault()).getYear() == year)
      .collect(Collectors.toList());
}

Date#toInstant()是Java 8中的一种新方法,我们将其用作旧Date和Java 8 Date and Time API之间的桥梁。转换可能看起来有点单调乏味,但这是因为Date并不完全是日期,as discussed here

  

尽管名称不同,java.util.Date代表时间线上的瞬间,而不是&#34; date&#34;。存储在对象中的实际数据是自1970-01-01T00:00Z(GMT / UTC 1970年初午夜)以来的长时间毫秒数。