Java 使用Lambda将列表分组并求和为映射

Java 使用Lambda将列表分组并求和为映射,java,lambda,java-8,Java,Lambda,Java 8,我有一个MoveTrack对象的列表,我希望按月对这些对象进行分组,并将数据计数并存储在映射中。我正在尝试学习Lambda并用它做实验,所以我尝试用Lambda做这个任务 class MoveTrack { private Date time; private Double movementAmount; //getters and setters } // in my main method List<MoveTrack> mveTracking = new ArrayList

我有一个
MoveTrack
对象的列表,我希望按月对这些对象进行分组,并将数据计数并存储在
映射中。我正在尝试学习Lambda并用它做实验,所以我尝试用Lambda做这个任务

class MoveTrack {
private Date time;
private Double movementAmount;

//getters and setters
}

// in my main method
List<MoveTrack> mveTracking = new ArrayList<>();
Map<String, Double> movMap = new HashMap<>();
类移动轨迹{
私人约会时间;
私人双动金额;
//接球手和接球手
}
//在我的主要方法中
List mveTracking=new ArrayList();
Map movMap=新的HashMap();
因此,我希望能够将
moveTracking
列表分组,并将值相加到
movMap
,每个Map键=月份名称(一月、二月等)和相应的值移动量是该月的双倍总和。

允许您将列表简化为一个映射,其中键是对列表元素的某种操作,值是应用于元素操作的某种聚合函数。 在您的情况下,您可以使用以下内容:

SimpleDateFormat monthFormatter = new SimpleDateFormat("MMM");
Map<String, Double> moveMap = 
    moveTracking.stream()
                .collect(Collectors.groupingBy
                    (m -> monthFormatter.format(m.getTime()),
                     Collectors.summingDouble(MoveTrack::getMovementAmount)));
SimpleDateFormat monthFormatter=新的SimpleDateFormat(“MMM”);
地图移动地图=
moveTracking.stream()
.collect(收集器.groupingBy
(m->monthFormatter.format(m.getTime()),
Collectors.summingDouble(MoveTrack::getMovementAmount));
使用方法如下:

mveTracking.stream().collect(Collectors.groupingBy(m -> {
            final Calendar cal = Calendar.getInstance();
            cal.setTime(m.getTime());
            final int month = cal.get(Calendar.MONTH);
            return new DateFormatSymbols().getMonths()[month];
        }, Collectors.summingDouble(MoveTrack::getMovementAmount)));
MutableList<MoveTrack> moveTracking = Lists.mutable.empty();
ObjectDoubleMap<String> doubleMap =
    moveTracking.sumByDouble(MoveTrack::getMonthName, MoveTrack::getMovementAmount);
为您编码;)

导入java.text.DateFormatSymbols;
导入java.util.ArrayList;
导入java.util.Calendar;
导入java.util.Date;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.stream.collector;
公共类组列表{
公共静态void main(字符串[]args){
List mveTracking=new ArrayList();
mveTracking.add(newmoveTrack(newdate(),10.0d));
mveTracking.add(newmoveTrack(newdate(),11.0d));
Map movMap=新的HashMap();
movMap=mveTracking.stream().collect(收集器.groupingBy(m->{
最终日历cal=Calendar.getInstance();
cal.setTime(m.getTime());
最后一个整月=cal.get(日历月);
返回新的DateFormatSymbols().getMonths()[month];
},Collectors.summingDouble(MoveTrack::getMovementAmount));
System.out.println(movMap);
}
}
最后一节课{
私人最终日期时间;
私人最终双倍移动金额;
公共移动轨道(最终日期时间、最终双移动金额){
this.time=新日期(time.getTime());
this.movementAmount=movementAmount;
}
公共日期getTime(){
返回时间;
}
public Double getMovementAmount(){
退货金额;
}
}

如果您愿意使用第三方库,则具有名为
sumBy
的专门方法,可以很好地与lambdas配合使用

如果对moveTracking列表使用from Eclipse集合,则代码如下所示:

mveTracking.stream().collect(Collectors.groupingBy(m -> {
            final Calendar cal = Calendar.getInstance();
            cal.setTime(m.getTime());
            final int month = cal.get(Calendar.MONTH);
            return new DateFormatSymbols().getMonths()[month];
        }, Collectors.summingDouble(MoveTrack::getMovementAmount)));
MutableList<MoveTrack> moveTracking = Lists.mutable.empty();
ObjectDoubleMap<String> doubleMap =
    moveTracking.sumByDouble(MoveTrack::getMonthName, MoveTrack::getMovementAmount);

注意:我是Eclipse集合的提交人

好了,你试过什么了吗?我怀疑您想使用
流.collect
收集器.groupingBy
和收集器.summingDouble作为下游collector@JonSkeet是,尝试groupBy和toMap时只出现错误。特别是当我开始输入SimpleDataFormat时。所以请说明您尝试了什么,以及这些错误是什么。@JonSkeet很好,我首先需要一个新的视角来确定我是否走上了正确的道路