背景

平时在编写前端代码时,习惯使用lodash来编写‘野生’的JavaScript;

lodash提供来一套完整的API对JS对象(Array,Object,Collection等)进行操作,这其中就包括_.groupBy 和 _.reduce,即分组和’聚合’(reduce不知道该怎么翻译合适)。

使用这些‘野生’的API能够极大的提高我本人编写JS代码的效率。而JAVA8开始支持stream和lambda表达式,这些和lodash的API有很多类似的功能。因此我在熟悉lodash的前提下尝试使用JAVA8的新特性减少冗余代码的编写。

需求

在开发后端某功能接口的过程中,需要对一个从数据库中取出的数据List进行按照ID进行聚合统计

JAVA8 reduce API

API个人理解

U reduce(U u,BiFunction accumulator,BinaryOperator combiner)

#第一个参数返回实例u,传递你要返回的U类型对象的初始化实例u

#第二个参数累加器accumulator,可以使用二元ℷ表达式(即二元lambda表达式),声明你在u上累加你的数据来源t的逻辑

#例如(u,t)->u.sum(t),此时lambda表达式的行参列表是返回实例u和遍历的集合元素t,函数体是在u上累加t

#第三个参数组合器combiner,同样是二元ℷ表达式,(u,t)->u

#lambda表达式行参列表同样是(u,t),函数体返回的类型则要和第一个参数的类型保持一致

伪代码

#1.声明一个返回结果U

#2.对List进行遍历,在U和每个T实例上应用一个累加器进行累加操作

#3.返回最终结果U

U result = identity;

for (T element : this stream)

result = accumulator.apply(result, element)

return result;

数据准备

var source =

[

{"name": "A","type": "san","typeValue": 1.0,"count": 2},

{"name": "A","type": "nas","typeValue": 13.0,"count": 1},

{"name": "B","type": "san","typeValue": 112.0,"count": 3},

{"name": "C","type": "san","typeValue": 43.0,"count": 5},

{"name": "B","type": "nas","typeValue": 77.0,"count": 7}

];

var target =

[

{

"name": "A",

"count": 3,

"totalTypeValue": 14.0,

"bazList": [

{

"type": "san",

"typeValue": 1.0

},

{

"type": "nas"

"typeValue": 13.0

}

]

},

{

"name": "B",

"count": 10,

"totalTypeValue": 189.0,

"bazList": [

{

"type": "san",

"typeValue": 112.0

}, {

"type": "nas"

"typeValue": 77.0

}

]

},

{

"name": "C",

"count": 5,

"totalTypeValue": 43.0,

"bazList": [

{

"type": "san",

"typeValue": 43.0

}

]

}

];

Code

讲了那么多废话,这个才是最直接的

代码执行大意

对 List 按照name分组统计得到 List

ReduceTest.java

import com.google.common.collect.Lists;

import Bar;

import Foo;

import java.util.List;

import java.util.stream.Collectors;

public class ReduceTest {

public static void main(String[] args) throws Exception{

List fooList = Lists.newArrayList(

new Foo("A","san",1.0,2),

new Foo("A","nas",13.0,1),

new Foo("B","san",112.0,3),

new Foo("C","san",43.0,5),

new Foo("B","nas",77.0,7)

);

List barList = Lists.newArrayList();

fooList

.stream()

.collect(Collectors.groupingBy(Foo::getName,Collectors.toList()))

.forEach((name,fooListByName)->{

Bar bar = new Bar();

bar = fooListByName

.stream()

.reduce(bar,(u,t)->u.sum(t),(u,t)->u);

System.out.println(bar.toString());

barList.add(bar);

});

}

/*

输出结果

name:A

count:3

totalTypeValue:14.0

bazList:

type:san

typeValue:1.0

type:nas

typeValue:13.0

name:B

count:10

totalTypeValue:189.0

bazList:

type:san

typeValue:112.0

type:nas

typeValue:77.0

name:C

count:5

totalTypeValue:43.0

bazList:

type:san

typeValue:43.0

*/

}

Foo.java

public class Foo{

private String name;

private String type;

private Double typeValue;

private Integer count;

public Foo(String name, String type, Double typeValue, Integer count) {

this.name = name;

this.type = type;

this.typeValue = typeValue;

this.count = count;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

public Double getTypeValue() {

return typeValue;

}

public void setTypeValue(Double typeValue) {

this.typeValue = typeValue;

}

public Integer getCount() {

return count;

}

public void setCount(Integer count) {

this.count = count;

}

}

Bar.java

import com.google.common.collect.Lists;

import java.util.List;

public class Bar{

private String name;

private Integer count;

private Double totalTypeValue;

private List bazList;

public Bar() {

this.name = null;

this.count = 0;

this.totalTypeValue = 0.0;

this.bazList = Lists.newArrayList();

}

public Bar sum(Foo foo){

if(name == null){

this.name = foo.getName();

}

this.count += foo.getCount();

this.totalTypeValue += foo.getTypeValue();

this.bazList.add(new Baz(foo.getType(),foo.getTypeValue()));

return this;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getCount() {

return count;

}

public void setCount(Integer count) {

this.count = count;

}

@Override

public String toString() {

StringBuilder sb = new StringBuilder();

sb.append("name:").append(this.name).append(System.lineSeparator());

sb.append("count:").append(this.count).append(System.lineSeparator());

sb.append("totalTypeValue:").append(this.totalTypeValue).append(System.lineSeparator());

sb.append("bazList:").append(System.lineSeparator());

this.bazList.forEach(baz->{

sb.append("\t").append("type:").append(baz.getType()).append(System.lineSeparator());

sb.append("\t").append("typeValue:").append(baz.getTypeValue()).append(System.lineSeparator());

});

return sb.toString();

}

}

Baz.java

public class Baz{

private String type;

private Double typeValue;

public Baz(String type, Double typeValue) {

this.type = type;

this.typeValue = typeValue;

}

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

public Double getTypeValue() {

return typeValue;

}

public void setTypeValue(Double typeValue) {

this.typeValue = typeValue;

}

}

PS

等下次有空补上不使用stream().reduce 实现同样操作的比较繁琐的代码,啦啦啦啦啦~~~

java reduce 分组_使用JAVA8 stream中三个参数的reduce方法对List进行分组统计相关推荐

