2016-05-30 63 views
-2

如何在Java 8流中编写以下方法?我找不到一个办法。这是我的代码:如何在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 - 布尔值,如果每天所有数量的总和大于16,则该值为true;如果不是,则为false。

+0

你有什么试过的?你有什么麻烦?其中一些转换非常直接。 – pvg

+0

你能用英文解释代码应该做什么吗?随样品输入/输出。 – Tunaki

+0

我是Java 8流的新手,对我来说最大的问题是执行此部分:(ObjectA objectA:objectAList){ int total = 0; (objectA object:list){ if(object.getDateTime()。toLocalDate()。equals(objectA.getDateTime()。toLocalDate())){ total + = object。getQuantity(); } } 谢谢 – Geha

回答

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声明。它只是改变了最后的布尔参数,所以我会重写它(即使没有流API):

objectBList.add(new ObjectB(objectA.getDateTime(), objectA.getDescription(), 
     objectA.getQuantity(), total > quantity)); 

所以现在我们看到,外环变成数据流的地图收集链,并且可以这样改写:

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()); 
} 
+0

谢谢!这是有帮助的 – Geha