目录
JDK8新特性
Java8介绍
JAVA 8主要新特性
Java 8接口增强-默认方法
接口
接口的应用
Lambda表达式介绍
Lambda表达式的写法
功能性接口Lambda表达式的应用
函数接口
JDK8新特性
Java8介绍
• Java8 是 Java 发布以来改动最大的一个版本,其中主要添加了函数式编程、 Stream 、一些日期处理类。函数式编程 中新 加了一些概念: Lambda 表达式 、函数式接口、函数引用、默认方法、 Optional 类等; Stream 中提供了一些流式处理集合的方法,并提供了一些归约、划分等类的方法;日期中添加了 ZoneDateTime 、 DataFormater 等线程安全的方法 类 ;
JAVA 8主要新特性
• Lambda 表达式• 函数 式 接口• Stream API• 方法 引用• Date-Time API• 接口增强
Java 8接口增强-默认方法
• 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表达式介绍
正如你所看到的,使用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表达式的写法
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);
}
}
功能性接口Lambda表达式的应用
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<T , R>: 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); } }