Java8之Stream 集合聚合操作集锦(含日常练习Demo)
Stream 是用函数式编程方式在集合类上进行复杂操作的工具,其集成了Java 8中的众多新特性之一的聚合操作,开发者可以更容易地使用Lambda表达式,并且更方便地实现对集合的查找、遍历、过滤以及常见计算等。
直接上代码:
基础实体类:

练习代码:
public static void main(String[] args) {
Student stuA = new Student(1, "A", "M", 184);
Student stuB = new Student(2, "B", "G", 163);
Student stuC = new Student(3, "C", "M", 175);
Student stuD = new Student(4, "D", "G", 158);
Student stuE = new Student(5, "A", "M", 158);
List<Student> list = new ArrayList<>();
list.add(stuA);
list.add(stuB);
list.add(stuC);
list.add(stuD);
list.add(stuE);
// stream-forEach循环
System.out.println("***********stream-forEach***********");
list.stream().forEach(stu -> System.out.println("stream-forEach: " + stu.getName()));
// stream-filter过滤即执行逻辑
System.out.println("***********stream-filter count***********");
long count = list.stream().filter(stu -> stu.height > 180).count();
list.stream().filter(stu -> stu.height > 180)
.forEach(stu -> System.out.println("stream-filter: " + stu));
// Stream-toMap 为了避免key冲突情况,(key1, key2) -> key1 表示冲突时取前者
System.out.println("***********Stream-toMap 字段:对象***********");
Map<String, Student> maps = list.stream()
.collect(Collectors.toMap(Student::getName, Function.identity(), (key1, key2) -> key1));
System.out.println("key-对象" + maps);
Map<String, Object> newMaps = list.stream()
.collect(Collectors.toMap(Student::getName, Student::getHeight, (key1, key2) -> key1));
System.out.println("key-字段" + newMaps);
// Stream-distinct 去重
System.out.println("***********Stream-distinct去重 必须重写equals和hashcode方法***********");
list.stream()
.distinct()
.forEach(b -> System.out.println("Stream-distinct去重 " + b.getName()+ "," + b.getHeight()));
list.stream()
.filter(StreamUtil.distinctByKey(b -> b.getSex()))
.forEach(b -> System.out.println("Stream-distinct指定字段去重 " + b.getName()+ "," + b.getSex()));
// 过滤后得到新集合
System.out.println("***********Stream操作后获取聚合集合***********");
List<Student> newList = list.stream().filter(stu -> stu.height > 165)
.collect(Collectors.toList());
System.out.println("新集合: " + newList);
// stream-聚合操作 最大值,最小值
System.out.println("**************stream-聚合操作 最大值,最小值************");
System.out.println("sum: " + list.stream().mapToDouble(Student::getHeight).sum());
System.out.println("max: " + list.stream().mapToDouble(Student::getHeight).max().getAsDouble());
System.out.println("min: " + list.stream().mapToDouble(Student::getHeight).min().getAsDouble());
System.out.println("avg: " + list.stream().mapToDouble(Student::getHeight).average().getAsDouble());
// Stream排序
System.out.println("**************stream-聚合操作 排序************");
List<Student> collect = list.stream().filter(stu -> stu.getHeight() > 165)
.sorted((e1,e2) -> Float.compare(e1.getHeight(), e2.getHeight()))
.collect(Collectors.toList());
System.out.println("stream 排序" + collect);
}
指定字段去重:
public class StreamUtil {
/**
* 指定字段去重
* @param keyExtractor
* @return
*/
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
日常练习Demo:
package com.mine.stream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
*
* @author 柯贤铭
* @date 2019年3月22日
* @email 806857264@qq.com
*/
public class TestForStream {
public static void main(String[] args) {
List<Transaction> transactions = null;
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
transactions = Arrays.asList(
new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000),
new Transaction(raoul, 2011, 400),
new Transaction(mario, 2012, 400),
new Transaction(mario, 2012, 710),
new Transaction(alan , 2012, 950));
// ①找出2011年发生的所有交易, 并按交易额排序(从低到高)
// 方式一:
Long begin = System.currentTimeMillis();
List<Transaction> newTr = transactions.stream().filter(tran -> tran.getYear() == 2011)
.collect(Collectors.toList());
newTr.sort(Comparator.comparing(t -> t.getValue()));
Long end = System.currentTimeMillis();
System.out.println("耗时: " + (end - begin) + " " + newTr);
// 方式二: 差距是35倍左右!
Long begin2 = System.currentTimeMillis();
List<Transaction> collect = transactions.stream().filter(tran -> tran.getYear() == 2011)
.sorted((e1,e2) -> Integer.compare(e1.getValue(), e2.getValue()))
.collect(Collectors.toList());
Long end2 = System.currentTimeMillis();
System.out.println("耗时: " + (end2 - begin2) + " " + collect);
// ②交易员都在哪些不同的城市工作过?
// 方式一:
transactions.stream()
.filter(StreamUtil.distinctByKey(tran -> tran.getTrader().getCity()))
.collect(Collectors.toList())
.forEach(t -> System.out.println(t.getTrader().getCity()));
// 方式二:
List<String> collCityTwo = transactions.stream()
.map(e -> e.getTrader().getCity())
.distinct()
.collect(Collectors.toList());
System.out.println("城市为: " + collCityTwo);
//③查找所有来自剑桥的交易员,并按姓名排序
List<Trader> collPerson = transactions.stream().filter(tran -> tran.getTrader().getCity().equals("Cambridge"))
.map(Transaction::getTrader)
.sorted((e1,e2) -> e1.getName().compareTo(e2.getName()))
.collect(Collectors.toList());
System.out.println(collPerson);
// ⑤有没有交易员是在米兰工作的?
long count = transactions.stream().filter(tran -> tran.getTrader().getCity().equals("Milan")).count();
System.out.println("是否有人在米兰工作: " + (count > 0));
// ⑥打印生活在剑桥的交易员的所有交易额总和
int sum = transactions.stream()
.filter(e -> e.getTrader().getCity().equals("Cambridge"))
.mapToInt(Transaction::getValue)
.sum();
System.out.println("总额为: " + sum);
// ⑦所有交易中,最高的交易额是多少
int max = transactions.stream()
.mapToInt(Transaction::getValue)
.max()
.getAsInt();
System.out.println("最大值是: " + max);
// ⑧找到交易额最小的交易
Transaction transaction = transactions.stream()
.min((e1,e2) -> Integer.compare(e1.getValue(), e2.getValue()))
.get();
System.out.println("最小值交易是: " + transaction);
}
}
class Trader {
private String name;
private String city;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Trader [name=" + name + ", city=" + city + "]";
}
public Trader(String name, String city) {
super();
this.name = name;
this.city = city;
}
}
class Transaction {
private Trader trader;
private int year;
private int value;
public Trader getTrader() {
return trader;
}
public void setTrader(Trader trader) {
this.trader = trader;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public String toString() {
return "Transaction [trader=" + trader + ", year=" + year + ", value=" + value + "]";
}
public Transaction(Trader trader, int year, int value) {
super();
this.trader = trader;
this.year = year;
this.value = value;
}
}
Java8之Stream 集合聚合操作集锦(含日常练习Demo)的更多相关文章
- java8在Stream的forEach操作时获取index
import java.util.Objects; import java.util.function.BiConsumer; /** * * @author yangzhilong * @dat ...
- Java8 如何进行stream reduce,collection操作
Java8 如何进行stream reduce,collection操作 2014-07-16 16:42 佚名 oschina 字号:T | T 在java8 JDK包含许多聚合操作(如平均值,总和 ...
- JDK1.8聚合操作
在java8 JDK包含许多聚合操作(如平均值,总和,最小,最大,和计数),返回一个计算流stream的聚合结果.这些聚合操作被称为聚合操作.JDK除返回单个值的聚合操作外,还有很多聚合操作返回一个c ...
- JAVA8 Stream集合操作:中间方法和完结方法
StreamLambda为java8带了闭包,这一特性在集合操作中尤为重要:java8中支持对集合对象的stream进行函数式操作,此外,stream api也被集成进了collection api, ...
- <JAVA8新增内容>关于集合的操作(Collection/Iterator/Stream)
因为下文频繁使用lambda表达式,关于Java中的lambda表达式内容请见: http://www.cnblogs.com/guguli/p/4394676.html 一.使用增强的Iterato ...
- java集合框架之聚合操作stream
参考http://how2j.cn/k/collection/collection-aggregate/702.html#nowhere 聚合操作 JDK8之后,引入了对集合的聚合操作,可以非常容易的 ...
- Java8中聚合操作collect、reduce方法详解
Stream的基本概念 Stream和集合的区别: Stream不会自己存储元素.元素储存在底层集合或者根据需要产生.Stream操作符不会改变源对象.相反,它会返回一个持有结果的新的Stream.3 ...
- Java8 Streams 让集合操作飞起来
前言 接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Stream 重点说明 ,并做了点补充. 基本说明 Stream 是基于 java8 的 lam ...
- 大数据项目2(Java8聚合操作)
前言:为很好的理解这些方法,你需要熟悉java8特性Lambda和方法引用的使用 一:简介 我们用集合的目的,往往不是简单的仅仅把数据保存哪里.而是要检索(遍历)或者去计算或统计....操作集合里面的 ...
随机推荐
- 腾讯云Redis混合存储版重磅推出,万字长文助你破解缓存难题!
导语 | 缓存+存储的系统架构是目前常见的系统架构,缓存层负责加速访问,存储层负责存储数据.这样的架构需要业务层或者是中间件去实现缓存和存储的双写.冷热数据的交换,同时还面临着缓存失效.缓存刷脏.数据 ...
- vue父路由高亮不显示
vue父路由高亮不显示 首页和考试中心作为父路由,点击时发现不高亮,是因为路由配置有问题 因为首页和考试中心已经重定向到homepage和tpersonal-data这两个路由,当点击首页和考试中心的 ...
- 一文读懂:GBDT梯度提升
先缕一缕几个关系: GBDT是gradient-boost decision tree GBDT的核心就是gradient boost,我们搞清楚什么是gradient boost就可以了 GBDT是 ...
- 安装mysql报错:遇到缺少vcruntime140_1.dll文件
把vcruntime140_1.dll文件放到System32 ,和System64就行 文件地址为:C:\Windows\System32 直接百度下载放进去就行
- [ C++ ] 勿在浮沙筑高台 —— 拾遗
explicit 主要用于处理一个参数的构造函数,使其不用于隐式类型转换(防止二义性) operator->() C++设计 ->可以一直保留下去 仿函数 仿函数会隐式继承他们中的一个(详 ...
- kubernetes资源均衡器Descheduler
背景 Kubernetes中的调度是将待处理的pod绑定到节点的过程,由Kubernetes的一个名为kube-scheduler的组件执行.调度程序的决定,无论是否可以或不能调度容器,都由其可配置策 ...
- 2020/6/10 JavaScript高级程序设计 BOM
BOM(浏览器对象模型):提供用于访问浏览器的对象. 8.1 window对象 window是BOM的核心对象,表示浏览器的一个实例. JavaScript访问浏览器窗口的接口 ECMAScript规 ...
- js语法基础入门(4)
4.运算符 4.1.什么是运算符? 运算符就是用来表示具体运算规则的符号,例如数学计算中的加减乘除就是具体的运算规则,我们分别用"+ - * /"等符号来表示 4.2.运算符的分类 ...
- Nginx 反向代理可以缓存 HTTP POST 请求页面吗?
摘要: Nginx 反向代理可以缓存 HTTP POST 请求页面吗? 2017-09-05 景峯 Netkiller 本文节选自<Netkiller Web 手札> 作者:netkil ...
- JavaScript基础有关构造函数、new关键字和this关键字(009)
1. 总是记得用new关键字来执行构造函数.前面提到,可以用构造函数创建JavaScript的对象,这个构造函数在使用的时候需要使用new关键字,但如果忘记写入new关键字,会怎么样?事实上这个函数还 ...