Lambda
@Test
public void test6(){
List<Employee> list = filerEmployee(employees,(e) -> e.getSalary() <= 666);
list.forEach(System.out::println);
}
Stream API
@Test
public void test7(){
employees.stream()
.filter((e) -> e.getSalary() >= 666)
.limit(2)//只取前两条数据
.forEach(System.out::println);
System.out.println("==============================================");
employees.stream()
.map(Employee::getName)//遍历出名字
.forEach(System.out::println);
}
Lambda表达式
package xc.xy2;
import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;
/**
* 星晨
* 一、Lambda 表达式的基础语法:Java8中引入了一个新的操作符“->"该操作符称为箭头操作符或Lambda操作符
* 箭头操作符将Lambda表达式拆分成两部分:
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能,既Lambda体
语法格式一:无参数,无返回值
() -> System.out.printIn("Hello Lambda!");
语法格式二:有一个参数,无返回值
(x) -> System.out.println(x);
语法格式三:若只有一个参数,小括号可以省略不写
x -> System.out.println(x);
语法格式四:有两个以上的参数,有返回值,并且Lambda体中有多条语句
Comparator<Integer> com = (x, y) -> {
System.out.println("函数式接口");
return Integer.compare(x, y);
};
语法格式五:若Lambda体中只有一条语句,return和大括号都可以省略不写
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
语法格式六:Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,既类型推断
(Integer x,Integer y) -> Integer.compare(x, y);
二、Lambda表达式需要”函数式接口“的支持
函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。可以使用注解@FunctionalInterface修饰
可以检查是否是函数接口
*/
public class TestLambda2 {
@Test
public void test1(){
//原方法
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello World!");
}
};
r.run();
System.out.println("======================================");
//Lambda方式
Runnable r1 = () -> System.out.println("Hello World!");
r1.run();
}
@Test
public void test2(){//有参无返回值
Consumer<String> con = (x) -> System.out.println(x);
con.accept("星晨学Java8");
}
@Test
public void test3(){//有多个参数
Comparator<Integer> com = (x, y) -> {
System.out.println("函数式接口");
return Integer.compare(x, y);
};
}
@Test
public void test4(){//方式五
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
}
//需求:对一个数进行运算
@Test
public void test5(){
Integer num = operation(100,(x) -> x * x);
System.out.println(num);
System.out.println( operation(100,(x) -> x + 300));
}
public Integer operation(Integer num,MyFun mf){
return mf.getValue(num);
}
}
四大内置核心函数式接口
package xy4;
import org.junit.Test;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* 星晨
* java8 内置的四大核心函数式接口
*
* Consumer<T>:消费型接口
* void accept(T t);
*
* Supplier<T>:供给型接口
* T get();
*
* Function<T,R>:函数型接口
* R apply(T t);
*
* Predicate<T>:断言型接口
* boolean test(T t);
*/
public class TestLambda3 {
//Predicate<T>:断言型接口
@Test
public void test4(){
List<String> list = Arrays.asList("Hello","xingchen","Lambda","www","ok");
List<String> stringList = filterStr(list,(s) -> s.length() > 3);
for (String str : stringList) {
System.out.println(str);
}
}
//需求:将满足条件的字符串,放入集合中
public List<String> filterStr(List<String> list, Predicate<String> pre){
List<String> strList = new ArrayList<>();
for (String str : list) {
if (pre.test(str)){
strList.add(str);
}
}
return strList;
}
//Function<T,R>函数型接口
@Test
public void test3(){
String newStr = strHandler("\t\t\t 星晨学Java8",(str) -> str.trim());
System.out.println(newStr);
String subStr = strHandler("星晨学Java8",(str) -> str.substring(0,3));
System.out.println(subStr);
}
//需求:用于处理字符串
public String strHandler(String str, Function<String,String> fun){
return fun.apply(str);
}
//Supplier<T>供给型接口
@Test
public void test2(){
List<Integer> numList = getNumList(10,() -> (int)(Math.random() * 100));
for (Integer integer : numList) {
System.out.println(integer);
}
}
//需求:产生指定个数的整数,并放入集合中
public List<Integer> getNumList(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
Integer n = sup.get();
list.add(n);
}
return list;
}
//Consumer<T>消费型接口
@Test
public void test1(){
happy(10000,(m) -> System.out.println("本次消费了"+ m +"元"));
}
public void happy(double money, Consumer<Double> con){
con.accept(money);
}
}
方法与构造器的引用
package xy4;
import org.junit.Test;
import xc.pojo.Employee;
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.*;
/**
* 星晨
* 方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用方法引用
* (可以理解为方法引用是Lambda表达式的另外一种表现形式)
*
* 主要有三种语法格式:
*
* 对象::实例方法名
*
* 类::静态方法名
*
* 类::实例方法名
*
* 注意:
* 1、Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致!
* 2、若Lambda 参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName :: method
*
* 二、构造器引用
*
* 格式:
* ClassName::new
* 注意:需要调用的构造器的参数列表要与函数式接口中的抽象方法的参数列表保持一致
*
* 三、数组引用
*
* Type::new
*/
public class TestMethodRef {
//数组引用
@Test
public void test7(){
Function<Integer,String[]> fun = (x) -> new String[x];
String[] strs = fun.apply(10);
System.out.println(strs.length);
Function<Integer,String[]> fun2 = String[]::new;
String[] strs2 = fun2.apply(20);
System.out.println(strs2.length);
}
//构造器引用
@Test
public void test5(){
Supplier<Employee> sup = () -> new Employee();
//构造器引用方式
Supplier<Employee> sup2 = Employee::new;
Employee emp = sup2.get();
System.out.println(emp);
}
@Test
public void test6(){
Function<Integer,Employee> fun = (x) -> new Employee(x);
Function<Integer,Employee> fun2 = Employee::new;
Employee emp = fun2.apply(101);
System.out.println(emp);
BiFunction<Integer,Integer,Employee> bf = Employee::new;
}
//类::实例方法名
@Test
public void test4(){//比较两个字符串
BiPredicate<String,String> bp = (x,y) -> x.equals(y);
BiPredicate<String,String> bp2 = String::equals;
}
//类::静态方法名
@Test
public void test3(){
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
Comparator<Integer> com1 = Integer::compare;
}
//对象::实例方法名
@Test
public void test1(){
PrintStream ps1 = System.out;
Consumer<String> con = (x) -> ps1.println(x);
PrintStream ps = System.out;
Consumer<String> con1 = ps::println;
Consumer<String> con2 = System.out::println;
con2.accept("abdc");
}
@Test
public void test2(){
Employee emp = new Employee();
Supplier<String> sup = () -> emp.getName();
String str = sup.get();
System.out.println(str);
Supplier<Integer> sup2 = emp::getAge;
Integer num =sup2.get();
System.out.println(num);
}
}
Stream创建
package xy4;
import org.junit.Test;
import xc.pojo.Employee;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/**
* 星晨
* 一、Stream的三个操作步骤
*
* 1.创建Stream
* 2.中间操作
* 3.终止操作(终端操作)
*/
public class TestStreamAPI1 {
//创建Stream
@Test
public void test1(){
//1.可以通过Collection系列集合提供的stream()或parallelStream()
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
//2.通过Arrays中静态方法stream()获取数组流
Employee[] emps = new Employee[10];
Stream<Employee> stream2 = Arrays.stream(emps);
//3.通过Stream类中的静态方法of()
Stream<String> stream3 = Stream.of("aa","bb","cc");
//4.创建无限流
//迭代
Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);
stream4.limit(10).forEach(System.out::println);
//生成
Stream.generate(() -> Math.random())
.limit(5)
.forEach(System.out::println);
}
}
Stream筛选
package xy4;
import org.junit.Test;
import xc.pojo.Employee;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
/**
* 星晨
* 一、Stream的三个操作步骤
*
* 1.创建Stream
* 2.中间操作
* 3.终止操作(终端操作)
*
* 中间操作
*
* 筛选与切片
* filter——接收Lambda,从流中筛选出不需要的数据
* limit——截断流,使其元素不超过给定数量
* skip(n)——跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
* distinc——筛选,通过流所生成的hashCode()和equals()去除重复元素
*/
public class TestStreamAPI2 {
List<Employee> employees = Arrays.asList(
new Employee(101,"张三",18,999.99),
new Employee(102,"李四",36,555.99),
new Employee(103,"王五",44,666.99),
new Employee(104,"赵六",55,777.99),
new Employee(105,"田七",22,888.99)
);
@Test
public void test4(){
employees.stream()
.filter((e) -> e.getSalary() > 666)
.skip(2)
.forEach(System.out::println);
}
@Test
public void test3(){
employees.stream()
.filter((e) -> {
System.out.println("短路");
return e.getSalary() >666;
})
.limit(2)
.forEach(System.out::println);
}
//内部迭代:迭代操作由Stream API完成
@Test
public void test1(){
//中间操作,不会执行任何操作
Stream<Employee> stream = employees.stream()
.filter((e) -> {
System.out.println("Stream API 的中间操作");
return e.getAge() > 35;
});
//终止操作,一次性执行全部内容,既惰性求值
stream.forEach(System.out::println);
}
//外部迭代
@Test
public void test2(){
Iterator<Employee> it = employees.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
Stream映射
package xy4;
import org.junit.Test;
import xc.pojo.Employee;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
/**
* 星晨
* 一、Stream的三个操作步骤
*
* 1.创建Stream
* 2.中间操作
* 3.终止操作(终端操作)
*
* 中间操作
*
* 筛选与切片
* filter——接收Lambda,从流中筛选出不需要的数据
* limit——截断流,使其元素不超过给定数量
* skip(n)——跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
* distinc——筛选,通过流所生成的hashCode()和equals()去除重复元素
*/
public class TestStreamAPI2 {
List<Employee> employees = Arrays.asList(
new Employee(101,"张三",18,999.99),
new Employee(102,"李四",36,555.99),
new Employee(103,"王五",44,666.99),
new Employee(104,"赵六",55,777.99),
new Employee(105,"田七",22,888.99)
);
/*
映射
map——接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
*/
@Test
public void test5(){
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
list.stream()
.map((str) -> str.toUpperCase())
.forEach(System.out::println);
System.out.println("=================================================");
employees.stream()
.map(Employee::getName)
.forEach(System.out::println);
System.out.println("=================================================");
Stream<Stream<Character>> stream = list.stream()
.map(TestStreamAPI2::filterCharacter);//{{a,a,a},{b,b,b}}
stream.forEach((sm) ->sm.forEach(System.out::println));
System.out.println("=================================================");
Stream<Character> sm = list.stream()
.flatMap(TestStreamAPI2::filterCharacter);//{a,a,a,b,b,b}
sm.forEach(System.out::println);
}
public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for (char ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
@Test
public void test4(){
employees.stream()
.filter((e) -> e.getSalary() > 666)
.skip(2)
.forEach(System.out::println);
}
@Test
public void test3(){
employees.stream()
.filter((e) -> {
System.out.println("短路");
return e.getSalary() >666;
})
.limit(2)
.forEach(System.out::println);
}
//内部迭代:迭代操作由Stream API完成
@Test
public void test1(){
//中间操作,不会执行任何操作
Stream<Employee> stream = employees.stream()
.filter((e) -> {
System.out.println("Stream API 的中间操作");
return e.getAge() > 35;
});
//终止操作,一次性执行全部内容,既惰性求值
stream.forEach(System.out::println);
}
//外部迭代
@Test
public void test2(){
Iterator<Employee> it = employees.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
Stream排序
/*
排序
sorted()——自然排序
sorted(Comparator com)——定制排序
*/
@Test
public void test7(){
List<String> list =Arrays.asList("ccc","bbb","ddd","aaa");
list.stream()
.sorted()
.forEach(System.out::println);
System.out.println("=========================");
employees.stream()
.sorted((e1,e2) -> {
if (e1.getAge()==(e2.getAge())){
return e1.getName().compareTo(e2.getName());
}else {
return -String.valueOf(e1.getAge()).compareTo(String.valueOf(e2.getAge()));
}
}).forEach(System.out::println);
}
查找与匹配
package xy5;
import org.junit.Test;
import xc.pojo.Employee;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* 星晨
*/
public class TestStreamAPI3 {
List<Employee> employees = Arrays.asList(
new Employee(101,"张三",18,999.99, Employee.Status.FREE),
new Employee(102,"李四",36,555.99, Employee.Status.BUSY),
new Employee(103,"王五",44,666.99, Employee.Status.VOCATION),
new Employee(104,"赵六",55,777.99, Employee.Status.FREE),
new Employee(105,"田七",22,888.99, Employee.Status.BUSY)
);
/*
查找与匹配
allMatch——检查是否匹配所有元素
anyMatch——检查是否至少匹配一个元素
noneMatch——检查是否没有匹配所有元素
findFirst——返回第一个元素
findAny——返回当前流中的任意元素
count——返回流中元素的总个数
max——返回流中最大值
min——返回流中最小值
*/
@Test
public void test2(){
Long count = employees.stream()
.count();
System.out.println(count);
Optional<Employee> op1 = employees.stream()
.max((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary()));
System.out.println("最大值"+op1.get());
Optional<Double> op2 = employees.stream()
.map(Employee::getSalary)
.min(Double::compare);
System.out.println("最小值"+op2.get());
}
@Test
public void test1(){
boolean b1 =employees.stream()
.allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b1);
boolean b2 =employees.stream()
.anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b2);
boolean b3 =employees.stream()
.noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
System.out.println(b3);
Optional<Employee> op = employees.stream()
.sorted((e1,e2) -> -Double.compare(e1.getSalary(), e2.getSalary()))
.findFirst();
System.out.println(op.get());
Optional<Employee> op2 = employees.stream()
.filter((e) -> e.getStatus().equals(Employee.Status.FREE))
.findAny();
System.out.println(op2.get());
}
}
归纳与搜集
/*
收集
collect——将流转换为其它形式,接收一个Collector接口实现,用于给Stream中元素做汇总的方法
*/
@Test
public void test10(){
String str = employees.stream()
.map(Employee::getName)
.collect(Collectors.joining(","));
System.out.println(str);//获得所有名字以,隔开
}
@Test
public void test9(){
DoubleSummaryStatistics dss = employees.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(dss.getSum());//总和
System.out.println(dss.getAverage());//平均值
System.out.println(dss.getMax());//最大值
}
@Test//分区 对错
public void test8(){
Map<Boolean,List<Employee>> map = employees.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() > 600));
System.out.println(map);
}
@Test//多级分组
public void test7(){
Map<Employee.Status,Map<String,List<Employee>>> map =employees.stream()
.collect(Collectors.groupingBy(Employee::getStatus,Collectors.groupingBy((e) ->{
if (((Employee) e).getAge() <= 35){
return "青年";
}else if (((Employee) e).getAge() <= 50){
return "中年人";
}else {
return "老年人";
}
})));
System.out.println(map);
}
@Test//按状态分组
public void test6(){
Map<Employee.Status,List<Employee>> map = employees.stream()
.collect(Collectors.groupingBy(Employee::getStatus));
System.out.println(map);
}
@Test
public void test5(){
//总数
Long count = employees.stream()
.collect(Collectors.counting());
System.out.println(count);
System.out.println("----------------------------------------------");
//平均值
Double avg = employees.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(avg);
//总和
Double sum = employees.stream()
.collect(Collectors.summingDouble(Employee::getSalary));
System.out.println(sum);
//最大值
Optional<Employee> max = employees.stream()
.collect(Collectors.maxBy((e1,e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
System.out.println(max.get());
//最小值
Optional<Double> min = employees.stream()
.map(Employee::getSalary)
.collect(Collectors.minBy(Double::compare));
System.out.println(min.get());
}
@Test
public void test4(){
List<String> list = employees.stream()
.map(Employee::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println("去重方法==========================");
Set<String> set = employees.stream()
.map(Employee::getName)
.collect(Collectors.toSet());
set.forEach(System.out::println);
System.out.println("======================");
HashSet<String> hs = employees.stream()
.map(Employee::getName)
.collect(Collectors.toCollection(HashSet::new));
hs.forEach(System.out::println);
}
并行流
package xy5;
import java.util.concurrent.RecursiveTask;
/**
* 星晨
*/
public class ForkJoinCalculate extends RecursiveTask<Long> {
private static final long serialVersionUID = 134656970987L;
private long start;
private long end;
private static final long THRESHOLD = 10000;
public ForkJoinCalculate(long start,long end){
this.start=start;
this.end=end;
}
protected Long compute(){
long length = end - start;
if (length <= THRESHOLD){
long sum = 0;
for (long i = start; i <= end ; i++) {
sum += i;
}
return sum;
}else {
long middle = (start+end) /2;
ForkJoinCalculate left = new ForkJoinCalculate(start,middle);
left.fork();//拆分子任务,同时压入线程队列
ForkJoinCalculate right = new ForkJoinCalculate(middle+1,end);
right.fork();
return left.join() + right.join();
}
}
}
package xy5;
import org.junit.Test;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
/**
* 星晨
*/
public class TestForkJoin {
//FrokJoin框架 更好的使用CPU
@Test
public void test1(){
Instant start = Instant.now();
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task =new ForkJoinCalculate(0,100000000L);
Long sum = pool.invoke(task);
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗费时间为:"+Duration.between(start,end).toMillis()+"毫秒");
}
//普通for
@Test
public void test2(){
Instant start = Instant.now();
long sum = 0L;
for (long i = 0; i <=10000000000L ; i++) {
sum += i;
}
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗费时间为:"+Duration.between(start,end).toMillis()+"毫秒");
}
//java8并行流
@Test
public void test3(){
Instant start = Instant.now();
LongStream.rangeClosed(0,10000000000L)
.parallel()
.reduce(0,Long::sum);
Instant end = Instant.now();
System.out.println("耗费时间为:"+Duration.between(start,end).toMillis()+"毫秒");
}
}
Optional容器
默认方法
类优先和静态方法