JAVA8之Stream API使用介绍一

前言

目前CSDN还没有系统的讲述JAVA8Stream内幕的,所以本次开始用最初始总结Stream,以及后面stream源码设计,希望感兴趣的博友一直跟上我的更新速度。
java8可谓java语言历史上变化最大的一个版本,其承诺要调整Java编程向着函数式风格迈进, 这有助于编写更为简洁、表达力更好,并且在很多情况下能够利用并行硬件的代码。本次分享将会深入介绍Java8特性,大家会了解到如何通过Lambda表达式使用一行代码编写Java函数,如何通过这种功能使用新的StreamAPI进行编程,如何将冗长的集合处理代码压缩为简单且可读性更好的流程序。当然,Java8开始,以及之后的Java9-10-11-12版本都 会不断的增强函数式API,之后可能编程越来越简化我们的代码编程,更加的方便,更加的快捷。Lambda表达式将Java面型对象的编程语言转换成了函数式的编程语言

1、与Java传统编程的区别

Java是基本上我们不声明它的类型(方法参数),它是不能通过编译的,在Java8之前
可能并为没有方法参数作为函数,返回值也是函数。之后那,这一现象将会改变,lambda表达式是对象,
他们必须依附于一类特别的对象类型-----函数式接口(必须只有一个抽象方法,前提条件)

2、Lambda表达式的样式

(String a,String b,String c)->{
     }
     ||
    (a,b,c)->{
         }
    左边是参数,中间是箭头,右边是代码块,
    而且lambda表达式不能单独存在,必须依附于函数式接口
    当只有一个参数的时候,参数的括号就可以省略,如下
    (a)->{}
    ||
    a->{};
    当然如果说方法体只有一行代码,大括号也可以省略,
    方法体返回值或者没有,lambda会识别并处理返回或者不返回,例如:
    (a)->{return 1;};
    ||
    (a)-> 1;
   
    以上的例子都是表达式(Expression)风格;

那么讨论了变天的,lambda表达式究竟是什么那?来不及解释了,上代码:

 public static void main(String[] args) {
        Runnable a=()->{};
        System.out.println(a);
    }

当然这里输出了com.ljk.java8.interfaces.Test$$Lambda$1/1078694789@3d075dc0,这个以目标类为后续的类路径,显然lambda表达式就是一个类,当然只能有一个抽象方法。

3、lambda表达式的作用

1、提升抽象层次
2、API重用性更好
3、更加灵活    

4、方法引用(mehtod reference)

某些情况下可以使用,必须方法是具体化,真实存在的,才可以使用,大多数还是使用Lambda。 方法引用实际上是个Lambda表达式的一种语法糖,语法糖也就是没有提供新的功能,只是对复杂的操作进行简化,可视度更好, 本身并没有对功能进行增强。 我们可以将方法引用看做是一个’函数指针’,function pointer;

//打印数据到控制台
 List<String> list = Arrays.asList("123", "456", "789");
 //Lambda方式
 list.forEach(t-> System.out.println(t));
//方法引用方式    
list.forEach(System.out::println);

那么方法引用有几种样式那?
方法引用分为四类:

4.1、类名::静态方法名

students.sort(Student::compareStudentByScore);
 students.forEach(student -> System.out.println(student.getScore()));

4.2、引用名(对象名)::普通方法名

StudentComparator studentComparator = new StudentComparator();
students.sort(student::compareStudentByScore);
students.forEach(student -> System.out.println(student.getName()));

4.3、类名::普通方法名

students.sort(Student::compareByName);
students.forEach(student -> System.out.println(student.getName()));

4.4、构造方法引用(类名::new) Supplier接口

  Supplier supplier=String::new;

5、@functionInterface说明(API文档解读)

一种信息注释类型,用于指示接口*类型声明是由Java语言规范定义的函数接口。
从概念上讲,函数接口只有一个抽象*方法,如果在接口中有来自object(所有类的父类)超
类的方法进行了覆盖,将不计入抽象方法数+1;
注意,函数接口的实例可以用*lambda表达式、方法引用或构造函数引用创建。
但是,编译器会将满足函数接口*定义的任何接口视为函数接口而不管接口声明中
是否存在@functionalinterface注释。

总结:1、如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口
     2、如果我们某个函数上声明了FunctionalInterface注解,那么编译器就会按照函数式接口的定义来要求该接口
     3、如果某个接口只有一个抽象方法,但是我们并没有给该接口声明FunctionalInterface注解,那么编译器依旧会将该接口看做是函数式接口

6、接口中新增的默认方法和静态方法

 确保了新特性的加入同时又是的java的向后版本的兼容
 类名.supper.默认方法名进行调动(如果一个类继承的多个类都有一个相同的默认方法)
 总结:1、类优先于接口。类重新方法更加的具体,所以优先级高于接口的默认方法
      2、子类胜于父类。

7、外部迭代和内部迭代的区别

外部迭代相当于一个命题作文一样,从构思到实现题目的制作,内容每一行的编写,以至于到最后作文的完成,都是我们自己完成的,外部编程还有一个问题,就是并发,加锁等等都是我们自己需要管理。
内部迭代相当于完形填空,文章架子写好了,选项还得自己选,而且你拆入的单词只是在里面的一小部分。
刚才的并发、加锁都会给我们解决(stream通过forkjoin线程池完成的)。
外部迭代的话使用集合存储数据,集合的设计关注的是数据与数据存储本身
内部迭代使用的stream关注的是数据所执行的计算。
AS IF:
流与迭代器类似的一点是:流是无法重复使用或者消费的;
Stream stream = Stream.iterate(1, item -> item + 2).limit(6);
System.out.println(stream);
Stream stream2 = stream.filter(item -> item > 2);
System.out.println(stream2);
Stream stream3 = stream2.distinct();
System.out.println(stream3);

下一节将介绍streamAPI的简单使用---->JAVA8之Stream API简介二

喜欢博客的博友可以点下关注,关注不迷路…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值