  1. python 参数个数 同名函数_如何在python中编写不同参数的同名方法

    我在Java背景下学习Python(3.x). 我有一个python程序,我在其中创建一个personObject并将其添加到列表中.p = Person("John") list ...

  2. [五]java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用...

    reduce-归约 看下词典翻译: 好的命名是自解释的 reduce的方法取得就是其中归纳的含义 java8 流相关的操作中,我们把它理解 "累加器",之所以加引号是因为他并不仅仅 ...

  3. java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用

    java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用

  4. java 不定参数方法_java中不定长参数的使用方法

    java中不定长参数的使用方法 不定长参数方法的语法如下:返回值 方法名(参数类型...参数名称) 在参数列表中使用"..."形式定义不定长参数,其实这个不定长参数a就是一个数组, ...

  5. [重学Java基础][Java IO流][Exter.2]IO流中几种不同的读写方法的区别

    [重学Java基础][Java IO流][Exter.2]IO流中几种不同的读写方法的区别 Read 读入方法 read(): 一般是这种形式 public int read() 1.从流数据中读取的 ...

  6. tomcat中三种部署项目的方法(转)

    tomcat中三种部署项目的方法 第一种方法:在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加:  <Context path="/h ...

  7. QT中三种构建菜单栏的方法

    QT中三种构建菜单栏的方法 方法1 <C++ GUI programming with Qt 4, Second Edition>给出的一种方法:QMenum定义单个菜单,调用menuBa ...

  8. Java8 Stream 中的 reduce() 方法,执行聚合操作

    初识 Stream 中的 reduce() 方法,是在最近一次刷算法题的过程中(下面会讲到),简洁干练的写法,让我眼前一亮. 所以,我简单学习了,总结了一下写法: 正文 Java 8 API添加了一个 ...

  9. java map 值排序_使用Java8 Stream API对Map类型按照键或值进行排序

    在这篇文章中,您将学习如何使用Java对Map按照键或值进行排序.前几日有位朋友面试遇到了这个问题,看似很简单的问题,但是如果不仔细研究一下也是很容易让人懵圈的面试题.所以我决定写这样一篇文章.在Ja ...

最新文章

  1. java ftp 判断文件是否存在_FTP判断文件是否存在
  2. 资源 | 做一款炫酷的机器人需要哪些学习资源(机器人资源Awesome系列)
  3. sdi线缆标准_松下会议摄像机新品AWUN145MC所搭载的12G/SDI到底是什么?
  4. 【SSL】weblogic 12c自带默认证书库密码
  5. 555定时器回差电压计算公式_555时基电路引脚解析
  6. guava API整理
  7. 考研数学(180°为什么等于π)
  8. 计算机房地板厚度,机房防静电地板 架空地板的技术参数与地板规格种类
  9. 【node】---记忆内容
  10. corspost请求失败_利用CORS实现POST方式跨域请求数据
  11. windows server 2003 IIS6.0下session问题
  12. flashftp中文绿色破解版免费下载
  13. 苹果 Apple Id 不同区域的不同点
  14. 仿网易云音乐小程序-uniapp
  15. 8. Numpy的索引和切片 (Indexing and Slicing)
  16. 解决Win10打开可执行文件提示为了对电脑进行保护,已经阻止此应用的问题
  17. Java获取微信用户昵称时昵称里有特殊符号导致插入数据库失败(解决方案)
  18. iOS wifi开发
  19. 精益看板方法从理论到实战 (6)—— 控制在制品数量(中)
  20. 集中式版本控制器和分布式版本控制器的个人理解

热门文章

  1. Python 炫技操作:条件语句的七种写法
  2. 为提升 DCP 传输效率,阿里工程师竟然这样做!
  3. Wi-Fi 6 爆发的 2019
  4. 想学新的编程语言?考虑下 Go 吧!
  5. 稳定=死亡!废掉一个人的最好办法,就是让他瞎努力......
  6. 揭秘支撑双 11 买买买背后的硬核黑科技!
  7. 一文详解 Java 的八大基本类型!
  8. PWA 即将终结应用程序商店!
  9. 12306 辟谣用户信息被卖;比特大陆两 CEO 均卸任?苹果又被起诉 | 极客头条
  10. 身为程序员的父母,你年薪多少才能让“码二代” 不输在起跑线上