推导lambda表达式

匿名函数,用于接口

  1. public class TestLambda {
  2. public void test1() {
  3. /* Comparator<Integer> comparator = new Comparator<Integer>(){
  4. @Override
  5. public int compare(Integer o1, Integer o2) {
  6. return Integer.compare(o1,o2);
  7. }
  8. };
  9. TreeSet<Integer> set =new TreeSet<Integer>(comparator);*/
  10. TreeSet<Integer> set = new TreeSet<>((x,y)->Integer.compare(x, y));
  11. }
  12. }

  1. package Dome;
  2. /*
  3. 推导lambda表达式
  4. */
  5. /**
  6. * @author dafran
  7. * @version 1.0
  8. * @date 2020-05-24 17:18
  9. */
  10. public class TestLambda01 {
  11. //3.静态内部类
  12. static class Like2 implements ILike {
  13. @Override
  14. public void lambda() {
  15. System.out.println("This is Lambda2");
  16. }
  17. }
  18. public static void main(String[] args) {
  19. ILike like = new Like();
  20. like.lambda();
  21. like = new Like2();
  22. like.lambda();
  23. //4.局部内部类
  24. class Like3 implements ILike {
  25. @Override
  26. public void lambda() {
  27. System.out.println("This is Lambda3");
  28. }
  29. }
  30. like = new Like3();
  31. like.lambda();
  32. //5.匿名内部类,没有类的名称,必须借助接口或者父类
  33. like = new ILike() {
  34. @Override
  35. public void lambda() {
  36. System.out.println("This is Lambda4");
  37. }
  38. };
  39. like.lambda();
  40. //6.用Lambda简化
  41. like = ()->{
  42. System.out.println("This is Lambda5");
  43. };
  44. like.lambda();
  45. }
  46. }
  47. //1.定义一个函数式接口
  48. interface ILike{
  49. void lambda();
  50. }
  51. //2.实现类
  52. class Like implements ILike {
  53. @Override
  54. public void lambda() {
  55. System.out.println("This is Lambda");
  56. }
  57. }

lambda表达式简化

  1. package Dome;
  2. /**
  3. * @author dafran
  4. * @version 1.0
  5. * @date 2020-05-24 17:47
  6. */
  7. public class TestLambda02{
  8. public static void main(String[] args) {
  9. ILove love = null;
  10. //1.Lambda简化
  11. love = (int a) ->{
  12. System.out.println("This is Love->" + a);
  13. };
  14. //2.参数简化
  15. love = (a) ->{
  16. System.out.println("This is Love->" + a);
  17. };
  18. //3.简化括号
  19. love = a -> {
  20. System.out.println("This is Love->" + a);
  21. };
  22. //4.简化花括号
  23. love = a -> System.out.println("This is Love->" + a);
  24. // 总结:
  25. // lambda表达式只能有一行代码的情况下才能简化成为行,如果有多行, 那么就用代码块包
  26. // 前提是接口为函数式接口
  27. // 多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号
  28. love.love(520);
  29. }
  30. }
  31. interface ILove{
  32. void love(int a);
  33. }

六大语法

”->“;

  • 左侧:Lambda表达式的参数列表
  • 右侧:Lambda表达式中所执行的功能,Lambda体
  • 依赖于函数式接口,Lambda表达式即对接口的实现
  1. public class LearnLambda {
  2. /*
  3. * 语法一:无参、无返回值
  4. * 里面的变量和匿名内部类的相同,默认为final
  5. * 需要可以设数组
  6. */
  7. public void test01() {
  8. Runnable runnable = ()->{
  9. System.out.println("1");
  10. };
  11. Runnable runnable =new Runnable() {
  12. @Override
  13. public void run() {
  14. System.out.println("1");
  15. }
  16. };
  17. }
  18. }
  19. /**************************************/
  20. /*
  21. * 语法二:有一个参数、无返回值
  22. */
  23. public void test02() {
  24. /* Consumer<String> com = (x)->{System.out.println(x);};
  25. com.accept("test02");
  26. }*/
  27. Consumer<String> com = new Consumer();
  28. this.change(com);
  29. System.out.println(com);
  30. };
  31. public void change(Consumer com) {
  32. com.accept("test02");
  33. }
  34. }
  35. /*
  36. */
  37. /*******/
  38. public class LearnLambda {
  39. /*
  40. * 语法三:只有一个参数,省略括号
  41. *
  42. */
  43. public void test03(){
  44. Consumer<String> com= x->{ System.out.println(x);};
  45. com.accept("003");
  46. }
  47. }
  48. /************************/
  49. /*
  50. * 语法四:两个以上的参数,有返回值,并且Lambda体中有多条语句
  51. *
  52. */
  53. public void test04(){
  54. Comparator<Integer> com = (x,y) -> {
  55. System.out.println("1234");
  56. return Integer.compare(x,y);
  57. };
  58. }
  59. /*****************/
  60. public class LearnLambda {
  61. /*
  62. * 语法五:Lambda体只有一条语句,return和大括号可以不写
  63. *
  64. */
  65. public void test05(){
  66. Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
  67. }
  68. }
  69. /**********************/
  70. public class LearnLambda {
  71. /*
  72. * 语六:参数指定类型
  73. *
  74. */
  75. public void test06(){
  76. Comparator<Integer> com = (Integer x,Integer y) -> Integer.compare(x,y);
  77. }
  78. }

四大内置函数

类型 抽象方法
消费型接口(一个参数,无返回值) Consumer void accept(T t);
供给型接口(无参数,有返回值) Supplier T get();
函数型接口(一个参数,有返回值) Function R app1y(T t);
断言型接口(有参数,返回值为boolean类型) Predicate boolean test(T t);
  1. import org.junit.jupiter.api.Test;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.function.Consumer;
  5. import java.util.function.Function;
  6. public class StudyLambda {
  7. //消费型接口Consumer
  8. //需求:传入一个参数做业务处理,不做返回值
  9. public void happy(double money,Consumer<Double> con){
  10. con.accept(money);
  11. }
  12. @Test
  13. public void test1(){
  14. happy(1000, (m) -> System.out.println("每次消费"+m+"元"));
  15. }
  16. //供给型接口Supplier
  17. //需求:产生指定数量的整数,放到集合中,返回集合
  18. public List<Integer> getNumList(int num, java.util.function.Supplier<Integer> sp){
  19. List<Integer> resurlt = new ArrayList<>();
  20. for (int i = 0; i < num; i++) {
  21. resurlt.add(sp.get());
  22. }
  23. return resurlt;
  24. }
  25. @Test
  26. public void test2(){
  27. List<Integer> numList = getNumList(5,() -> (int) (Math.random() * 100));
  28. numList.forEach(System.out::println);
  29. }
  30. //函数型
  31. //需求:传入一个字符串,返回一个字符串
  32. public String strHandler(String str, Function<String, String>fun){
  33. return fun.apply(str);
  34. }
  35. @Test
  36. public void test3(){
  37. String result = strHandler("武林盟主",(x) -> x+"无忌老师");
  38. System.out.println(result);
  39. }
  40. //断言型
  41. //Predicate
  42. }

  1. /*下面的不是很懂*/
  2. class StudyLambda03{
  3. /*方法引用和对象引用
  4. * 若Lambda体中的内容有方法实现,我们可以使用“方法引用”
  5. * 可以理解为方法引用是Lambda表达式的另一种表现形式
  6. * */
  7. //对象::实例方法名
  8. @Test
  9. public void test4(){
  10. //Consumer<String> con = (x) -> System.out.println(x);
  11. PrintStream printStream = System.out;
  12. //注意的是接口的抽象方法的形参表、返回值类型需要和调用的类方法形参表 返回值类型保持一致
  13. Consumer<String> con = System.out::println;
  14. con.accept("123456");
  15. }
  16. //类::静态方法名
  17. @Test
  18. public void test5(){
  19. //注意的是接口的抽象方法的形参表、返回值类型需要和调用的类方法形参表 返回值类型保持一致
  20. Comparator<Integer> com = (x,y) -> Integer.compare(x, y);
  21. Comparator<Integer> com2 = Integer::compare;
  22. }
  23. //类::实例方法名
  24. @Test
  25. public void test6(){
  26. //需求一:比较两个字符串是否相等;
  27. //要求:第一参数是实例方法的调用者,第二个参数是方法的传入参数时
  28. BiPredicate<String, String> bp = (x,y) -> x.equals(y);
  29. BiPredicate<String, String> bp2 = String::equals;
  30. }
  31. //构造器引用
  32. //此处自己新建类
  33. @Test
  34. public void test7(){
  35. Supplier<Person> student = Person::new;
  36. Person person = student.get();
  37. Function<Integer, Person> student = Person::new;
  38. Person apply = student.apply(25);
  39. System.out.println(apply.getAge());
  40. }
  41. }

