Java8包括以下特性
- 接口定义增强
- Lambda表达式
- 方法引用
- 內建函数式接口
- Stream
1. 接口定义增强
什么是接口定义增强、需求和总结都整理在代码,请看代码
package com.zbj.spring.boot.java8;
/**
* InterfaceTest
* 接口增强 从java8开始允许在接口中定义普通方法,使用 default 和 static 关键字,跟在访问修饰符之后,
* 两者的区别是,default 定义的普通方法用对象调用,static 定义的方法用接口名调用
* @author weigang
* @create 2017-10-21
**/
public class InterfaceTest {
/**
* 需求
* 一个接口虽则时间的推移,接口下面已经有1w个实现类,这个时候接到个需求,给接口增加一个方法,
* 并且每个实现类这个方法都是相同的实现,那么应该怎么办?
* 总结
* 1.接口里面使用 default 或 static 定义的方法,意义是避免子类重复实现相同的代码方法
* 2.这样的定义只是针对有类似需求的接口,正常的接口还是使用全局常量和抽象方法来定义
* @param args
*/
public static void main(String[] args) {
// MessageImpl message = new MessageImpl();
IMessage message = new MessageImpl();
message.print();
message.hello();
IMessage.helloWorld();
}
}
interface IMessage{
/**
* 定义标准的接口抽象方法(子类必须实现 该方法)
*/
void print();
/**
* 普通接口方法(默认此方法已经被所有子类实现)
*/
default void hello(){
System.out.println("method: hello; hello world!");
}
/**
* 普通接口方法(默认此方法已经被所有子类实现)
*/
static void helloWorld(){
System.out.println("method: helloWorld; hello world!");
}
}
class MessageImpl implements IMessage {
/**
* 内部类访问法访问方法变量的时候可以不用加上final关键字
*/
String msg;
class MessageSub {
public void msg(){
// 访问方法变量
msg = "你好,世界";
}
}
@Override
public void print(){
System.out.println("method: print hello world!");
}
}
2. Lambda表达式
Lambda表达式属于函数式编程的概念,那么为什么需要函数式编程呢?
如果想清楚函数式编程产生的目的,那么必须从匿名内部类分析
package com.zbj.spring.boot.java8;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* LambdaTest
*
* @author weigang
* @create 2017-10-21
**/
public class LambdaTest {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(1);
service.submit(new Runnable() {
@Override
public void run() {
System.out.println("以前匿名内部类写法");
}
});
service.submit(() -> System.out.println("Lambda表达式写法"));
}
}
对于Lambda表达式有三种形式:
- (参数) -> 单行语句;
- (参数) -> {多行语句};
- (参数1, 参数2, …) -> 表达式;
例子如下
public class LambdaTest {
public static void main(String[] args) {
fun((s1, s2) -> s1 + s2);
// 默认包含return
// fun((s1, s2) -> {return s1 + s2;});
}
private static void fun(IPrint iPrint){
System.out.println(iPrint.add(45, 32));
}
}
interface IPrint{
Integer add(Integer num1, Integer num2);
}
3. 方法引用
方法引用的标准形式:
类名::方法名 (注意:方法名没有括号)
Java8中定义了4种形式的方法引用
- 引用静态方法 类名称 :: static方法 String::valueOf
- 引用某个对象的实例方法 实例对象 :: 普通方法
- 引用特定类型的方法 特定类 :: 普通方法
- 引用构造方法 类名称 :: new
引用静态方法
interface IMessage<P, R>{
R convert(P p);
}
public class TestDemo{
public static void main(String[] args){
// 将String.valueOf()方法变成了IMessage的convert() 方法
IMessage<Integer, String> message = String::valueOf;
String convert = message.convert(10000);
System.out.println(convert.replaceAll("0", "8"));
}
}
引用某个对象的实例方法
/**
* FunctionInterface为函数式接口,只能定义一个方法(default和static方法除外,因为它们是普通方法)
*/
@FunctionInterface
interface IMessage<R>{
R upper();
}
public class TestDemo{
public static void main(String[] args){
IMessage<String> message = "hello world"::toUpperCase;
// 相当于调用 "hello world".toUpperCase()
String convert = message.upper();
System.out.println(convert);
}
}
引用特定类型的方法
/**
* FunctionInterface为函数式接口,只能定义一个方法(default和static方法除外,因为它们是普通方法)
*/
@FunctionInterface
interface IMessage<R>{
int compare(R1, R2);
}
public class TestDemo{
public static void main(String[] args){
IMessage<String> message = String::compare;
System.out.println(message.compare("a", "B"));
}
}
引用构造方法
@InterfaceFunction
interface IMessage<T>{
T create(String t, double d);
}
class Book{
private String title;
private double price;
public String toString(){
System.out.println("书名: " + this.title + ", 价格: " + price);
}
}
public class DemoTest{
public static void main(String[] args){
// 引用构造方法
IMessage<Book> message = Book::new;
Book book = message.create("Java核心技术II", 88.88);
System.out.println(book);
}
}
4.內建函数式接口
一个新的包:Java.util.function,在这个包里面针对于用户有可能做的函数式接口做了一个公共定义。在java.util.function包中最为核心的有四个接口:
- 功能型接口:Function R apply(T t) 接收一个参数,返回一个参数
- 消费型接口:Consumer void accept(T t) 只负责接收数据,不返回
- 供给型接口:Supplier T get() 不接收参数,但返回参数
- 断言形接口:Predicate boolean test(T t) 进行判断操作使用
功能型接口 Function
public class DemoTest{
public static void main(String[] args){
Function<String,Boolean> fun = "##hello world"::startsWith;
System.out.println(fun.apply("##"));
}
}
消费型接口 Consumer
public class DemoTest{
public static void main(String[] args){
Consumer<String> consumer = System.out::print;
consumer.accept("hello world");
}
}
供给型接口 Supplier
public class DemoTest{
public static void main(String[] args){
Supplier<String> supplier = "hello world"::toUpperCase;
System.out.println(supplier.get());
}
}
断言形接口:Predicate
public class DemoTest{
public static void main(String[] args){
Predicate<String> pre = "hello world"::equalsIgnoreCase;
System.out.println(pre.test("HelLo WorlD"));
}
}
5. Stream