JDK8.0相关特性
一、JDK8.0中接口新语法
-
JDK8.0,接口中可以定义静态的方法,带有方法的实现部分。
- 语法:public static 返回值类型 方法名(形参列表){ //实现部分 }
-
JDK8.0,接口中可以定义带有默认实现的非抽象方法
- 语法:public default 返回值类型 方法名(形参列表){ // 方法实现 }
二、Lambda表达式的相关语法
-
Lambda表达式实现接口,并创建对象(匿名内部类的简化写法)
-
Lambda表达式在Java语言中引入一个新的语法元素和符号: “->”,该操作符被称为Lambda操作符或是箭头操作符,此操作符将Lambda表达式分为两个部分:
- 左侧:指定Lambda表达式所需要的参数
- 右侧:指定Lambda表达式的执行功能部分
-
语法格式一:无参数、无返回值
接口名 引用名 = ()->{ //执行功能部分 };
案例:
public class Test { public static void main(String[] args) { IA ia = ()->{ System.out.println("m1方法...."); }; ia.m1(); } } interface IA{ void m1(); }
注意:
- 利用Lambda表达式实现的接口,接口中必须只定义一个抽象方法;
- 如果Lambda表达式的实现体仅有一行语句,则{}可以省略,不建议省略。
-
语法格式二:带有参数,没有返回值
接口名 引用 = (数据类型 变量名) ->{//实现体…};
案例一:一个参数
public class Test { public static void main(String[] args) { IA ia = (int n)->{ if(n%2==0){ System.out.println(n+"是偶数...."); }else{ System.out.println(n+"是奇数...."); } }; ia.m1(6); } } interface IA{ void m1(int n); }
案例二:多个参数
public class Test { public static void main(String[] args) { IA ia = (int a,double b)-> { System.out.println("a="+a+",b="+b); }; ia.m1(3,9.8); } } interface IA{ void m1(int n,double d); }
注意:Lambda表达式中的数据类型可以省略,因为编译器可进行类型推断。
-
语法格式三:带有返回值
接口名 引用名 = (参数列表) -> { return 语句;}
public class Test { public static void main(String[] args) { IA ia = (a)->{ if(a<5){ a=a+1; } return a; }; int r=ia.m1(3); System.out.println("r="+r); } } interface IA{ int m1(int a); }
注意:如果Lambda表达式中仅一条return语句,则可以写为
接口名 引用 = (形参列表) ->表达式;不建议使用。
三、Lambda表达式的实际应用
-
实际应用一:利用Lambda表达式实现Ruannble接口
public class Test { public static void main(String[] args) { Runnable r = ()->{ for(int i=0;i<10;i++){ System.out.println("+++++++++++++++"+i); } }; new Thread(r).start(); } }
-
实际应用二:利用Lambda表达式,完成Consumer的实现,接收数据完成对应操作
public class Test { public static void main(String[] args) { Consumer<String> c = (String s)->{ System.out.println(s); }; c.accept("百知威武...."); } }
-
实际应用三:利用Lambda表达式完成,List集合遍历
-
利用匿名内部类完成:
``` List<String> list=Arrays.asList("胡老八","李四,"张三","胡明"); list.forEach(new Consumer<String>() { public void accept(String s) { if(s.contains("胡")){ System.out.println(s); } } });
-
利用Lambda表达式完成:
List<String> list=Arrays.asList("胡老八","李四,"张三","胡明"); list.forEach((s)-> { if (s.contains("胡")) { System.out.println(s); } }); 只是List集合打印遍历输出: list.for((s)-> System.out.println(s))
-
-
练习:在集合ArrayList中存储多个学生对象:
-
在学生集合中筛选出所有男生
-
在学生集合中筛选出所有不及格的学生
-
在学生集合中筛选出所有不及格的男生学生
-
在学生集合中筛选出所有不及格的姓刘的男生
-
-
练习二:调用Collections.sort()方法,通过定制排序比较两个Srudent(先按照年龄比较,年龄相同再按照成绩排序),使用Lambda表达式作为参数进行传递。
public class Test { public static void main(String[] args) { ArrayList<Student> list = new ArrayList(); list.add(new Student("张三",23,88.0)); list.add(new Student("李四",26,98.0)); list.add(new Student("胡八一",25,78.0)); list.add(new Student("胡八一",25,88.0)); Collections.sort(list,(s1,s2)->{ if(s1.getAge()>s2.getAge()){ return 1; }else if(s1.getAge()<s2.getAge()){ return -1; }else{ return Double.compare(s1.getScore(),s2.getScore()); } }); list.forEach((s)-> System.out.println(s)); } }
四、函数式接口(Lambda表达式需要函数式接口的支持)
-
含义:接口中只有一个抽象方法的接口被称为函数式接口。
-
自定义函数式接口:可以利用注解@FunctionalInterface检测接口是否为函数式接口。
@FunctionalInterface interface IA{ int m1(int a); }
注意:添加@FunctionalInterface注解的接口中必须只能有一个抽象方法。自定义函数式接口案例:
public class Test { public static void main(String[] args) { int r = optional(5,(m)->{return m*m;}); System.out.println("r="+r); } public static Integer optional(int n,MyFuntion f){ return f.getValue(n); } } //对一个整数进行计算操作,将计算的结果作为返回值返回 interface MyFuntion{ Integer getValue(int n); }
-
Java8.0内置的四大核心函数式接口
-
消费型接口:Consumer
- void accept(T t); —> 参数为T类型,返回值为 void类型
-
供给型接口:Supplier
- T get(); —>参数为无参,返回值为T类型
-
函数型接口:Function<T,R>
- R apply(T t); —>参数类型为T类型,返回值为R类型
-
断言型接口:Predicate
-
boolean test(T t); —>参数为T类型,返回值为boolean类型
-
案例一:消费型接口:
public class TestFirst { public static void main(String[] args) { happy(20000.0,(s)-> System.out.println("拿着"+s+"元去消费....")); } public static void happy(double money, Consumer<Double> c){ c.accept(money); } }
-
案例二:供给型接口
public class TestFirst { public static void main(String[] args) { happy(20000.0,(s)-> System.out.println("拿着"+s+"元去消费....")); String str=getString(10,()->{ String s = "anhjshfjshsairiweriwir89863lkkqljrkql"; java.util.Random rd = new java.util.Random(); int n=rd.nextInt(s.length()); return s.charAt(n); }); System.out.println(str); } public static String getString(int num, Supplier<Character> s){ String result=null; for(int i=0;i<num;i++){ String str=s.get()+""; result +=str; } return result; } }
-
案例三:函数式接口
public class TestFirst { public static void main(String[] args) { String r=changString("helloworld",(s)->s.toUpperCase()); System.out.println(r); System.out.println(changString("helloworld",(s)->s.substring(1,4))); } public static String changString(String s, Function<String,String> f){ return f.apply(s); } }
-
案例四:断言型接口
public class TestFirst { public static void main(String[] args) { List<String> list= Arrays.asList("zhangsan","lisi","wangwu","lily","tom"); List<String> asList=filterString(list,(s)->s.length()>4); for(String s:asList){ System.out.println(s); } } //将集合中所有的数据元素,根据条件进行过滤 public static List<String> filterString(List<String> list,Predicate<String> p){ List<String> asList=new ArrayList<>(); for(String s:list){ if(p.test(s)){ asList.add(s); } } return asList; } }
-
-
其他函数式接口:
-