import com.entity.Person;
import org.junit.Test;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* @program: Demohander
* @description:JDK8新特性
* @author: GuoTong
* @create: 2020-11-18 10:14
**/
@SuppressWarnings("all")//正压一切警告
public class JDKStreamTest {

/*在Jdk1.8中引入了stream流的概念,
这个“流”并不同于IO中的输入和输出流,
它是Jdk中的一个类,
具体位置在:java.util.stream.Stream*/

/*关于它的操作主要分为三种:获取流、中间操作、最终操作*/

/*所谓获取流,就是将其他对象(非Stream对象)转为Stream对象。
只有两类对象可能转化为Stream对象,分别是:
数组(这个数组中的元素必须是引用类型)
集合*/

@Test
public void TestCreateStream() {
//数组获取流
Integer[] iArr = {12, 14, 15, 15, 17, 19, 22};
Stream<Integer> streamByArrInt = Stream.of(iArr);
// 数组
String[] str = "I Love You But I miss You so I miss you".split(" ");
Stream<String> streamByArrStr = Arrays.stream(str);
//集合获取流
List<String> list = Arrays.asList(str);
Stream<String> streamList = list.stream();

}

/*Stream流常用的中间操作:filter 过滤某些规则下的东西
* Stream流常用的终止操作:collect(Collectors.toList())---返回一个集合
* flatMap 可用Stream替换值,然后将多个Stream连接成一个Stream,会将之前生成Stream流的每一个元素更换为一个新的Stream对象。*/
@Test
public void TestStream01() {
//filter :
// filter方法用于通过设置的条件过滤出元素,下面的例子是过滤出长度大于3的字符串
String[] s = "I Love You But I miss You so I miss you".split(" ");
List<String> list = Arrays.asList(s);
// List流转:赛选大于3个字段的,返回一个集合
/*list.stream().filter(str -> str.length() > 3):只是流操作了,原数据并未改变*/
/*list.stream().filter(str -> str.length() > 3).collect(Collectors.toList());返回的新集合就改变了*/
List<String> collect = list.stream().filter(str -> str.length() > 3).collect(Collectors.toList());
collect.forEach(System.out::println);//还是经过流处理的集合

//map
//map元素用于映射每隔元素到对应的结果,下面的例子用map输出元素对应的平方数
Stream.of(1, 2, 3, 4, 5).map(i -> i * i).forEach(System.out::println);
System.out.println("============");
//flatMap 可用Stream替换值,然后将多个Stream连接成一个Stream,会将之前生成Stream流的每一个元素更换为一个新的Stream对象。
Stream<Integer> stream2 = Stream.of(1, 2).distinct()
.flatMap(numbers -> Stream.of(5, 6, 6, 7, 8));
//会将1,2都会替换为5,6,7,8,5,6,7,8
Object[] objects = stream2.toArray();
for (Object object : objects) {
System.out.println(object);
}
}

/*map、sorted测试*/
@Test
public void TestStream02() {
String[] str = {"1", "-12", "10", "23", "4", "7", "3"};
//map
//map元素内部遍历集合,可以对集合元素一系列操作。
List<String> list = Arrays.asList(str);
/*将集合元素转为大写(每个元素映射到大写)->降序排序->迭代输出*/
/*原始字符串的转大写,比较大小降序*/
Stream.of("a", "c", "f", "b", "w", "h", "z").map(String::toUpperCase).sorted((a, b) -> a.compareTo(b)).forEach(System.out::println);
System.out.println("====================================");
/*new Function<String, Integer>():标识类型转换:第一个范式需要转换为第二个范式的类型*/
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s);
}
}).sorted((x, y) -> y - x).forEach(x -> System.out.print(x + ","));/*sorted((x,y)-> y-x):内部是compareTo方法实现,采用lambda表达式*/
/*x-> System.out.print(x+",") 对比 System.out::println ,前者可以自定义输出内容,lambda表达式,后者只能原样输出*/
System.out.println("=================================");
list.stream().map(x -> x + "1").forEach(x -> System.out.print(x + ","));

}

/*map、sorted等较完整的链式编程*/
@Test
public void TestStream03() {
String[] str = {"17", "-12", "10", "23", "24", "17", "23", "15", "52", "12", "24", "14"};
List<String> list = Arrays.asList(str);
System.out.println("================集中多路链式编程=================");
/*集中多路链式编程*/
List<Integer> collect = list.stream().map(new Function<String, Integer>() {//类型转化为int
@Override
public Integer apply(String s) {
return Integer.parseInt(s);
}
}).limit(5) //限制,只取前几个元素
.skip(1) //跳过,表示跳过前几个元素
.distinct() //去重
.sorted() //自然排序
.sorted(Integer::compareTo)//自定义排序,默认降序
.collect(Collectors.toList());//返回出去
collect.forEach(System.out::println);//打印
}

