2

Java新特性

 2 years ago
source link: https://haojunsheng.github.io/2022/02/java-new-features/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Java新特性

calendar.png2022-02-17

| 阅读:6次

Java新特性

lambda表达式

Java 帝国之函数式编程

Java 帝国之函数式编程

Java编程偏向于命令式的,准确告诉计算机如何做。函数式编程则偏向于声明式的,类似于SQL。

Java 8之前和函数式编程的一个巨大的鸿沟是:Java是强类型的,我们如果要在Java上支持强类型,则需要给函数确定一个类型。

Java8则设计了基于Lambda表达式的类型推断,如

() -> System.out.println("Hello Lambda");
s-> s.toUpperCase();
(x,y) -> x +y ; 

本质上而言,Lambda就是匿名函数。 箭头(->) 左边是函数的参数列表, 右边是方法体

那么,Lambda表达式自然也是可以嵌套的。

我们定义了一个接口:

public interface StringFuction{
        public String apply(String s);        
}

我们实现了一个函数:

public String run (StringFuction f){
        return f.apply("Hello World");
}

我们可以这么用:

run (s -> s.toUpperCase()) ;  HELLO WORLD
run (s -> s.toLowerCase()) ;  hello world

本质上:s -> s.toUpperCase()表达式的类型是StringFuction,由编译器进行类型推断。

本质上:这个StringFunction 的apply方法接收一个字符串参数, 然后返回另外一个字符串的值。

这个等价于我们的匿名类:

run(new StringFuction(){            
     public String apply(String s) {
                return s.toUpperCase();
      }
});

因此,如果我们这么写:run(s -> s.length())就会编译失败。

本质上而言,为了维护Java的强类型,需要定义一个函数接口,编译器会把Lambda表达式和接口进行匹配。在jdk中引入了java.util.function包,定义了下面这些接口:

// 1. Function函数接口: 传入一个类型为T的参数, 返回一个类型为R 的参数
public interface Function<T,R>{
    R apply(T t);
    ......
}

// 2. Predicate<T> 函数接口:传入一个类型为T 的参数, 返回boolean
public interface Predicate<T> {
    boolean test(T t);
    ......
}
// 3. Consumer<T>函数接口:传入一个类型为T的参数,没有返回值
public interface Consumer<T> {
    void accept(T t);
    ......
}
// 4. Supplier<T>接口,返回一个类型为T的参数
public interface Supplier<T> {
    T get();
}
// BinaryOperator<T>接口,
s -> s.length()  就可以匹配 (1)   
x -> x>5   就可以匹配 (2) 
s ->  System.out.println(s)  就可以匹配 (3) 

Java引入了Stream来实现延迟计算(惰性求值的功能)。

public class EvenNumber implements Supplier<Long>{
    long num = 0;
    @Override
    public Long get() {
        num += 2;
        return num ;
    }    
}
// numbers代表无穷无尽的偶数序列,只是没有计算出来而已
Stream<Long> numbers = Stream.generate(new EvenNumber());
numbers.limit(5).forEach(x->System.out.println(x));
输出: 2 4 6 8 10

集合中的流式处理:

Arrays.asList("Hello", "Java8", "Java7").stream()
                .map(s -> s.toUpperCase())
                .filter(s -> s.startsWith("J"))
                .forEach(s -> System.out.println(s));
// 输出
JAVA8
JAVA7

Arrays.asList("Hello", "Java8", "Java7").stream()
                .map(s -> {
                    System.out.println("map: " + s);
                    return s.toUpperCase();
                })
                .filter(s -> {
                    System.out.println("filter:" + s);
                    return s.startsWith("J");
                })
                .forEach(s -> System.out.println(s));
// 输出
map: Hello
filter:HELLO
map: Java8
filter:JAVA8
JAVA8
map: Java7
filter:JAVA7
JAVA7

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK