推导lambda表达式
匿名函数,用于接口
public class TestLambda {
public void test1() {
/* Comparator<Integer> comparator = new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
TreeSet<Integer> set =new TreeSet<Integer>(comparator);*/
TreeSet<Integer> set = new TreeSet<>((x,y)->Integer.compare(x, y));
}
}
package Dome;
/*
推导lambda表达式
*/
/**
* @author dafran
* @version 1.0
* @date 2020-05-24 17:18
*/
public class TestLambda01 {
//3.静态内部类
static class Like2 implements ILike {
@Override
public void lambda() {
System.out.println("This is Lambda2");
}
}
public static void main(String[] args) {
ILike like = new Like();
like.lambda();
like = new Like2();
like.lambda();
//4.局部内部类
class Like3 implements ILike {
@Override
public void lambda() {
System.out.println("This is Lambda3");
}
}
like = new Like3();
like.lambda();
//5.匿名内部类,没有类的名称,必须借助接口或者父类
like = new ILike() {
@Override
public void lambda() {
System.out.println("This is Lambda4");
}
};
like.lambda();
//6.用Lambda简化
like = ()->{
System.out.println("This is Lambda5");
};
like.lambda();
}
}
//1.定义一个函数式接口
interface ILike{
void lambda();
}
//2.实现类
class Like implements ILike {
@Override
public void lambda() {
System.out.println("This is Lambda");
}
}
lambda表达式简化
package Dome;
/**
* @author dafran
* @version 1.0
* @date 2020-05-24 17:47
*/
public class TestLambda02{
public static void main(String[] args) {
ILove love = null;
//1.Lambda简化
love = (int a) ->{
System.out.println("This is Love->" + a);
};
//2.参数简化
love = (a) ->{
System.out.println("This is Love->" + a);
};
//3.简化括号
love = a -> {
System.out.println("This is Love->" + a);
};
//4.简化花括号
love = a -> System.out.println("This is Love->" + a);
// 总结:
// lambda表达式只能有一行代码的情况下才能简化成为行,如果有多行, 那么就用代码块包
// 前提是接口为函数式接口
// 多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号
love.love(520);
}
}
interface ILove{
void love(int a);
}
六大语法
”->“;
- 左侧:Lambda表达式的参数列表
- 右侧:Lambda表达式中所执行的功能,Lambda体
- 依赖于函数式接口,Lambda表达式即对接口的实现
public class LearnLambda {
/*
* 语法一:无参、无返回值
* 里面的变量和匿名内部类的相同,默认为final
* 需要可以设数组
*/
public void test01() {
Runnable runnable = ()->{
System.out.println("1");
};
Runnable runnable =new Runnable() {
@Override
public void run() {
System.out.println("1");
}
};
}
}
/**************************************/
/*
* 语法二:有一个参数、无返回值
*/
public void test02() {
/* Consumer<String> com = (x)->{System.out.println(x);};
com.accept("test02");
}*/
Consumer<String> com = new Consumer();
this.change(com);
System.out.println(com);
};
public void change(Consumer com) {
com.accept("test02");
}
}
/*
*/
/*******/
public class LearnLambda {
/*
* 语法三:只有一个参数,省略括号
*
*/
public void test03(){
Consumer<String> com= x->{ System.out.println(x);};
com.accept("003");
}
}
/************************/
/*
* 语法四:两个以上的参数,有返回值,并且Lambda体中有多条语句
*
*/
public void test04(){
Comparator<Integer> com = (x,y) -> {
System.out.println("1234");
return Integer.compare(x,y);
};
}
/*****************/
public class LearnLambda {
/*
* 语法五:Lambda体只有一条语句,return和大括号可以不写
*
*/
public void test05(){
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
}
}
/**********************/
public class LearnLambda {
/*
* 语六:参数指定类型
*
*/
public void test06(){
Comparator<Integer> com = (Integer x,Integer y) -> Integer.compare(x,y);
}
}
四大内置函数
类型 | 类 | 抽象方法 |
---|---|---|
消费型接口(一个参数,无返回值) | Consumer | void accept(T t); |
供给型接口(无参数,有返回值) | Supplier | T get(); |
函数型接口(一个参数,有返回值) | Function |
R app1y(T t); |
断言型接口(有参数,返回值为boolean类型) | Predicate | boolean test(T t); |
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public class StudyLambda {
//消费型接口Consumer
//需求:传入一个参数做业务处理,不做返回值
public void happy(double money,Consumer<Double> con){
con.accept(money);
}
@Test
public void test1(){
happy(1000, (m) -> System.out.println("每次消费"+m+"元"));
}
//供给型接口Supplier
//需求:产生指定数量的整数,放到集合中,返回集合
public List<Integer> getNumList(int num, java.util.function.Supplier<Integer> sp){
List<Integer> resurlt = new ArrayList<>();
for (int i = 0; i < num; i++) {
resurlt.add(sp.get());
}
return resurlt;
}
@Test
public void test2(){
List<Integer> numList = getNumList(5,() -> (int) (Math.random() * 100));
numList.forEach(System.out::println);
}
//函数型
//需求:传入一个字符串,返回一个字符串
public String strHandler(String str, Function<String, String>fun){
return fun.apply(str);
}
@Test
public void test3(){
String result = strHandler("武林盟主",(x) -> x+"无忌老师");
System.out.println(result);
}
//断言型
//Predicate
}
/*下面的不是很懂*/
class StudyLambda03{
/*方法引用和对象引用
* 若Lambda体中的内容有方法实现,我们可以使用“方法引用”
* 可以理解为方法引用是Lambda表达式的另一种表现形式
* */
//对象::实例方法名
@Test
public void test4(){
//Consumer<String> con = (x) -> System.out.println(x);
PrintStream printStream = System.out;
//注意的是接口的抽象方法的形参表、返回值类型需要和调用的类方法形参表 返回值类型保持一致
Consumer<String> con = System.out::println;
con.accept("123456");
}
//类::静态方法名
@Test
public void test5(){
//注意的是接口的抽象方法的形参表、返回值类型需要和调用的类方法形参表 返回值类型保持一致
Comparator<Integer> com = (x,y) -> Integer.compare(x, y);
Comparator<Integer> com2 = Integer::compare;
}
//类::实例方法名
@Test
public void test6(){
//需求一:比较两个字符串是否相等;
//要求:第一参数是实例方法的调用者,第二个参数是方法的传入参数时
BiPredicate<String, String> bp = (x,y) -> x.equals(y);
BiPredicate<String, String> bp2 = String::equals;
}
//构造器引用
//此处自己新建类
@Test
public void test7(){
Supplier<Person> student = Person::new;
Person person = student.get();
Function<Integer, Person> student = Person::new;
Person apply = student.apply(25);
System.out.println(apply.getAge());
}
}
Stream
Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用StreamAPI对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用StreamAPl来并行执行操作。
简而言之,StreamAPI提供了一种高效且易于使用的处理数据的方式。
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamApi {
//需求:学员年龄大于25岁的
List<Person> studentList = Arrays.asList(
new Person("无极","18","181","35000");
new Person("无极1","18","181","35000");
new Person("无极2","18","181","35000");
new Person("无极3","18","181","35000");
new Person("无极4","18","181","35000")
)
//创建流
//四种
@Test
public void test(){
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
Person[] students = new Person[]{};
Stream<Person> stream1 = Arrays.stream(students);
Stream<String> stream = Stream.of("a","b","c");
Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);
stream4.limit(10).forEach(System.out::println);
}
//终止操作:一次性执行全部内容 --> "惰性求值"
@Test
public void test2(){
Stream<Person> studentStream = studentList.stream()
.filter((x) -> x.getSlary() -> 25000);
studentStream.forEach(System.out::println);
}
//map 映射 接收Lambda,将元素转换成其他形式或提取信息。
//接受一个函数作为参数,该函数会被应用到每个元素上并其映射成一个新的元素
@Test
public void test3(){
Stream<String> stream = Stream.of("aaa","bbb","ccc");
stream.map((x) -> x.toUpperCase())
.forEach(System.out::println);
//studentList.stream().map(Person::getName).forEach(System.out::println);
}
}
并行流和串行流
并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。Java8中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API可以声明性地通过parallel()与sequential()在并行流与顺序流之间进行切换。
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.time.Instant;
import java.util.stream.LongStream;
/**
* @author Administrator
* @Classname StreamApi2
* @Description TODO
* @Date 2020-10-04 21:24
* @Version V1.0
*/
public class StreamApi2 {
@Test
public void test(){
Instant start = Instant.now();
long res = LongStream.rangeClosed(0,1000000L).
parallel().reduce(0,Long::sum);
System.out.println(res);
Instant end = Instant.now();
System.out.println("耗费事件为:"+ Duration.between(start, end).toMillis());
}
}
ForkJoin并发框架从JDK1.7开始,Java提供ForkJoin框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果。
两个特性:递归分治、工作密取
引出Stream
import java.util.concurrent.RecursiveTask;
/**
* @author Administrator
* @Classname ForkJoinCalculate
* @Description TODO
* @Date 2020-10-04 20:43
* @Version V1.0
*/
public class ForkJoinCalculate extends RecursiveTask {
private long start;
private long end;
private static final long THRESHOLD = 10000;
public ForkJoinCalculate(long start, long end){
this.start = start;
this.end = end;
}
/**
* 运算或者任务拆分
*
*/
@Override
protected Object compute() {
long length = end - start;
if (length <= THRESHOLD) {
//当前任务数据区间小于10000
long sum = 0;
for (long i = start; i <= end; i++){
sum += i;
}
return sum;
}else {
//当前任务数据区间大于10000
long middle = (start + end) / 2;
ForkJoinCalculate left = new ForkJoinCalculate(start,middle);
ForkJoinCalculate rigth = new ForkJoinCalculate(middle+1,end);
left.fork();
rigth.fork();
return left.join() + rigth.join();
}
}
}