/*终止操作*/
@Test
public void TestStream04() {
//reduce:一般用于求和,第一个参数一般是结果的初始值,第二个参数操作
//静态流:Stream.of(1,2,3)
Integer reduce = Stream.of(1, 2, 3, 4, 3, 2, 5, 1, 4, 2, 5).distinct().reduce(0, (x1, x2) -> x1 + x2);
System.out.println("不重复的和:" + reduce);
//第二个:collect(Collectors.toList());将流转化为XXX(list,set,hashset。。。。)
//stream.collect(Collectors.toCollection(HashSet::new));
String[] str = {"17", "-12", "10", "23", "24", "17", "23", "15", "52", "12", "24", "14"};
List<String> list = Arrays.asList(str);
HashSet<String> collect = list.stream().distinct().collect(Collectors.toCollection(HashSet::new));
Iterator<String> iterator = collect.iterator();//使用集合的迭代器迭代
while (iterator.hasNext()) {
String next = iterator.next();//迭代每一个元素
System.out.println(next);
}
//count方法是用来统计流中元素的个数
long count = Stream.of(1, 2, 3, 4, 3, 2, 5, 1, 4, 2, 5).distinct().count();
System.out.println("不重复的个数:" + count);
}

/*Stream 流判空过滤*/
@Test
public void TestStream05() {
ArrayList<Person> arrayList = new ArrayList<>();
arrayList.add(new Person());
arrayList.add(null);
arrayList.add(new Person("小郭", 23));
arrayList.add(new Person("小李", 21));
arrayList.add(new Person("三少", 18));

/*过滤找出null*/
arrayList.stream().filter(Objects::isNull).forEach(person -> {
System.out.println("是空的");
});
System.out.println("=============================");
/*过滤找出不是null的,但是包含空参构造对象*/
arrayList.stream().filter(Objects::nonNull).forEach(person -> {
System.out.println(person.getAge());
System.out.println(person.getName());
});
/*当arrayList为null的时候不会报空指针错误,并且还打了日志。*/
System.out.println("=============================");
arrayList = null;
Optional.ofNullable(arrayList).orElseGet(() -> {
System.out.println("personList 是空的");
return new ArrayList<>();
}).stream().filter(Objects::nonNull).forEach(person -> {
System.out.println(person.getAge());
System.out.println(person.getName());
});
}

/*Stream的匹配操作:anymatch(是否涵盖)||allMatch(全部的原始是否都涵盖)*/
@Test
public void TestStream06() {
//数据封装
ArrayList<Person> arrayList = new ArrayList<>(); arrayList.add(
new Person()); arrayList.add(
null); arrayList.add(
new Person("小郭", 23)); arrayList.add(
new Person("小李", 21)); arrayList.add(
new Person("三少", 18));
//测试涵盖
boolean anyMatch = Optional.ofNullable(arrayList).orElseGet(() -> { System.
out.println("personList 是空的");
return new ArrayList<>(); }).stream(). filter(Objects::

nonNull). filter(s -> s.getName() !=
null). anyMatch((person) -> person.getName().startsWith(
"小")); String name = anyMatch ?
"涵盖--->名字以“小”字母开头的" : "不涵盖"; System.
out.println(name); System.
out.println("=====================================");
//测试是否都满足
boolean allMatch = Optional.ofNullable(arrayList).orElseGet(() -> { System.
out.println("personList 是空的");
return new ArrayList<>(); }).stream(). filter(Objects::

nonNull). filter(s -> s.getName() !=
null). allMatch(person -> person.getName().startsWith(
"小")); String allName = allMatch ?
"全都--->名字以“小”字母开头的" : "不全"; System.
out.println(allName); System.
out.println("=====================================");
/*noneMatch((s) -> s.startsWith("d"));集合中是否没有元素匹配以'd'开头*/
}

/*并行 parallelStream 流*/
@Test
public void TestStreamToDouble() {
/*回去并行流的两种方式*/
// 直接获取并行的流
ArrayList<Integer> list = new ArrayList<>(); Stream<Integer> stream01 = list.parallelStream();

// 将串行流转成并行流
ArrayList<Integer> list2 = new ArrayList<>(); Stream<Integer> stream02 = list2.stream().parallel();

/*大量数据时,并行流会比串行流更快:底层是Fork/Join框架;少量数据时,由于使用框架会损耗资源,所以建议用串行流*/
/*并行流和串行流比较*/
//顺序输出 123456789
List<Integer> numbers = Arrays.asList( 5, 6, 7, 8, 9,1, 2, 3, 4); numbers.stream().sorted().forEach(System.
out::print); System.

out.println();//换行

//并行乱序输出 比如 658974132 此输出不固定
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 3, 7, 2, 5);
//虽然写了排序,但是输出是未排序的;当然串行流不会,写了排序就会排序
nums.parallelStream().distinct().sorted((x, y) -> x - y).forEach(x->System.out.println(x+",")); System.
out.println("===================");
// count()||collect()||reduce() 是终止操作,有终止操作才会执行中间操作sorted()
List<Integer> collect = nums.parallelStream().distinct().sorted((x, y) -> x - y).collect(Collectors.toList()); collect.forEach(System.
out::println);
/*部分情况会有线程安全问题,parallelStream里面使用的外部变量,比如集合一定要使用线程安全集合,不然就会引发多线程安全问题*/
//建议使用JUC下的东西

}}

