使用java8流创建另一个对象列表

时间:2016-02-26 11:50:57

标签: java java-stream

我正在尝试理解Java 8流。 我有两个班:

public class UserMeal {
    protected final LocalDateTime dateTime;

    protected final String description;

    protected final int calories;

    public UserMeal(LocalDateTime dateTime, String description, int calories) {
        this.dateTime = dateTime;
        this.description = description;
        this.calories = calories;
    }

    public LocalDateTime getDateTime() {
        return dateTime;
    }

    public String getDescription() {
        return description;
    }

    public int getCalories() {
        return calories;
    }
}

public class UserMealWithExceed {
    protected final LocalDateTime dateTime;

    protected final String description;

    protected final int calories;

    protected final boolean exceed;

    public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) {
        this.dateTime = dateTime;
        this.description = description;
        this.calories = calories;
        this.exceed = exceed;
    }
}

exceed字段应指示一整天的卡路里总和。该字段对于当天的所有条目都是相同的。

我尝试从List<UserMeal> mealList获取对象,按天分组,计算一段时间的卡路里​​,然后创建List<UserMealWithExceed>

public static List<UserMealWithExceed>  getFilteredMealsWithExceeded(List<UserMeal> mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) {

    return mealList.stream()
            .filter(userMeal -> userMeal.getDateTime().toLocalTime().isAfter(startTime)&&userMeal.getDateTime().toLocalTime().isBefore(endTime))
            .collect(Collectors.groupingBy(userMeal -> userMeal.getDateTime().getDayOfMonth(),
                         Collectors.summingInt(userMeal -> userMeal.getCalories())))
            .forEach( ????? );
}

但我不明白如何在forEach中创建新对象并返回集合。

我如何看待伪代码:

.foreach( 
    if (sumCalories>caloriesPerDay)
    {return new UserMealWithExceed(userMeal.getdateTime, usermeal.getDescription, usermeal.getCalories, true);}
    else
    {return new UserMealWithExceed(userMeal.getdateTime, usermeal.getDescription, usermeal.getCalories, false)
    }
)//foreach

4 个答案:

答案 0 :(得分:88)

如果要迭代列表并使用“已转换”对象创建新列表,则应使用stream + map()的{​​{1}}函数。在下面的示例中,我找到姓氏为“l1”的所有人以及每个人“映射”到新的Employee实例。

collect()

答案 1 :(得分:10)

您可能正在寻找的是map()。你可以&#34;转换&#34;通过这种方式映射到另一个流中的对象:

...
 .map(userMeal -> new UserMealExceed(...))
...

答案 2 :(得分:1)

@Rafael Teles解决方案的补充。语法糖Collectors.mapping一步完成相同的操作:

//...
List<Employee> employees = persons.stream()
  .filter(p -> p.getLastName().equals("l1"))
  .collect(
    Collectors.mapping(
      p -> new Employee(p.getName(), p.getLastName(), 1000),
      Collectors.toList()));

可以找到详细的示例here

答案 3 :(得分:-1)

我更喜欢用经典的方式解决这个问题,创建一个我想要的数据类型的新数组:

List<MyNewType> newArray = new ArrayList<>();
myOldArray.forEach(info -> newArray.add(objectMapper.convertValue(info, MyNewType.class)));