Java8新特性
Java8新特性
Java8已经出现了很久了,但是呢,还是有很多人都还在习惯使用以前的来版本JDK,或者是以前老版本的编程方式。通过一段时间对Java8新特性的学习之后,自己也深受感触,原来java8版本写代码可以这么简洁。Java8的新特性给我们编程的过程带来了很多便利,不仅仅是代码量少。更多的还是让程序更简洁,减少代码冗余。Java8新特性中有几个比较主要的特性如下:
- Lambda 表达式
- 函数式接口
- 方法引用
- 几个新增库Stream流、Optional类
Lambda 表达式
简介
Lambda 表达式其实就是一种匿名函数,在这之前大家可能还接触过匿名内部类,虽然也是一种匿名函数,但是它并没有Lambda表达式那么简洁,Lambda表达式的特点就是可以传递,在使用Lambda表达式的时候我们可以将代码像数据一样传递。使用Lambda表达式能够极大的减少我们代码的冗余,而且使用也相当的方便。熟练之后会大大加快我们写代码的速度。
Lambda表达式语法
基础语法
Java8中引入了一个新的操作符“->”该操作符称为箭头操作符或Lambda 操作符
箭头操作符将Lambda表达式拆分成两部分:
左侧:Lambda 表达式参数列表。
右侧:Lambda 表达式中所需要执行的功能,即Lambda 体
示例
1:无参数,无返回值
() ->System.out.println("Hello")
2: 有一个参数,并且无返回值
(e) -> System.out.println(e)
3:若只有一个参数,参数的小括号可以省略
e -> System.out.println(e)
4: 两个以上的参数,又返回值,有多条执行语句
(x,y)-> {
System.out.println("Lambda");
return Integer.compare(x,y);
};
5:如果有两个以上的参数,又返回值,只有一条执行语句,Lambda 体的大括号和return可以省略
Comparator
con=(x,y)->Integer.compare(x,y); 6: Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器可以通过上下文推断出数据类型,即“类型推断”
(Integer x,Integery)->Integer.compare(x,y)
函数式接口
简介
是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。我们也可以自定义函数式接口 例如: Java8提供了 @FunctionalInterface
的注解。下面我们详细看下函数式接口。
Java8 提供了4个函数式接口
1. Consumer<T> : 消费型接口 方法:void accep(T t)
2. Supplier<T> : 供给型接口 方法: T get();
3. Function<T,R> : 函数型接口 方法: R apply(T t)
4. Predicate<T> : 断言型接口 方法: boolean Test(T t)
消费型接口: Consumer
@FunctionalInterface
public interface Consumer<T> {
/**
* 对给定参数执行此操作
*/
void accept(T t);
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
使用示例
public class ConsumerCase {
public static void main(String[] args) {
Consumer consumer = new Consumer<Object>() {
@Override
public void accept(Object o) {
System.out.println("o = " + o);
}
};
consumer.accept("我是消费式函数接口1");
consumer.accept("我是消费式函数接口2");
}
}
供给型接口: Supplier
@FunctionalInterface
public interface Supplier<T> {
/**
* 获取一个结果
*/
T get();
}
使用示例:
public class SupplierCase {
public static void main(String[] args) {
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return "这是一个结果";
}
};
String s = supplier.get();
System.out.println(s);
Supplier<List<String>> supplier1 = new Supplier<List<String>>() {
@Override
public List<String> get() {
List<String> arrayList = new ArrayList<>();
arrayList.add("1");
arrayList.add("2");
arrayList.add("4");
return arrayList;
}
};
List<String> lists = supplier1.get();
System.out.println(lists);
}
}
函数型接口: Function
@FunctionalInterface
public interface Function<T, R> {
/**
* 将此函数应用于给定的参数。
*/
R apply(T t);
}
使用示例
public class FunctionCase {
public static void main(String[] args) {
// 这里的参数指定string类型,返回值Object类型,根据自己的需要定义参数类型
Function<String, Object> function = new Function<String, Object>() {
@Override
public Object apply(String s) {
return "传给我的参数是:" + s;
}
};
Object tom = function.apply("大张伟");
System.out.println(tom);
}
}
断言型接口: Predicate
@FunctionalInterface
public interface Predicate<T> {
/**
* 对参数值进行检验
*/
boolean test(T t);
}
使用示例:
public class PredicateCase {
public static void main(String[] args) {
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String s) {
if("1".equals(s)){
return true;
}
return false;
}
};
boolean test = predicate.test("2");
System.out.println("test = " + test);
}
}
除了以上函数式接口,Java8还对以上函数式接口进行扩展,如下:
两个参数的函数:
BiConsumer<T, U>
BiFunction<T, U, R>
BiPredicate<T, U>
这些函数就不详细介绍了,大家自行根据源码理解。
方法引用
简介
方法引用通过方法的名字来指向一个方法。方法引用可以使语言的构造更紧凑简洁,减少冗余代码。方法引用使用一对冒号 ::
示例
public class MethodReference {
public static MethodReference create(final Supplier<MethodReference> supplier) {
return supplier.get();
}
public static void collide(final MethodReference methodReference) {
System.out.println("Collided " + methodReference.toString());
}
public void follow(final MethodReference methodReference) {
System.out.println("Following the " + methodReference.toString());
}
public void repair() {
System.out.println("Repaired " + this.toString());
}
}
构造器引用:它的语法是Class::new,或者更一般的Class< T >::new实例如下
MethodReference methodReference = MethodReference.create(MethodReference::new);
静态方法引用:它的语法是Class::static_method,实例如下:
cars.forEach(MethodReference::collide);
特定类的任意对象的方法引用:它的语法是Class::method实例如下:
cars.forEach(MethodReference::repair);
特定对象的方法引用:它的语法是instance::method实例如下:
public static void main(String[] args) {
MethodReference methodReference = MethodReference.create(MethodReference::new);
final List< MethodReference > cars = Arrays.asList( methodReference );
MethodReference reference = MethodReference.create(MethodReference::new);
cars.forEach(reference::follow);
}
Stream流
由于Stream篇幅过长,大家可以阅读另外一篇文章:
https://www.cnblogs.com/zwhdd/p/17448911.html
Optional类
大家可以阅读另外一篇文章: https://www.cnblogs.com/zwhdd/p/17125123.html
本文来自博客园,作者:笨笨的二黄子,转载请注明原文链接:https://www.cnblogs.com/zwhdd/p/17448946.html