Stream

Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用StreamAPI对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用StreamAPl来并行执行操作。

简而言之,StreamAPI提供了一种高效且易于使用的处理数据的方式。

Lambda表达式 - 图1

  1. import org.junit.jupiter.api.Test;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.List;
  5. import java.util.stream.Stream;
  6. public class StreamApi {
  7. //需求:学员年龄大于25岁的
  8. List<Person> studentList = Arrays.asList(
  9. new Person("无极","18","181","35000");
  10. new Person("无极1","18","181","35000");
  11. new Person("无极2","18","181","35000");
  12. new Person("无极3","18","181","35000");
  13. new Person("无极4","18","181","35000")
  14. )
  15. //创建流
  16. //四种
  17. @Test
  18. public void test(){
  19. List<String> list = new ArrayList<>();
  20. Stream<String> stream = list.stream();
  21. Person[] students = new Person[]{};
  22. Stream<Person> stream1 = Arrays.stream(students);
  23. Stream<String> stream = Stream.of("a","b","c");
  24. Stream<Integer> stream4 = Stream.iterate(0,(x) -> x+2);
  25. stream4.limit(10).forEach(System.out::println);
  26. }
  27. //终止操作:一次性执行全部内容 --> "惰性求值"
  28. @Test
  29. public void test2(){
  30. Stream<Person> studentStream = studentList.stream()
  31. .filter((x) -> x.getSlary() -> 25000);
  32. studentStream.forEach(System.out::println);
  33. }
  34. //map 映射 接收Lambda,将元素转换成其他形式或提取信息。
  35. //接受一个函数作为参数,该函数会被应用到每个元素上并其映射成一个新的元素
  36. @Test
  37. public void test3(){
  38. Stream<String> stream = Stream.of("aaa","bbb","ccc");
  39. stream.map((x) -> x.toUpperCase())
  40. .forEach(System.out::println);
  41. //studentList.stream().map(Person::getName).forEach(System.out::println);
  42. }
  43. }

并行流和串行流

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。Java8中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API可以声明性地通过parallel()与sequential()在并行流与顺序流之间进行切换。

  1. import org.junit.jupiter.api.Test;
  2. import java.time.Duration;
  3. import java.time.Instant;
  4. import java.util.stream.LongStream;
  5. /**
  6. * @author Administrator
  7. * @Classname StreamApi2
  8. * @Description TODO
  9. * @Date 2020-10-04 21:24
  10. * @Version V1.0
  11. */
  12. public class StreamApi2 {
  13. @Test
  14. public void test(){
  15. Instant start = Instant.now();
  16. long res = LongStream.rangeClosed(0,1000000L).
  17. parallel().reduce(0,Long::sum);
  18. System.out.println(res);
  19. Instant end = Instant.now();
  20. System.out.println("耗费事件为:"+ Duration.between(start, end).toMillis());
  21. }
  22. }

ForkJoin并发框架从JDK1.7开始,Java提供ForkJoin框架用于并行执行任务,它的思想就是讲一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果。
两个特性:递归分治、工作密取

引出Stream

  1. import java.util.concurrent.RecursiveTask;
  2. /**
  3. * @author Administrator
  4. * @Classname ForkJoinCalculate
  5. * @Description TODO
  6. * @Date 2020-10-04 20:43
  7. * @Version V1.0
  8. */
  9. public class ForkJoinCalculate extends RecursiveTask {
  10. private long start;
  11. private long end;
  12. private static final long THRESHOLD = 10000;
  13. public ForkJoinCalculate(long start, long end){
  14. this.start = start;
  15. this.end = end;
  16. }
  17. /**
  18. * 运算或者任务拆分
  19. *
  20. */
  21. @Override
  22. protected Object compute() {
  23. long length = end - start;
  24. if (length <= THRESHOLD) {
  25. //当前任务数据区间小于10000
  26. long sum = 0;
  27. for (long i = start; i <= end; i++){
  28. sum += i;
  29. }
  30. return sum;
  31. }else {
  32. //当前任务数据区间大于10000
  33. long middle = (start + end) / 2;
  34. ForkJoinCalculate left = new ForkJoinCalculate(start,middle);
  35. ForkJoinCalculate rigth = new ForkJoinCalculate(middle+1,end);
  36. left.fork();
  37. rigth.fork();
  38. return left.join() + rigth.join();
  39. }
  40. }
  41. }