Java8 过滤器数组列表与字段日期的自定义对象



我必须在字段上过滤List<Card>issueDate(键入String),其中卡片显示到最近 7 年日期。

我尝试的解决方案是将issueDate字段从String解析为Date,然后应用date.after(startDate)date.before(endDate)如下所示:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
cardList.stream()
.map(s->s.getIssueDate())
.filter(dt -> sdf.parse(dt).after(sdf.parse("2020-06-08")) && 
sdf.parse(dt).before(sdf.parse("2020-08-12")))
.collect(Collectors.toList());  

甚至不能申请循环,因为可能会发行数百张卡,并且通过迭代每个发卡日期(字符串到日期和检查年份)来影响性能

任何人都可以提出解决这个问题的好方法吗?

您的代码存在许多问题:

  1. java.util日期时间 API 及其格式设置 APISimpleDateFormat已过时且容易出错。建议完全停止使用它们并切换到现代日期时间 API*
  2. 您应该将issueDate声明为LocalDate(如果您仍想坚持使用旧版 API,则声明为Date)而不是String。但是,出于任何原因,如果您仍想将其保留为String,则可以更改代码以在流处理期间仅将其解析为日期类型对象一次(目前,您正在执行两次)。
  3. 您正在流处理中解析2020-06-082020-08-12,而它们是静态值,因此应在流处理外部解析它们。实际上,如果这些静态日期不那么String,则可以直接创建日期类型对象,例如LocalDate start = LocalDate.of(2020, 6, 8).

这些建议已合并到以下代码中:

LocalDate start = LocalDate.parse("2020-06-08");
LocalDate end = LocalDate.parse("2020-08-12");
List<LocalDate> dates = 
cardList.stream()
.map(card -> LocalDate.parse(card.getIssueDate()))
.filter(ld -> ld.isAfter(start) && ld.isBefore(end))
.collect(Collectors.toList());

如果要将流收集到卡片列表中,可以执行以下操作:

List<Card> cards = 
cardList.stream()
.filter(card -> {
LocalDate ld = LocalDate.parse(card.getIssueDate());                            
return ld.isAfter(start) && ld.isBefore(end);
})
.collect(Collectors.toList());

* 出于任何原因,如果你必须坚持使用 Java 6 或 Java 7,你可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请查看通过脱糖提供的 Java 8+ API 和如何在 Android Project 中使用 ThreeTenABP。要了解有关现代日期时间 API 的更多信息,请参阅跟踪:日期时间

不确定是否需要在此处解析日期。您的所有日期都是String的,并且具有相同的yyyy-MM-dd格式。

在这种特殊情况下,您可以简单地按字典顺序比较字符串:

String from = "2020-06-08";
String to = "2020-08-12";
List<Card> filteredCardList = 
cardList.stream()
.filter(card -> card.getIssueDate().compareTo(from) > 0)
.filter(card -> card.getIssueDate().compareTo(to) < 0)
.collect(toList());

或者你对普通的旧循环做同样的事情:

List<Card> filteredCardList = new ArrayList<>();
for(Card card : cardList) {
String date = card.getIssueDate();
if(date.compareTo(from) > 0 && date.compareTo(to) < 0) {
filteredCardList.add(card);
}
}

相关内容

  • 没有找到相关文章

最新更新