我必须在字段上过滤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());
甚至不能申请循环,因为可能会发行数百张卡,并且通过迭代每个发卡日期(字符串到日期和检查年份)来影响性能
任何人都可以提出解决这个问题的好方法吗?
您的代码存在许多问题:
java.util
日期时间 API 及其格式设置 APISimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到现代日期时间 API*。- 您应该将
issueDate
声明为LocalDate
(如果您仍想坚持使用旧版 API,则声明为Date
)而不是String
。但是,出于任何原因,如果您仍想将其保留为String
,则可以更改代码以在流处理期间仅将其解析为日期类型对象一次(目前,您正在执行两次)。 - 您正在流处理中解析
2020-06-08
和2020-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);
}
}