系列文章目录
第一篇 java8新语法详解
目录
总结 学习常用表达式
生成可参考右边的帮助文档
前言
新项目已经使用了java8开发,语言简洁,快来学习一下吧
提示:以下是本篇文章正文内容,下面案例可供参考
一、java8变化是什么?
Java 8中最大的也是期待已久的变化.它允许我们将一个函数当作方法的参数(传递函数),或者说把代码当作数据,这是每个函数式编程者熟悉的概念,很多基于 JVM平台的语言一开始就支持Lambda表达式,但是Java程序员没有选择,只能使用匿名内部类来替代Lambda
二、函数式(Funtional)接口
如果一个接口中,只声明一个抽象方法,则此接口就称为函数式接口
java.util.function下是jdk自带函数式接口
不是每个接口都可以缩写成 Lambda 表达式。只有那些函数式接口(Functional Interface)才能缩写成 Lambda 表示式。
1)Java从诞生起就一直倡导“万物皆可对象”,在Java里面向对象(OOP)编程是一切,但是随着python、Scala等语言的兴起和挑战,Java不得不作出调整以便支持更加广泛的技术要求,也即Java不但可以支持OOP还可以支持OOF(面向函数编程)
2)在函数式编程语言中,函数被当作一等公民对待,在将函数作为一等公民的编程语言中,Lambda表达式的类型是函数,但是在Java8中,有所不同。在Java8注解,Lambda表达式是对象,而不是函数,它们必须依附于一类特别的对象类型—函数式接口
3)简单地说:在Java8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也即是说,只要一个对象是函数式接口的实例 ,那么该对象就可以用Lambda表达式来表达
三、表达式
1.->表达式
Lambda 表达式:在java8语言引入的一种心得语法元素和操作符,这个操作符为 “->” ,该操作符被统称为Lambda操作符或者箭头操作符。它将Lambda分为两个部分:
* -> :lambda操作符,也称箭头操作符
* -> 左边是 lambda形参列表 (接口中抽象方法的形参列表)
* -> 右边是 lambda体 (重写的抽象方法的方法体)
左边右边均可以简写
//无参数无返回值
Runnable runnable = () -> System.out.println("runable");
//有参数无返回值
Consumer<Integer> consumer = (Integer a) -> System.out.println(a);
//有参数有返回值
Comparator<String> comparator = (a,b) -> a.compareTo(b);
2.:: 表达式
类型 | 语法 | lambda表达式 |
静态方法引用 | 类名::staticMethodName | (args) -> 类名.staticMethodName(args) |
实例方法引用 | 实例名::instanceMethodname | (args) -> 实例名.instanceMethodName(args) |
对象方法引用 | 类名::instanceMethodName | (实例名,args) -> 实例名.instanceMethodName(args) |
构造方法引用 | 类名::new | args -> new 类名(args) |
静态方法引用
@FunctionalInterface
interface Convert<T,S>{
T trans(S from);
}
Convert<String,Integer> convert1 = String::valueOf; //函数是接口的实例
System.out.println(convert1.trans(123)); //123
实例方法引用
//创建一个类
class TestStr{
String startWith(String str){
return str.valueOf(str.charAt(0));
}
}
TestStr testStr = new TestStr();
Convert<String,String> convert = testStr::startWith;//函数式接口实例
System.out.println( convert.trans("test"));//输出 t
特定类型的任意对象的实例方法
ClassName::instanceMethodName
Convert<Integer,String> convert2 = String::length;
Convert<String,String> convert3 = ( s) -> s.toLowerCase();//String::toLowerCase
System.out.println(convert2.trans("testtest"));
System.out.println(convert3.trans("TETSDFSDF"));
//含参数的特定类型的引用
@FunctionalInterface
interface Convert2<T>{
Integer trans(T t1,T t2);
}
Convert2<String> stringConvert2 = String::compareTo;
System.out.println(stringConvert2.trans("123","545"));
引用构造函数
构造函数本质上是静态方法,只是方法名字比较特殊。
ClassName::new
例子: String::new,对应的 Lambda:() -> new String()
Convert<String,StringBuffer> convert21 = String::new;
convert21.trans(new StringBuffer("34234"));
class Name {
String firstName;
String lastName;
Name() {}
Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
@FunctionalInterface
interface NameConvert<T> {
T create(String firstName, String lastName);
}
@FunctionalInterface
interface NameConvertTest<T> {
T create();
}
@Test
public void testPerson(){
NameConvert<Name> personPersonFactory = new NameConvert<Name>() {
@Override
public Name create(String firstName, String lastName) {
return new Name(firstName,lastName);
}
};
NameConvert<Name> personPersonFactory1 = ( firstName, lastName )-> new Name(firstName,lastName);
NameConvert<Name> personPersonFactory2 = Name::new;
//无参构造函数
NameConvertTest<Name> nameConvertTest = Name::new;
ystem.out.println(nameConvert2.create("123","name"));
System.out.println(nameConvertTest.create());
System.out.println(nameConvert2.create("123","name").firstName);
System.out.println(nameConvertTest.create().firstName);
}
输出:
cn.com.servyou.test.SimpleTest$Name@7a92922
cn.com.servyou.test.SimpleTest$Name@71f2a7d5
123
null
数组构造方法引用
组成语法格式: TypeName[]::new
int[]::new是一个含有一个参数的构造器引用,这个参数就是数组的长度。等价于lambda表达式 x -> new int[x]
IntFunction<int[]> intFunction = int[]::new;
int [] arr = intFunction.apply(10);
System.out.println(arr[0]);
System.out.println(arr.length);
//使用intFunction构造,因为使用的函数是长度,不是填充的double值
IntFunction<double[]> doubleFunction = double[]::new;
double [] doubleArr = doubleFunction.apply(5);
System.out.println(doubleArr[0]);
System.out.println(doubleArr.length);
总结
本篇介绍了常用的表达式,学习后基本上语法是能够了解了,下次学习一下常用函数式接口