dede免费网站模板,云服务器如何安装网站,wordpress可以做下载站吗,app地推网文章目录 接口增强默认方法静态方法 函数式接口SupplierConsumerFunctionPredicate Optional 类以前对null 的处理Optional的基本使用Optional的常用方法 方法引用方法引用的格式对象名::方法名类名::静态方法名类名::引用实例方法类名::构造器数组::构造器 接口增强
在JDK8之… 文章目录 接口增强默认方法静态方法 函数式接口SupplierConsumerFunctionPredicate Optional 类以前对null 的处理Optional的基本使用Optional的常用方法 方法引用方法引用的格式对象名::方法名类名::静态方法名类名::引用实例方法类名::构造器数组::构造器 接口增强
在JDK8之前接口的结构如下
interface 接口名{静态常量;抽象方法;
}JDK8之后对接口做了增加接口中可以有默认方法和静态方法
interface 接口名{静态常量;抽象方法;默认方法;静态方法;
}默认方法
为什么要增加默认方法
在JDK8以前接口中只能有抽象方法和静态常量会存在以下的问题
如果接口中新增抽象方法那么实现类都必须要实现这个抽象方法非常不利于接口的扩展的
interface A{void test1();// 接口中新增抽象方法所有实现类都需要重写这个方法不利于接口的扩展void test2();
}class B implements A{Overridepublic void test1() {}Overridepublic void test2() {}
}class C implements A{Overridepublic void test1() {}Overridepublic void test2() {}
}
如果接口A新增了test3()方法接口B、C都需要实现也不符合开闭原则。
默认方法的格式
接口中默认方法的语法格式是
interface 接口名{修饰符 default 返回值类型 方法名{方法体;}
}默认的方法实现类可实现可不实现当然也可以通过实例调用默认方式。
interface A{void test1();// 接口中新增抽象方法所有实现类都需要重写这个方法不利于接口的扩展void test2();/*** 接口中定义的默认方法* return*/public default String test3(){System.out.println(接口中的默认方法执行了...);return hello;}
}class B implements A{Overridepublic void test1() {}Overridepublic void test2() {}Overridepublic String test3() {System.out.println(B 实现类中重写了默认方法...);return ok ...;}
}class C implements A{Overridepublic void test1() {}Overridepublic void test2() {}
}
静态方法
静态方法作用也是为了接口的扩展
静态方法的格式
interface 接口名{修饰符 static 返回值类型 方法名{方法体;}
}静态方法是不可以被实现的调用的话只能通过接口类型来实现: 接口名.静态方法名()。 interface A{void test1();// 接口中新增抽象方法所有实现类都需要重写这个方法不利于接口的扩展void test2();/*** 接口中定义的默认方法* return*/public default String test3(){System.out.println(接口中的默认方法执行了...);return hello;}/*** 接口中的静态方法* return*/public static String test4(){System.out.println(接口中的静态方法....);return Hello;}
} 函数式接口
使用Lambda表达式的前提是需要有函数式接口而Lambda表达式使用时不关心接口名、抽象方法名只关心抽象方法的参数列表和返回值类型。因此为了让我们使用Lambda表达式更加的方法JDK中提供了大量常用的函数式接口主要是在 java.util.function 包中。
Supplier
Supplier是一个无参有返回值的接口对于的Lambda表达式需要提供一个返回数据的类型。
FunctionalInterface
public interface SupplierT {/*** Gets a result.** return a result*/T get();
}Supplier 函数式接口的使用
/*** */
public class SupplierTest {public static void main(String[] args) {fun1(()-{int arr[] {22,33,55,66,44,99,10};// 计算出数组中的最大值Arrays.sort(arr);return arr[arr.length-1];});}private static void fun1(SupplierInteger supplier){// get() 是一个无参的有返回值的 抽象方法Integer max supplier.get();System.out.println(max max);}
}Consumer
Consumer是有参无返回值得接口Supplier接口是用来生产数据的而Consumer接口是用来消费数据的使用的时候需要指定一个泛型来定义参数类型
FunctionalInterface
public interface ConsumerT {/*** Performs this operation on the given argument.** param t the input argument*/void accept(T t);
}使用将输入的数据统一转换为小写输出
public class ConsumerTest {public static void main(String[] args) {test(msg - {System.out.println(msg - 转换为小写 msg.toLowerCase());});}public static void test(ConsumerString consumer){consumer.accept(Hello World);}
}Function
Function是一个有参有返回值的接口Function接口是根据一个类型的数据得到另一个类型的数据前者称为前置条件后者称为后置条件。
FunctionalInterface
public interface FunctionT, R {/*** Applies this function to the given argument.** param t the function argument* return the function result*/R apply(T t);
}使用传递进入一个字符串返回一个数字
public class FunctionTest {public static void main(String[] args) {test(msg -{return Integer.parseInt(msg);});}public static void test(FunctionString,Integer function){Integer apply function.apply(666);System.out.println(apply apply);}
}Predicate
Predicate是一个有参且返回值为Boolean的接口
FunctionalInterface
public interface PredicateT {/*** Evaluates this predicate on the given argument.** param t the input argument* return {code true} if the input argument matches the predicate,* otherwise {code false}*/boolean test(T t);
}使用
public class PredicateTest {public static void main(String[] args) {test(msg - {return msg.length() 3;});}private static void test(PredicateString predicate){boolean b predicate.test(HelloWorld);System.out.println(b: b);}
}在Predicate中的默认方法提供了逻辑关系操作 and、or、negate、isEquals方法
package com.bobo.jdk.fun;import java.util.function.Predicate;public class PredicateDefaultTest {public static void main(String[] args) {test(msg1 - {return msg1.contains(H);},msg2 - {return msg2.contains(W);});}private static void test(PredicateString p1,PredicateString p2){// p1 包含H 同时 p2 包含Wboolean bb1 p1.and(p2).test(Hello);// p1 包含H 或者 p2 包含Wboolean bb2 p1.or(p2).test(Hello);// p1 不包含Hboolean bb3 p1.negate().test(Hello);System.out.println(bb1); // FALSESystem.out.println(bb2); // TRUESystem.out.println(bb3); // FALSE}
}
Optional 类
Java的Optional类是一个用于解决null安全问题的工具类。在Java 8中引入了这个类它提供了一种更优雅、更安全的方式来处理可能为null的值。
以前对null 的处理 Testpublic void test01(){String userName null;if(userName ! null){System.out.println(字符串的长度 userName.length());}else{System.out.println(字符串为空);}}Optional的基本使用
Optional对象的创建方式 /*** Optional对象的创建方式*/Testpublic void test02(){// 第一种方式 通过of方法 of方法是不支持null的OptionalString op1 Optional.of(zhangsan);//OptionalObject op2 Optional.of(null);// 第二种方式通过 ofNullable方法 支持nullOptionalString op3 Optional.ofNullable(lisi);OptionalObject op4 Optional.ofNullable(null);// 第三种方式 通过empty方法直接创建一个空的Optional对象OptionalObject op5 Optional.empty();}Optional的常用方法
/*** Optional中的常用方法介绍* get(): 如果Optional有值则返回否则抛出NoSuchElementException异常* get()通常和isPresent方法一块使用* isPresent():判断是否包含值包含值返回true不包含值返回false* orElse(T t):如果调用对象包含值就返回该值否则返回t* orElseGet(Supplier s):如果调用对象包含值就返回该值否则返回 Lambda表达式的返回值* ifPresent*/Testpublic void test03(){OptionalString op1 Optional.of(zhangsan);OptionalString op2 Optional.empty();// 获取Optional中的值if(op1.isPresent()){String s1 op1.get();System.out.println(用户名称: s1);}// isPresent()get()简洁表达op1.ifPresent(s- System.out.println(有值: s));if(op2.isPresent()){System.out.println(op2.get());}else{System.out.println(op2是一个空Optional对象);}String s3 op1.orElse(李四);System.out.println(s3);String s5 op2.orElseGet(()-{return Hello;});System.out.println(s5);}
方法引用
为什么要用方法引用
在使用Lambda表达式的时候也会出现代码冗余的情况比如用Lambda表达式求一个数组的和
public class FunctionRefTest01 {public static void main(String[] args) {printMax(a-{// Lambda表达式中的代码和 getTotal中的代码冗余了int sum 0;for (int i : a) {sum i;}System.out.println(数组之和 sum);});}/*** 求数组中的所有元素的和* param a*/public void getTotal(int a[]){int sum 0;for (int i : a) {sum i;}System.out.println(数组之和 sum);}private static void printMax(Consumerint[] consumer){int[] a {10,20,30,40,50,60};consumer.accept(a);}
}
上述代码中在Lambda表达式中要执行的代码和getTotal方法中的代码是一样的没有必要重写一份逻辑了这时我们就可以“引用”重复代码
public class FunctionRefTest01 {public static void main(String[] args) {// :: 方法引用 也是JDK8中的新的语法printMax(FunctionRefTest02::getTotal);}
方法引用的格式
符号表示::
符号说明双冒号为方法引用运算符而它所在的表达式被称为 方法引用
应用场景如果Lambda表达式所要实现的方案已经有其他方法存在相同的方案那么则可以使用方法引用。
方法引用的注意事项
被引用的方法参数要和接口中的抽象方法的参数一样当接口抽象方法有返回值时被引用的方法也必须有返回值
方法引用在JDK8中使用是相当灵活的有以下几种形式
instanceName::methodName 对象::方法名ClassName::staticMethodName 类名::静态方法ClassName::methodName 类名::普通方法ClassName::new 类名::new 调用的构造器TypeName[]::new String[]::new 调用数组的构造器
对象名::方法名
这是最常见的一种用法。如果一个类中的已经存在了一个成员方法则可以通过对象名引用成员方法 public static void main(String[] args) {Date now new Date();SupplierLong supplier ()-{return now.getTime();};System.out.println(supplier.get());// 然后我们通过 方法引用 的方式来处理SupplierLong supplier1 now::getTime;System.out.println(supplier1.get());}类名::静态方法名
public class FunctionRefTest04 {public static void main(String[] args) {SupplierLong supplier1 ()-{return System.currentTimeMillis();};System.out.println(supplier1.get());// 通过 方法引用 来实现SupplierLong supplier2 System::currentTimeMillis;System.out.println(supplier2.get());}
}类名::引用实例方法
Java面向对象中类名只能调用静态方法类名引用实例方法是有前提的实际上是拿第一个参数作为方法的调用者
public class FunctionRefTest05 {public static void main(String[] args) {FunctionString,Integer function (s)-{return s.length();};System.out.println(function.apply(hello));// 通过方法引用来实现FunctionString,Integer function1 String::length;System.out.println(function1.apply(hahahaha));}
}
类名::构造器
由于构造器的名称和类名完全一致所以构造器引用使用 ::new的格式使用
public class FunctionRefTest06 {public static void main(String[] args) {SupplierPerson sup ()-{return new Person();};System.out.println(sup.get());// 然后通过 方法引用来实现SupplierPerson sup1 Person::new;System.out.println(sup1.get());BiFunctionString,Integer,Person function Person::new;System.out.println(function.apply(张三,22));}
}数组::构造器 public static void main(String[] args) {FunctionInteger,String[] fun1 (len)-{return new String[len];};String[] a1 fun1.apply(3);System.out.println(数组的长度是 a1.length);// 方法引用 的方式来调用数组的构造器FunctionInteger,String[] fun2 String[]::new;String[] a2 fun2.apply(5);System.out.println(数组的长度是 a2.length);}方法引用是对Lambda表达式符合特定情况下的一种缩写方式它使得我们的Lambda表达式更加的精简也可以理解为lambda表达式的缩写形式不过要注意的是方法引用只能引用已经存在的方法。