jdk8中的StreamAPI
1.实体类
package com.zy.model; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import java.io.Serializable; @Data
@Builder
@AllArgsConstructor
public class Employee implements Serializable { private Integer id;
private String name;
private Integer age;
private double salary; }
备注,该实体类采用了JetBrains的插件,IDEA编译器需要先导入插件(链接:http://plugins.jetbrains.com/plugin/6317-lombok-plugin)
并在pom.xml中引入Jar包
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.</version>
<scope>provided</scope>
</dependency>
2.Stream 的操作步骤
/*
*
* 1. 创建 Stream
*
* 2. 中间操作
*
* 3. 终止操作
*/
2.1创建Stream
package com.zy.stream; import com.zy.model.Employee;
import org.junit.Test; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream; public class TestStreamAPI01 { // 1.创建stream流的方式
@Test
public void test1(){
// 1.1第一种方式:通过Collection系列集合提供的Stream或paralleStream
List<Object> list = new ArrayList<>();
// 串行流,按顺序
Stream<Object> streamList1 = list.stream();
// 并行流,不按顺序
Stream<Object> parallelStream = list.parallelStream(); // 1.2第二种方式:通过Arrays中的静态方法获取数组流
Employee[] employee = new Employee[];
Stream<Employee> streamArray = Arrays.stream(employee); // 1.3第三种方式:通过Stream类中的of()方法创建流
Stream<String> stringStream = Stream.of("a", "b", "c"); // 1.4创建无限流
// 1.4.1第一种方式:迭代
Stream.iterate(, (x) -> (x + ))
.limit()
.forEach(System.out::println);
System.out.println("=================");
// 1.4.2第二种方式:生成
Stream.generate(()->Math.random())
.limit()
.forEach(System.out::println);
} }
2.2Stream的中间操作
package com.zy.stream; import com.zy.model.Employee;
import org.junit.Test; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream; public class TestStreamAPI02 { // 2.中间操作
/**
*
* 筛选与切片
* filter--接收Lambda,从流中排除某些元素
* limit(n)--截断流,使其元素不超过给定数量n
* skip(n)--跳过元素,返回一个扔掉了前n个元素的流,若元素不足n个,则返回null,与limit(n)互补
* distinct--筛选,通过流所生成的hashCode(),和equals()去除重复元素
*
* map--接收Lambda表达式,将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会应用到每个元素上,并将其映射成一个新的元素.
* flatMap--接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流凑成一个流
* map与flatMap的关系类似于List中的add()与addALl()
*
* sorted--自然排序
*
*/ List<Employee> emps = Arrays.asList(
new Employee(, "李四", , 6666.66),
new Employee(, "张三", , 9999.99),
new Employee(, "王五", , 3333.33),
new Employee(, "赵六", , 7777.77),
new Employee(, "赵六", , 7777.77),
new Employee(, "赵六", , 7777.77),
new Employee(, "田七", , 5555.55)
); // 筛选元素
@Test
public void fn1(){
// 内部迭代,由StreamAPI完成
Stream<Employee> employeeStream = emps.stream()
.filter((e) -> e.getAge() > );
// 一次性执行完所有内容,即"惰性求值"
employeeStream.forEach(System.out::println);
} // 只选前几个元素
@Test
public void fn2(){
emps.stream()
.filter((e)->e.getSalary()>)
.limit()
.forEach(System.out::println);
} // 跳过前几个元素
@Test
public void fn3(){
emps.stream()
.filter((e)->e.getAge()>)
.skip()
.forEach(System.out::println); } // 去重
@Test
public void fn4(){
emps.stream()
.distinct()
.forEach(System.out::println);
} // map
@Test
public void fn5(){
emps.stream()
.map(Employee::getName)
.forEach(System.out::println);
} @Test
public void fn6(){
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
Stream<Character> characterStream = list.stream()
.flatMap(TestStreamAPI02::filterCharacter);
characterStream.forEach(System.out::println);
} public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for(Character character : str.toCharArray()){
list.add(character);
}
return list.stream();
} // 排序
@Test
public void fn7(){
List<String> list = Arrays.asList("b", "c", "a", "m", "d");
list.stream()
.sorted()
.forEach(System.out::println);
} @Test
public void fn8(){
emps.stream()
.sorted((e1,e2)->{
if (e1.getAge().equals(e2.getAge())){
return e1.getName().compareTo(e2.getName());
}else {
return -e1.getAge().compareTo(e2.getAge());
}
})
.forEach(System.out::println);
}
}
2.3Stream的终止操作
package com.zy.stream; import com.zy.model.Employee;
import org.junit.Test; import java.util.Arrays;
import java.util.List;
import java.util.Optional; public class TestStreamAPI03 { //3. 终止操作
/*
allMatch——检查是否匹配所有元素
anyMatch——检查是否至少匹配一个元素
noneMatch——检查是否没有匹配的元素
findFirst——返回第一个元素
findAny——返回当前流中的任意元素
count——返回流中元素的总个数
max——返回流中最大值
min——返回流中最小值
*/
List<Employee> emps = Arrays.asList(
new Employee(, "李四", , 6666.66),
new Employee(, "张三", , 9999.99),
new Employee(, "王五", , 3333.33),
new Employee(, "赵六", , 7777.77),
new Employee(, "赵六", , 7777.77),
new Employee(, "赵六", , 7777.77),
new Employee(, "田七", , 5555.55)
); // 终止操作集锦
@Test
public void fn1(){
boolean b = emps.stream()
.allMatch((e) -> e.getAge() > );
System.out.println("allMatch()================="+b); boolean b1 = emps.stream()
.anyMatch((e) -> e.getAge() > );
System.out.println("anyMatch()================="+b1); boolean b2 = emps.stream()
.noneMatch((e) -> e.getAge() == );
System.out.println("noMatch()================"+b2); Optional<Employee> optional = emps.stream()
.sorted((e1, e2) -> e1.getAge().compareTo(e2.getAge()))
.findFirst();
System.out.println("findFirst()================" + optional.get()); Optional<Employee> any = emps.stream()
.filter((e)->e.getAge()>)
.findAny();
System.out.println("findAny()============="+any.get()); long count = emps.stream()
.count();
System.out.println("count()========="+count); Optional<Employee> max = emps.stream()
.max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println("max()==================="+max); Optional<Employee> min = emps.stream()
.min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println("min()====================="+min); }
}
2.4reduce和collecttors
package com.zy.stream; import com.zy.model.Employee;
import org.junit.Test; import java.util.*;
import java.util.stream.Collectors; public class TestStreamAPI04 {
List<Employee> emps = Arrays.asList(
new Employee(, "李四", , 6666.66),
new Employee(, "张三", , 9999.99),
new Employee(, "王五", , 3333.33),
new Employee(, "赵六", , 7777.77),
new Employee(, "赵六", , 7777.77),
new Employee(, "赵六", , 7777.77),
new Employee(, "田七", , 5555.55)
);
//3. 终止操作 /**
*
* 规约
* reduce(T identity, BinaryOperator) / reduce(BinaryOperator)
* ——可以将流中元素反复结合起来,得到一个值。
*/
@Test
public void fn1(){
List<Integer> list = Arrays.asList(,,,,,,,,,);
Integer reduce = list.stream()
.reduce(, (a, b) -> a + b);
System.out.println(reduce);
} /**
* map-reduce模式
* 谷歌用这种模式进行搜索
*/
@Test
public void fn2(){
Optional<Double> optional = emps.stream()
.map(Employee::getSalary)
.reduce(Double::max);
System.out.println(optional);
}
/**
* collect——将流转换为其他形式。
* 接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
*/ // 用List接收
@Test
public void fn4(){
List<String> nameList = emps.stream()
.map(Employee::getName)
.collect(Collectors.toList());
System.out.println(nameList);
} // 用Set接收
@Test
public void fn5(){
Set<String> nameSet = emps.stream()
.map(Employee::getName)
.collect(Collectors.toSet());
System.out.println(nameSet);
} // 用指定容器接收,如TreeSet
@Test
public void fn6(){
TreeSet<String> nameTreeSet = emps.stream()
.map(Employee::getName)
.collect(Collectors.toCollection(TreeSet::new));
System.out.println(nameTreeSet);
} // 计数
@Test
public void fn7(){
Long count = emps.stream()
.collect(Collectors.counting());
System.out.println(count);
} // 求均值
@Test
public void fn8(){
Double d = emps.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(d);
} // 求和
@Test
public void fn9(){
DoubleSummaryStatistics sum = emps.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(sum);
} // 最大值
@Test
public void fn10(){
Optional<Employee> optional = emps.stream()
.collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
System.out.println(optional.get());
} // 最小值
@Test
public void fn11(){
Optional<Double> min = emps.stream()
.map(Employee::getSalary)
.collect(Collectors.minBy(Double::compare));
System.out.println(min.get());
} // 单列分组
@Test
public void fn12(){
Map<String, List<Employee>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getName));
System.out.println(map);
} // 多列分组
@Test
public void fn13(){
Map<String, Map<String, List<Employee>>> mapMap = emps.stream()
.collect(Collectors.groupingBy(Employee::getName, Collectors.groupingBy((e) -> {
if (e.getAge() > )
return "老年";
else if (e.getAge() > )
return "中年";
else
return "青年人";
})));
System.out.println(mapMap);
} // 分区
@Test
public void fn14(){
Map<Boolean, List<Employee>> listMap = emps.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() >= ));
System.out.println(listMap);
} }
2.5练习部分
package com.zy.stream; import com.zy.model.Employee;
import org.junit.Test; import java.util.Arrays;
import java.util.List;
import java.util.Optional; public class TestStreamAPI05 { /*
1. 给定一个数字列表,如何返回一个由每个数的平方构成的列表呢?
,给定【1,2,3,4,5】, 应该返回【1,4,9,16,25】。
*/
@Test
public void fn1(){
Integer[] arr = {,,,,};
Arrays.stream(arr)
.map((x)->x * x)
.forEach(System.out::println);
} /*
2. 怎样用 map 和 reduce 方法数一数流中有多少个Employee呢?
*/
List<Employee> emps = Arrays.asList(
new Employee(, "李四", , 6666.66),
new Employee(, "张三", , 9999.99),
new Employee(, "王五", , 3333.33),
new Employee(, "赵六", , 7777.77),
new Employee(, "赵六", , 7777.77),
new Employee(, "赵六", , 7777.77),
new Employee(, "田七", , 5555.55)
); @Test
public void fn2(){
Optional<Integer> reduce = emps.stream()
.map((e) -> )
.reduce(Integer::sum);
System.out.println(reduce.get());
}
}
3.jdk8中的并行流(多线程)与串行流(顺序流)
3.1并行流
package com.zy.stream; import org.junit.Test; import java.time.Instant;
import java.util.stream.LongStream; public class TestStreamAPI06ParallelStream { // 并行流
@Test
public void fn1(){
long start = System.currentTimeMillis();
long sum = LongStream.rangeClosed(, )
.parallel()
.sum();
long end = System.currentTimeMillis();
System.out.println(sum + "=======================" + (end - start));
} // 串行流
@Test
public void fn2(){
long start = System.currentTimeMillis();
long sum = LongStream.rangeClosed(, )
.sequential()
.sum();
long end = System.currentTimeMillis();
System.out.println(sum + "=======================" + (end - start));
}
}
jdk8中的StreamAPI的更多相关文章
- JDK8中JVM对类的初始化探讨
在<深入理解Java虚拟机>(第二版,周志明著)中,作者介绍了JVM必须初始化类(或接口)的五种情况,但是是针对JDK7而言的. 那么,在JDK8中,这几种情况有没有变化呢?(我猜测应该会 ...
- JDK8中JVM堆内存划分
一:JVM中内存 JVM中内存通常划分为两个部分,分别为堆内存与栈内存,栈内存主要用运行线程方法 存放本地暂时变量与线程中方法运行时候须要的引用对象地址. JVM全部的对象信息都 存放在堆内存中.相比 ...
- JDK7与JDK8中HashMap的实现
JDK7中的HashMap HashMap底层维护一个数组,数组中的每一项都是一个Entry transient Entry<K,V>[] table; 我们向 HashMap 中所放置的 ...
- forEach与jdk8中的lambda, Stream
增强for循环 :forEach 反编译后可以看到实际使用的仍然是Iterator+while遍历的 forEach的优点是写法简单,缺点是不能使用xxx.remove(e)或者iter.remove ...
- 谈谈JDK8中的字符串拼接
字符串拼接问题应该是每个Java程序员都熟知的事情了,几乎每个Java程序员都读过关于StringBuffer/StringBuilder来拼接字符串. 在大多数的教程中,也许你会看到用+号拼接字符串 ...
- JDK7中匿名内部类中使用局部变量要加final,JDK8中不需要,但jdk会默认加上final
今天看书的时候看到了局部内部类,书上说局部内部类可以访问局部变量,但是必须是final的.因为局部变量在方法调用之后就消失了,使用final声明的话该局部变量会存入堆中,和内部类有一样的声明周期.但是 ...
- 深入分析 JDK8 中 HashMap 的原理、实现和优化
HashMap 可以说是使用频率最高的处理键值映射的数据结构,它不保证插入顺序,允许插入 null 的键和值.本文采用 JDK8 中的源码,深入分析 HashMap 的原理.实现和优化.首发于微信公众 ...
- JDK8中接口的新特性
在JDK8环境中,接口中的方法不再是只能有抽象方法,还可以有静态方法和default方法.实现类只需要实现它的抽象方法即可,JDK8中的接口有愈发向抽象类靠拢的感觉. 关于静态方法和默认方法作如下简述 ...
- HashMap在JDK7和JDK8中的区别
在[深入浅出集合Map]中,已讲述了HashMap在jdk7中实现,在此就不再细说了 JDK7中的HashMap 基于链表+数组实现,底层维护一个Entry数组 Entry<K,V>[] ...
随机推荐
- ubuntu 指令修改时区 tzselect
修改时区 tzselect 指令只是根据提示一步步选择正确时区,但不能真正修改时区,最后输入提示的指令,然后重启,才能永久修改. aaron@ubuntu:~$ tzselect Please ide ...
- Android 从上层到底层-----hal层
CPU:RK3288 系统:Android 5.1 功能:上层 app 控制 led 亮灭 开发板:Firefly RK3288 led_hal.c path:hardware/rockchip/fi ...
- HDOJ5521(巧妙构建完全图)
Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- JDK 8 - Method Reference 分析
Java SE 8 在 Java 语言层面上新增了 lambda expression 的功能,使得 Java 具备了函数式语言的能力 - 可以将函数作为方法参数传递,即 code as data. ...
- ARP的一次请求与应答
ARP: 我们知道,网络层和网络层以上使用的是IP地址,但在实际网络的链路上传送数据帧时,数据包首先是被网卡接受到再去处理上层协议的,所以最终还是必须使用该网络的硬件地址.但IP地址和下面的网络的硬件 ...
- 获取响应数据___JSON Extractor 后置处理器
对于大部分请求返回的结果,都是json,有一个更方便使用的插件:JSON Extractor 不过得首先下载插件 https://jmeter-plugins.org/wiki/JSONPathExt ...
- Appium Hybrid混合应用测试——Native切换WebView , 切换不了WebView (没有试过,先记录在此)
Appium Hybrid混合应用测试过程中,经常需要在Native和WebView之间进行切换: 1.切换至WEBVIEW操作: for cons in driver.contexts: if co ...
- 纯css实现点击事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 项目中Map端数据处理不均匀性分析
Map任务的不均匀性 最近发现Map端数据越来越不均匀,而处理输入的数据,写到本地磁盘的数据量都差不多,我们随便拿出来两个attempt任务(当前map数量为64个),33和45,33的counter ...
- 卷积神经网络之VGG网络模型学习
VGG:VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION 牛津大学 visual geometry group(VG ...