如何在Java 8流中编写以下方法?我找不到办法做到这一点。这是我的代码:
public static List<ObjectB> getFilteredList(List<ObjectA> list, LocalTime startTime, LocalTime endTime, int quantity) {
List<ObjectA> objectAList = new LinkedList<>();
List<ObjectB> objectBList = new LinkedList<>();
for (ObjectA object : list) {
if (object.getDateTime().toLocalTime().isAfter(startTime) && object.getDateTime().toLocalTime().isBefore(endTime)) {
objectAList.add(object);
}
}
for (ObjectA objectA : objectAList) {
int total = 0;
for (ObjectA object : list) {
if (object.getDateTime().toLocalDate().equals(objectA.getDateTime().toLocalDate())) {
total += object.getQuantity();
}
}
if (total > quantity) {
objectBList.add(new ObjectB(objectA.getDateTime(), objectA.getDescription(), objectA.getQuantity(), true));
} else {
objectBList.add(new ObjectB(objectA.getDateTime(), objectA.getDescription(), objectA.getQuantity(), false));
}
}
return objectBList;}
我有一个包含两个字段的对象列表:日期和数量。我需要为每个日期返回一个包含一个对象的列表,但是还有一个feild - boolean,如果每天所有数量的总和大于16,则为true,如果不是则为false。
答案 0 :(得分:1)
让我们一步一步来做。
for (ObjectA object : list) {
:for循环通常替换为stream()
,因此请从list.stream()
开始。if (...) {
:条件通常替换为filter()
,因此请继续.filter(object -> object.getDateTime()...)
objectAList.add(object);
:将结果添加到容器通常会替换为collect()
。您使用的是LinkedList()
,但此处的任何其他列表都没问题,因此我们只需使用collect(Collectors.toList())
。所以这是第一个循环:
List<ObjectA> objectAList = list.stream()
.filter(object -> object.getDateTime().toLocalTime().isAfter(startTime) &&
object.getDateTime().toLocalTime().isBefore(endTime))
.collect(Collectors.toList());
现在让我们看看计算total
:
int total = 0;
for (ObjectA object : list) {
if (object.getDateTime().toLocalDate().equals(objectA.getDateTime().toLocalDate())) {
total += object.getQuantity();
}
}
它也是流过滤器收集序列,但在这里你要收集总和。因此,您可以在IntStream
处使用sum()
方法:
int total = list.stream()
.filter(object -> object.getDateTime().toLocalDate().equals(
objectA.getDateTime().toLocalDate())
.mapToInt(ObjectA::getQuantity).sum();
为了让您的代码不那么拥挤,我会将其提取到单独的方法中:
private static int getQuantityByDate(List<ObjectA> list, LocalDate date) {
return list.stream().filter(object -> object.getDateTime().toLocalDate().equals(date))
.mapToInt(ObjectA::getQuantity).sum();
}
现在是下一个if
语句。它只是改变了最后一个布尔参数,所以我会重写它(即使没有Stream API):
objectBList.add(new ObjectB(objectA.getDateTime(), objectA.getDescription(),
objectA.getQuantity(), total > quantity));
所以现在我们看到外部循环变成了stream-map-collect链,可以这样重写:
List<ObjectB> objectBList = objectAList.stream()
.map(objectA ->
new ObjectB(objectA.getDateTime(), objectA.getDescription(), objectA.getQuantity(),
getQuantityByDate(list, objectA.getDateTime().toLocalDate()) > quantity))
.collect(Collectors.toList());
现在你可以注意到收集到objectAList
是不必要的,因为我们只是用它来创建另一个流。因此,我们可以将两个循环合并到单个管道中,从而生成以下最终代码:
private static int getQuantityByDate(List<ObjectA> list, LocalDate date) {
return list.stream().filter(object -> object.getDateTime().toLocalDate().equals(date))
.mapToInt(ObjectA::getQuantity).sum();
}
public static List<ObjectB> getFilteredList(
List<ObjectA> list, LocalTime startTime, LocalTime endTime, int quantity) {
return list.stream()
.filter(object -> object.getDateTime().toLocalTime().isAfter(startTime) &&
object.getDateTime().toLocalTime().isBefore(endTime))
.map(objectA -> new ObjectB(
objectA.getDateTime(), objectA.getDescription(), objectA.getQuantity(),
getQuantityByDate(list, objectA.getDateTime().toLocalDate()) > quantity))
.collect(Collectors.toList());
}