JDK 8 Stream 流 用 法的更多相关文章

  1. java8 Stream的实现原理 (从零开始实现一个stream流)

    1.Stream 流的介绍 1.1 java8 stream介绍 java8新增了stream流的特性,能够让用户以函数式的方式.更为简单的操纵集合等数据结构,并实现了用户无感知的并行计算. 1.2  ...

  2. JDK 8 中Stream流中的去重的方法

    JDK 8 中Stream流中去重的方法 1.简单的去重,可以使用distinct()方法去重,该方法是通过比较equals和hashcode值去去重, 2.复杂的去重, 例如,在一个JavaBean ...

  3. 【JDK8】JDK 8 中Stream流中的去重的方法

    JDK 8 中Stream流中去重的方法 1.简单的去重,可以使用distinct()方法去重,该方法是通过比较equals和hashcode值去去重, 2.复杂的去重, 例如,在一个JavaBean ...

  4. Java Stream 流(JDK 8 新特性)

    什么是 Steam Java 8 中新增了 Stream(流)来简化集合类的使用,Stream 本质上是个接口,接口中定义了很多对 Stream 对象的操作. 我们知道,Java 中 List 和 S ...

  5. Java中的文件和stream流的操作代码

    1.Java中FileRead方法的运用代码及详解 package example2;import java.io.FileReader;import java.io.IOException;clas ...

  6. JavaSE复习(七)Stream流和方法引用

    Stream流 全新的Stream概念,用于解决已有集合类库既有的弊端. 传统集合的多步遍历代码 几乎所有的集合(如 Collection 接口或 Map 接口等)都支持直接或间接的遍历操作.而当我们 ...

  7. 手把手带你体验Stream流

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 上一篇讲解到了Lambda表达式的使用<最近学 ...

  8. Java 8创建Stream流的5种方法

    不知不觉间,Java已经发展到13了,来不及感慨时间过得真的太快了,来不及学习日新月异的技术更新,目前大多数公司还是使用的JDK8版本,一方面是版本的稳定,另一方面是熟悉,所以很多公司都觉得不升级也挺 ...

  9. Lambda学习总结(二)--Stream流

    一.Stream 流 1.1 概念 官方解释:可以支持顺序和并行对元素操作的元素集合. 简单来讲,Stream 就是 JDK8 提供给我们的对于元素集合统一.快速.并行操作的一种方式. 它能充分运用多 ...

  10. JDK8新特性之Stream流

    是什么是Stream流 java.util.stream.Stream Stream流和传统的IO流,它们都叫流,却是两个完全不一样的概念和东西. 流可以简单的说是处理数据集合的东西,可以申明式流式A ...

随机推荐

  1. 完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用

    转载自:https://www.bilibili.com/read/cv14326780?spm_id_from=333.999.0.0 0x00 前言简述 最近单位在做等保测评,由于本人从事安全运维 ...

  2. K8S Pod Pending 故障原因及解决方案

    文章转载自:https://mp.weixin.qq.com/s/SBpnxLfMq4Ubsvg5WH89lA

  3. 【Ceph】Ceph学习理解Ceph的三种存储接口:块设备、文件系统、对象存储

    文章转载自:https://blog.51cto.com/liangchaoxi/4048519

  4. 给 SSH 启用二次身份验证

    转载自:https://mp.weixin.qq.com/s/ssuhFbfaHxxzGmLg6Y2MjA 目前来说,二次验证(这里就不做过多解释了)是比较常用的安全手段,通过设置二次验证(谷歌或其他 ...

  5. Beats在Kibana中的集中管理

    前提条件: 1.es版本是白金版 2.es开启安全设置,kibana访问es需要密码 操作步骤汇总: 1-3步是基础环境配置 4-9步是注册beats到集中管理平台,然后启动beats,只是单纯启动b ...

  6. Pytorch及Yolov5环境配置及踩坑

    Pytorch及Yolov5环境配置及踩坑 1.何为Yolov5 yolo是计算机视觉方面用来进行目标检测的一个十分出名的开源框架,我搜不到官方的对此概括性的定义,但实际上也没什么必要,更重要的是会使 ...

  7. proxy解决跨域问题

    首先我们在本地开发,域名都是localhost,当我们需要请求后台数据时,就会出现跨域的问题 下面就是在vue.config.js配置文件里: devServer: {     proxy: {    ...

  8. MFC-创建MFC图形界面dll

    创建MFC图形界面dll 概述: 利用MFC的DLL框架,制作带有图形界面的dll,可以实现很多功能. 流程: 选择静态链接MFC DLL:以免有的库没有. 采用该框架创建的MFC,会自动生产一个MF ...

  9. 分支结构之二:switch-case

    1.格式 switch(表达式){case 常量1: 执行语句1; //break; case 常量2: 执行语句2; //break; ... default: 执行语句n; //break; } ...

  10. 数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储

    哈希表 解释 哈希表是一种根据关键码去寻找值的数据映射结构,该结构通过把关键码映射的位置去寻找存放值的地方 内存结构分析图 1.定义一个类为结点,存储的信息 2.定义链表的相关操作 3.定义一个数组存 ...