目录
• Java8 是 Java 发布以来改动最大的一个版本,其中主要添加了函数式编程、 Stream 、一些日期处理类。函数式编程 中新 加了一些概念: Lambda 表达式 、函数式接口、函数引用、默认方法、 Optional 类等; Stream 中提供了一些流式处理集合的方法,并提供了一些归约、划分等类的方法;日期中添加了 ZoneDateTime 、 DataFormater 等线程安全的方法 类 ;
• Lambda 表达式• 函数 式 接口• Stream API• 方法 引用• Date-Time API• 接口增强
• Java 8 新增了接口的默认方法。• 简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。• 我们只需在方法名前面加个 default 关键字即可实现默认方法。为什么要有这个特性?
首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需要修改全部实现该接口的类,目前的 java 8 之前的集合框架没有 foreach 方法,通常能想到的解决办法是在JDK里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法。他们的目的是为了解决接口的修改与现有的实现不兼容的问题。
由于同一个方法可以从不同接口引入, 自然而然的会有冲突的现象,规则如下: 1)一个声明在类里面的方法优先于 任何默认方法 |
静态方法的使用区别于前两者 |
接口
- package shili22;
-
- /**
- * 接口特点:
- * 行为协议--标准:抽象方法
- * 不可以直接使用(不可以直接创建对象)---如何应用呢?
- * 实现类。
- *
- *
- * 接口引用:实现类。
- * @date : 2022/11/22 9:17
- */
- @FunctionalInterface
- public interface MyInterface {
-
- // 常量和抽象方法(jdk8之前):public 修饰
- // 常量 :public static。。。。
- public static final int MAX_VALUE = 10;
-
-
- // 抽象方法:(jdk8之前) public abstract ....
- public abstract void method1();
-
-
- }
实现类1
- package shili22;
-
- /**
- *
- * @date : 2022/11/22 9:24
- */
- public class MyInterfaceImpl implements MyInterface {
- @Override
- public void method1() {
- System.out.println("oracle数据库执行操作");
- }
- }
-
实现类2
- package shili22;
-
- /**
- *
- * @date : 2022/11/22 9:25
- */
- public class MyInterfaceImpl2 implements MyInterface{
- @Override
- public void method1() {
- System.out.println("mysql功能处理2");
- }
- }
实现类3与匿名内部类
- package shili22;
-
- /**
- * 当前这个类中所实现接口中的功能处理 仅仅在整个项目中只被应用一次 此时定义一个类 不合适---》如何处理呢? 匿名类
- * @date : 2022/11/22 9:32
- */
- //
- public class MyInterfaceImpl3 implements MyInterface{
- @Override
- public void method1() {
- System.out.println("查询订单。。。。个人订单----特殊情况下使用---假设整个系统中只被执行一次");
- }
- }
-
- class Demo01{
-
-
- public static void main(String[] args) {
- // 内部类的调用
- MyInterface myInterface2 = new MyInterfaceImpl3();
- myInterface2.method1();
-
-
- // 匿名内部类----》 匿名类 使用一次情况下常用
- MyInterface myInterface3 = new MyInterface() {
- @Override
- public void method1() {
- System.out.println("查询订单。。。。个人订单----特殊情况下使用---假设整个系统中只被执行一次");
- }
- };
-
- myInterface3.method1();
-
- }
- }
测试类
- package shili22;
-
- /**
- *
- * @date : 2022/11/22 9:22
- */
- public class TestMyInterface {
-
- public static void main(String[] args) {
- // 访问接口中成员:
- // 常量:MyInterface.常量名,可直接调用静态常量
- System.out.println(MyInterface.MAX_VALUE);
-
- // 接口不可以直接进行实例化
- //接口特点: 行为协议--标准:抽象方法 不可以直接使用(不可以直接创建对象)---如何应用呢? 实现类。 接口引用:实现类。
- // MyInterface myInterface = new MyInterface();(错误示范)
-
- // 接口引用:实现类。
- MyInterface myInterface = new MyInterfaceImpl();
- myInterface.method1();
-
- }
- }
正如你所看到的,使用Lambda表达式不仅让代码变的简单、而且可读、最重要的是代码量也随之减少很多
代码对比
- package lambda;
-
- /**
- *
- * @date : 2022/11/22 10:23
- */
- @FunctionalInterface
- //当有两个时,就不是功能型接口,就不能使用Lambda
- public interface MyInterface {
-
- public void method1();
- // public void method2(int a);
- }
-
-
- class Demo01{
- public static void main(String[] args) {
- /*MyInterface myInterface = new MyInterface() {
- @Override
- public void method1() {
- System.out.println("method1........");
- }
- };*/
-
- // lambda:代码简洁 可读性强
- MyInterface myInterface = ()-> {System.out.println("执行代码");};
- myInterface.method1();
-
- }
- }
- package lambda;
-
- import java.util.Comparator;
- import java.util.TreeSet;
-
- /**
- * @date : 2022/11/22 10:29
- */
- public class Demo02Lambda {
-
- public static void main(String[] args) {
-
- // 是否是所有接口都可以应用lambda表达式呢?
-
- // 观察:一个接口中定义多个抽象方法 再使用lambda表达式 就出现编译型问题---》改为函数式接口\功能性接口
- // 使用lambda表达式前提---必须是一个函数式接口\功能性接口
- // 函数式接口\功能性接口:只有一个抽象方法的接口才称为功能性接口
- // 如何检查是否是功能性接口:可以标注 @FunctionalInterface 编译通过说明是
- //
-
- // 改变排序规则:降序
- /*TreeSet<Integer> treeSet = new TreeSet<>(new Comparator<Integer>() {
- @Override
- public int compare(Integer o1, Integer o2) {
- return o2.compareTo(o1);
- }
- });*/
- TreeSet<Integer> treeSet = new TreeSet<>((Integer o1, Integer o2)->{return o2.compareTo(o1);});
- treeSet.add(30);
- treeSet.add(10);
- treeSet.add(20);
- System.out.println(treeSet);
-
-
- }
- }
查看源码发现,在接口中只有一个抽象方法,接口上多了一个@FunctionalInterface注解,这种格式的接口被称为函数式接口,
函数式接口定义如下:
函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,但是可以有多个非抽象方法。Java中的Lambda才能顺利地进行推导。
Lambda表达式格式-([参数类型 ]参数名称) ‐> { 代码语句 }
需求 | 格式 | 说明 |
有一个形参 | 参数名称->{代码语句} | 一个形参可以省略小括号 |
没有形参 | ()->{代码语句} | 没有形参括号不能省略 |
方法体中只有一行代码 | (参数名称)->代码语句 | 方法体中只有一行代码,可以省略大括号,分号和return关键字 |
- package lambda;
-
- @FunctionalInterface
- public interface MyInterfaceLambda {
-
- // public void method1();
- // public void method2(int a);
- // public void method2(int a,String str);
- public int method2(int a,String str);
-
- }
-
- class DemoMyInterfaceLambda{
- public static void main(String[] args) {
-
- // 1)没有返回值 没有参数
- /*MyInterfaceLambda myInterfaceLambda = ()->{
- System.out.println("hello");
- System.out.println("java");
- };
- myInterfaceLambda.method1();
- System.out.println("===================");
- // {}是否可以省略问题 :{}中只有一行代码 {}可以省略
- MyInterfaceLambda myInterfaceLambda2 = ()->
- System.out.println("hello");
- ;
- myInterfaceLambda2.method1();*/
-
-
- // 2)没有返回值 有参数--1个参数
- // A:lambda--形参名字--自定义
- // B:形参 类型可以省略
- // C:()可以省略
- /*MyInterfaceLambda myInterfaceLambda3 = (int a)->{
- if(a>2){
- System.out.println("b>2");
- }else{
- System.out.println("a<2");
- }
- };*/
- /*MyInterfaceLambda myInterfaceLambda3 = (a)->{
- if(a>2){
- System.out.println("a>2");
- }else{
- System.out.println("a<2");
- }
- };*/
-
- /*MyInterfaceLambda myInterfaceLambda3 = a->{
- if(a>2){
- System.out.println("a>2");
- }else{
- System.out.println("a<2");
- }
- };
- myInterfaceLambda3.method2(1);*/
-
-
-
- // 3)没有返回值 有参数--多个参数 ()不可以省略
- /* MyInterfaceLambda myInterfaceLambda4=(int a,String str)->{
- System.out.println(a+"=========="+str);
- };*/
- /* MyInterfaceLambda myInterfaceLambda4=(a,str)->
- System.out.println(a+"=========="+str);
- ;
-
- myInterfaceLambda4.method2(66,"hello");*/
-
-
-
- // 4)有返回值抽象方法 return 关键字
- /* MyInterfaceLambda myInterfaceLambda5 = (a,str)->{
-
- String result = a+"==="+str;
- System.out.println(result);
- if (a>100){
- return a;
- }
- return 0;
- };
-
- myInterfaceLambda5.method2(200,"hello");*/
-
- // 有返回值的方法: 如果{}里面只有一行代码 {}省略同时return也要省略
- MyInterfaceLambda myInterfaceLambda5 = (a,str)-> a;
-
- int result = myInterfaceLambda5.method2(200, "hello");
- System.out.println("result:"+result);
-
- }
- }
- package lambda.demo03;
-
- import org.junit.Test;
-
- /**
- * @date : 2022/11/22 11:12
- */
- public class JunitTest {
-
- public void testMyFunction(MyFunction myFunction){
- myFunction.test("tidy");
- }
-
-
- @Test
- //加上注释变成测试类
- public void testMethod(){
-
- /* MyFunction myFunction = name->{
- System.out.println("name:"+name);
- };
-
- testMyFunction(myFunction);*/
- /* testMyFunction(name->{
- System.out.println("name:"+name);
- });*/
-
- testMyFunction(name->
- System.out.println("name:"+name)
- );
-
- }
-
-
-
- }
- package part2;
-
- @FunctionalInterface
- public interface MyFunction {
-
- // 抽象方法 a=10,b=20;计算a+b,并返回计算结果
- // 方法:
- // 3要素:1)是否有返回值 2)方法名 3)方法參數
- public int operation(int num1, int num2);
-
- }
-
- class Demo {
-
-
- public static void main(String[] args) {
- //案例一:a=10,b=20;计算a+b,并返回计算结果
- // MyFunction myFunction = (num1,num2)->{return num1+num2;};
- MyFunction myFunction = (num1, num2) -> num1 + num2;
- int result1 = myFunction.operation(10, 20);
- System.out.println("result1:" + result1);
-
- // a=10,b=20;计算a*b,并返回计算结果
-
- MyFunction myFunction2 = (num1, num2) -> num1 * num2;
- int result2 = myFunction2.operation(10, 20);
- System.out.println("result2:" + result2);
-
- System.out.println("======================");
-
- Demo demo = new Demo();
- /*MyFunction myfunction3 = (a,b)->a+b;
- int sum = demo.sum(50, 60, myfunction3);*/
- int sum = demo.sum(50, 60, (a,b)->a*b);
- System.out.println("sum:"+sum);
- }
-
-
- public int sum(int a, int b, MyFunction myfunction) {
- return myfunction.operation(a, b);
- }
-
- }
-
四个接口示例
- package part2;
-
- import java.util.function.Consumer;
- import java.util.function.Function;
- import java.util.function.Predicate;
- import java.util.function.Supplier;
-
- /**
- * @date : 2022/11/22 15:35
- */
- public class FunctionDemo02 {
-
- public static void main(String[] args) {
- // 1)消费型接口---传入参数
- Consumer consumer = t->{
- if(t.equals("hello")){
- System.out.println("OK");
- }else{
- System.out.println("NG");
- }
- };
-
- consumer.accept("hello");
-
-
- // 2)Supplier供给型接口--返回值
- System.out.println("==Supplier供给型接口--返回值:=================");
-
-
- Supplier<Integer> supplier = ()->new Integer(12);
-
- Integer num = supplier.get();
- System.out.println(num);
-
- // 3)Function<T , R>: Function接口
- System.out.println("=Function
: Function接口:=================" ); - // 判断用户名是否正确: tidy success 否则 fail
- String inputName = "tidy";
- Function<String,String> function = str->{
- if ("tidy".equals(str)){
- return "Success";
- }else{
- return "fail";
- }
- };
-
- String result = function.apply(inputName);
- System.out.println("result:"+result);
-
-
-
- // 4)Predicate<T>:断言型接口
- Predicate<String> predicate = t->{
-
- return "123456".equals(t)?true:false;
-
- };
-
- boolean flg = predicate.test("123456");
- System.out.println("flg:"+flg);
-
- }
-
-
-
-
-
-
- }
作业
1. 给一个整数集合,分别求集合中偶数和与奇数和
- package housework;
-
- import java.util.ArrayList;
- import java.util.List;
-
- public interface test221 {
-
- public int[] operation(List<Integer> list);
- }
-
- class test11221{
- public static void main(String[] args) {
- List<Integer> list = new ArrayList<>();
- list.add(1);
- list.add(2);
- list.add(3);
- list.add(4);
- test221 function = (list2)->{
- int jishuSum =0;
- int oushuSum = 0;
- for (int i = 0; i < list2.size(); i++) {
- if (list2.get(i)%2==0){
- oushuSum=oushuSum+list2.get(i);
- }else{
- jishuSum = jishuSum+list2.get(i);
- }
- }
- int[] arr = new int[2];
- arr[0]=jishuSum;
- arr[1]=oushuSum;
- return arr;
- } ;
- int[] arr2 = function.operation(list);
- System.out.println("奇数和:"+arr2[0]);
- System.out.println("偶数和:"+arr2[1]);
- }
- }
2. 给一个整数集合,将集合分成偶数集合和奇数集合
- package housework;
-
- import java.util.ArrayList;
- import java.util.List;
-
- public interface test222 {
-
- public List operation(List<Integer> list);
- }
-
- class test11222{
- public static void main(String[] args) {
- test222 function = (list2)->{
- List<Integer> ji = new ArrayList<>();
- List<Integer> ou = new ArrayList<>();
- for (int i = 0; i < list2.size(); i++) {
- if (list2.get(i)%2==0){
- ou.add(list2.get(i));
- }else{
- ji.add(list2.get(i));
- }
- }
- List<List<Integer>> sum = new ArrayList<>();
- sum.add(ou);
- sum.add(ji);
- return sum;
- } ;
- List<Integer> list = new ArrayList<>();
- list.add(1);
- list.add(2);
- list.add(3);
- list.add(4);
- function.operation(list);
- List list1 = function.operation(list);
- System.out.println("奇数和:"+ list1.get(1));
- System.out.println("偶数和:"+list1.get(0));
- }
- }
3. 集合转换:[[1, 2, 3, 4, 5], [2, 1, 9, 3, 6, 7], [3, 1, 6]] > ["1", "2", "4", "5", "2", …… "3", "1","6"]
package housework; import java.util.ArrayList; import java.util.Collections; import java.util.List; public interface test223 { public List<String> operation(List<List<Integer>> list); } class test11223{ public static void main(String[] args) { test223 function = (list2)->{ List<String> ji = new ArrayList<>(); for (int i = 0; i < list2.size(); i++) { for (int j = 0; j < (list2.get(i)).size(); j++) ji.add("“"+list2.get(i).get(j).toString()+"”"); } return ji; } ; List<List<Integer>> list = new ArrayList<>(); List<Integer> list1 = new ArrayList<>(); List<Integer> list2 = new ArrayList<>(); List<Integer> list3 = new ArrayList<>(); Collections.addAll(list1,1,2,3,4,5); Collections.addAll(list2,3,1,6); Collections.addAll(list3,2,1,9,3,6,7); list.add(list1); list.add(list2); list.add(list3); // System.out.println(list); // function.operation(list); List<String> list4 = function.operation(list); System.out.println("后:"+ list4); } }