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和方法引用的使用 一:简介 我们用集合的目的,往往不是简单的仅仅把数据保存哪里.而是要检索(遍历)或者去计算或统计....操作集合里面的 ...
随机推荐
- python工业互联网应用实战2—从需求开始
前言:随着国家工业2025战略的推进,工业互联网发展将会提速,将迎来一个新的发展时期,越来越多的企业开始逐步的把产线自动化,去年年底投产的小米亦庄的智能工厂就是一个热议的新闻.小米/华为智能工厂只能说 ...
- [实战] Flutter 上的内存泄漏监控
一.前言 Flutter 所使用的 Dart 语言具有垃圾回收机制,有垃圾回收就避免不了会内存泄漏. 在 Android 平台上有个内存泄漏检测工具 LeakCanary, 它可以方便地在 debug ...
- webpack介绍—上
6.1 webpack概念的引入 在网页中会引用哪些常见的静态资源? JS .js. .jsx ..coffee. .ts(TypeScript 类 C# 语言) CSS .css. .less. . ...
- 再看rabbitmq的交换器和队列的关系
最近又要用到rabbitmq,业务上要求服务器只发一次消息,需要多个客户端都去单独消费.但我们知道rabbitmq的机制里,每个队列里的消息只能消费一次,所以客户端要单独消费信息,就必须得每个客户端单 ...
- Linux下安装MongoDB 4.2数据库--使用tar包方式
(一)基础环境设置 操作系统版本 :centos-7.4 MongoDB版本:MongoDB 4.2 社区版 (1)关闭防火墙 # 关闭防火墙 [root@mongodbenterprise lib ...
- android自定义控件onLayout方法
onLayout设置子控件的位置,对应一些普通的控件例如Button.TextView等控件,不存在子控件,所以可以不用复写该方法. 向线性布局.相对布局等存在子控件,可以覆写该方法去控制子控件的位置 ...
- .net core docker容器编排部署(linux)
环境准备 需要一个linux操作系统:我这里用的是ubuntu 18.04,安装步骤就不说了,网上很多教程,当然也可以私信我. 既然需要用到docker,那么就安装个docker,apt instal ...
- 浅谈bfs
广搜(bfs) 定义 广度优先算法,简称BFS.是一种图形搜索演算法,简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点,如果发现目标,终止. 与dfs的相似之处与不同 结合深搜理解 相同点:都 ...
- 113资讯网——NGINX 502 Bad Gateway——解决方案
NGINX 502 Bad Gateway错误出现的原因较多,对于后端连接PHP服务的场景下,常见的原因有php服务响应超时,php进程不足等引起的一类服务器错误. 发生原因: PHP FastCGI ...
- Javascript 中 数组遍历 forin和forof 的区别
定义一个数组 let array = [1, 2, 3, 4]; for (let a in array){ console.log("遍历a的值 "+a+"”,数组中的 ...