Java 8 新特性

Java 8 新特性

Lambda表达式

Lambda表达式可以说是一个匿名的方法。这个和匿名内部类有点像,
匿名内部类必须有一个父类或者接口。Lambda表达式需要有一个函数接口。

函数接口:只含有一个方法的接口(如果继承某个接口超过一个方法也不行), 一个函数接口可以用@FunctionInterface标记。

语法:

  • (parameters) -> expression 或 (parameters) -> { statements; }
  • 括号种的参数为0时: () -> {表达式/语句}
  • 如果只有一个参数且可推断,参数括号也可以省略: c - > {return c}

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

//运行后 打印: custom lambda interface
public static void main(String[] arg){
TestFunc testFunc = () -> System.out.println("custom lambda interface");
testLambda(testFunc);
}

@FunctionalInterface
public interface TestFunc{
void test();
}

//以前的写法是
TestFunc testFunc1 = new TestFunc() {
@Override
public void test() {
System.out.println("custom lambda interface");
}
};

// 两者对比: 接口test()的方法是无参数的方法, 所以 () 表示无参数
// System.out.println("custom lambda interface"); 这句就是test()的具体实现

//传统线程写法和Lambda表达式对比
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("传统线程写法");
}
}).start();

new Thread(() -> System.out.println("lambda线程写法")).start();

再举个有参数的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

static class Person implements Comparable{
int age;

Person(int age){
this.age = age;
}

@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}

@Override
public int compareTo(Object o) {
if(o instanceof Person){
return this.age - ((Person) o).age;
}
return 0;
}
}

// main方法
List<Person> persons = new ArrayList<>();
persons.add(new Person(19));
persons.add(new Person(36));
persons.add(new Person(22));

Collections.sort(persons, (o1, o2) -> o1.age - o2.age);
System.out.println(persons);

System.out.println("------------------------");
Collections.sort(persons, Person::compareTo);

System.out.println(persons);
// 打印结果:
// [Person{age=19}, Person{age=22}, Person{age=36}]
// ------------------------
// [Person{age=19}, Person{age=22}, Person{age=36}]

Collections.sort(persons, (o1, o2) -> o1.age - o2.age);
这种写法里,o1, o2 对应compareTo(Person o1, Person o2)
o1.age - o2.age 就是具体的实现。

Collections.sort(persons, Person::compareTo);
Person::compareTo 等同于 (o1, o2) -> o1.compareTo(o2)

官方提供了一系列的公共函数接口:在java.util.function包里
Supplier: 无参数提供, 返回T
Predicate: 提供T,返回boolean
Function: 提供T,返回R
Consumer: 提供T,无返回值
BiPredicate: 提供T, U, 返回boolean
BiFunction: 提供T, U, 返回R
BiConsumer: 提供T,U, 无返回值
…..

接口的默认方法和静态方法

Java SE 7,接口在发布之后就已经被定型,除非我们能够一次性更新所有该接口的实现,否则向接口添加方法就会破坏现有的接口实现。默认方法的目标即是解决这个问题。

默认方法也可以被继承,不过,当类型或者接口的超类拥有多个具有相同签名的方法,必须覆盖默认方法,重新实现,也可以调用super指定一个接口的默认方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface OnActionListener{
void onAction();
default void defaultAction(){
System.out.println("defaultAction1");
}
}

interface OnActionListener2{
void onAction2();
default void defaultAction(){
System.out.println("defaultAction2");
}
}

interface OnActionListener3 extends OnActionListener, OnActionListener2{
@Override
default void defaultAction() {
OnActionListener2.super.defaultAction();
}
}

静态方法使得我们可以从接口直接调用和它相关的辅助方法,而不是从其它的类中调用.

方法引用

方法引用有很多种,它们的语法如下:

  • 静态方法引用:ClassName::methodName
  • 实例上的实例方法引用:instanceReference::methodName
  • 超类上的实例方法引用:super::methodName
  • 类型上的实例方法引用:ClassName::methodName
  • 构造方法引用:Class::new
  • 数组构造方法引用:TypeName[]::new
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static void main(String[] arg){
new Thread(A::print).start(); // 静态方法引用

Consumer<A> consumer = A::println; //实例方法引用
printConsumerA(consumer);

Supplier<A> supplier = A::new; // 构造方法引用
A a = supplier.get();
a.println();

IntFunction<A[]> arrayMaker = A[]::new; //数组构造方法引用
A[] arr = arrayMaker.apply(2);
System.out.println(Arrays.toString(arr));
}

private static void printConsumerA(Consumer<A> consumer){
consumer.accept(new A());
}

private static class A{

void println(){
System.out.println("I am A");
}

static void print(){
System.out.println("I am A");
}
}
参考: http://www.cnblogs.com/figure9/archive/2014/10/24/4048421.html
Loading comments box needs to over the wall