目录
Lambda表达式:参数列表,->,具体操作
原理
Lamdba表达式的本质是一个“语法糖”,由编译器推断并将我们转换包装为常规的代码,因此可以使用更少的代码来实现同样的功能。
但是还是不要随便使用,因为如果使用了Lambda表达式,就意味着代码更加简洁,难懂,不容易调试,加大了后期维护的功能。
简单例子
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
具体使用
遍历list
对平常的list进行输出打印,我们平常使用的是for循环遍历,但是在Java8中我们可以使用lamdba表达式,代码量更加少,将原来的三行代码合为了一行代码。
public class Java8 {
public static void main(String args[]) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 以前的循环方式
for (String str : list) {
System.out.print(str + "; ");
}
System.out.println();
// 使用 lambda 表达式
list.forEach((str) -> System.out.print(str + "; "));
}
}
数组排序(匿名内部类)
我们对某个数组进行排序的时候,可能比较傻一点的方法,就是手动排序,什么选择排序,直接排序,冒泡排序,归并排序的,但这种比较浪费时间,而且对算法也有一定的要求。稍微好一点的方法就是使用Arrays提供的sort方法,自己写一个comparator,作为匿名内部类,代码如下:
public class Java8 {
public static void main(String args[]) {
String[] strs = {"chenchen","huangzengzeng","blibili"};
//1.使用匿名内部类
Arrays.sort(strs, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
List<String> list=Arrays.asList(strs);
list.forEach(name->System.out.println(name));
}
}
数组排序(lamdba表达式)
但是有时候觉得上面的代码太冗余了,行数太多,也可以用lamdba表达式,代码如下:
public class Java8 {
public static void main(String args[]) {
String[] strs = {"chenchen","huangzengzeng","blibili"};
Arrays.sort(strs,(String o1,String o2)->o1.compareTo(o2));
List<String> list=Arrays.asList(strs);
list.forEach(name->System.out.println(name));
}
}
方法引用:对Lamdba表达式的近一步简化
原理
也就是对lambda表达式的近一步简化,减少重复代码。
四种形式
方法引用的四种形式:
- 引用静态方法->类名称::static 方法名称
- 引用某个对象的实例的普通方法->实例对象::普通方法
- 引用某个类的普通方法->特定类::普通方法
- 引用构造方法->类名称::new
使用
先写一个person对象,用于底下的测试:
public class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public static int compareByAge(Person a, Person b){
return a.getAge()-b.getAge();
}
}
public class Java8 {
public static void main(String args[]) {
Person person1 = new Person("cc", 24);
Person person2 = new Person("hzz", 23);
Person[] persons = {person1, person2};
//1.引用静态方法
Arrays.sort(persons, Person::compareByAge);
//2.引用对象的普通方法
Supplier<String> name =person1::getName;
//4.引用构造方法
Supplier<Person> supplier = Person::new;
Person person=supplier.get();
}
}
默认方法:接口interface添加默认default方法
原理
在接口中添加一个以实现好的方法,且该接口的实现类中不需要实现该方法。
interface GreetingService
{
void sayMessage(String message);
//可以在接口中定义默认方法
default void sayHello(){
System.out.println("Hello");
}
}
为什么要有默认方法
主要是为了方便扩展已有的接口。如果没有默认方法,实现该接口的所有类都要添加该方法,也就是所有的类都得修改,影响会很大。
如果使用默认方法,可以给已有的接口添加新的方法,而不用修改该接口的所有实现类。
例子来了:在Java8的Iterable接口中添加了一个默认的方法forEach,也正是因为forEach是默认方法,才不用修改Iterable的所有实现类。
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
关于默认方法的调用冲突
关于下面的代码,有几个问题?
1.为什么会报错?
2.如果在InterfaceC重写foo方法,还报错吗?
3.如果在InterfaceB去除foo方法,还报错吗?
Stream API
原理
对数据的筛选和统计。
使用
public class Java8 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("cc", 12));
personList.add(new Person("ls", 23));
Stream<Person> stream = personList.stream();
List<Person> newList = stream.filter(p -> p.getAge() > 20).collect(Collectors.toList());
newList.forEach(person -> System.out.println(person.getName()));
}
}