使用Lambda将列表分组并汇总到地图中

Aes*_*eir 5 java lambda java-8

我有一个MoveTrack对象列表,我想按月分组,并计算和存储数据Map<String, Double>.我正在尝试学习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<>();
Run Code Online (Sandbox Code Playgroud)

因此,我希望能够对moveTracking列表进行分组,并将值movMap与每个Map Key = Month Name(1月,2月等)相加,并且相应的值为移动量,即该月份的双精度之和.

Don*_*aab 6

如果您愿意使用第三方库,那么Eclipse Collections可以使用专门的方法调用sumBylambda.

如果您使用MutableListEclipse Collections作为moveTracking列表,则代码如下所示:

MutableList<MoveTrack> moveTracking = Lists.mutable.empty();
ObjectDoubleMap<String> doubleMap =
    moveTracking.sumByDouble(MoveTrack::getMonthName, MoveTrack::getMovementAmount);
Run Code Online (Sandbox Code Playgroud)

由您决定要实现的位置和方式getMonthName().你会注意到sumByDouble返回一个ObjectDoubleMap.这意味着您可以使用它double,movementAmount并且在求和期间不会装箱.

如果你想保持你List<MoveTrack>当前的类型,你可以使用一个ListAdapterIterate实用程序类来完成同样的事情.

List<MoveTrack> list = ...;
ObjectDoubleMap<String> doubleMap =
    Iterate.sumByDouble(list, MoveTrack::getMonthName, MoveTrack::getMovementAmount);
Run Code Online (Sandbox Code Playgroud)

注意:我是Eclipse Collections的提交者


Mur*_*nik 5

Collectors.groupingBy允许您将列表缩减为映射,其中键是对列表元素的某些操作,值是应用于元素操作的某个聚合函数.在你的情况下,你可以使用这样的东西:

SimpleDateFormat monthFormatter = new SimpleDateFormat("MMM");
Map<String, Double> moveMap = 
    moveTracking.stream()
                .collect(Collectors.groupingBy
                    (m -> monthFormatter.format(m.getTime()),
                     Collectors.summingDouble(MoveTrack::getMovementAmount)));
Run Code Online (Sandbox Code Playgroud)