一、Lambda
Lambda是一个匿名函数,可以理解为是一段可以传递的代码(将代码像数据一样进行传递),使 Java 语言的表达能力得到了提升。
->
左侧:指定了 Lamdba 表达式所需要的所有参数。右侧:Lamdba 表达式要执行的功能。
interface Foo {
void sayHello();
}
public class LamdbaDemo {
public static void main(String[] args) {
Foo foo = () -> {
System.out.println("hello");
};
foo.sayHello();
}
}
运行结果:
hello
函数氏接口
Lamdba 表达式,必须是函数氏接口,必须只有一个方法,如果接口中只有一个方法,Java 默认它为函数式接口。为了正确的使用 Lamdba 表达式,需要给接口加一个注解:
@FunctionalInterface
函数式接口中,可以有实现方法,也可以有静态方法。
二、四大函数型接口
public class StreamDemo {
public static void main(String[] args) {
// 消费型接口 Consumer
// void accept(T t); 返回类型void
// 复制小括号,写死右箭头,落地大括号
Consumer<String> consumer = (t) -> {
System.out.println(t);
};
consumer.accept("hello");
// 供给型接口 Supplier
// T get(); 有返回值
Supplier<Integer> supplier = () -> {
return 1;
};
System.out.println(supplier.get());
// 函数型接口 Function
// R apply(T t);
Function<Integer, Integer> function = (t) -> {
return t * 2;
};
System.out.println(function.apply(6));
// 断定型 Predicate
// boolean test(T t);
Predicate<String> predicate = (t)->{
return t.equals("f");
};
System.out.println(predicate.test("f"));
System.out.println(predicate.test("fo"));
}
}
运行结果:
hello
1
12
true
false
三、Stream
**定义:**对数据源的计算
特点:
- 不会存储元素;
- 经过操作不会改变原有的数据,而会产生新的数据源;
- 操作延迟的
class User {
private int id;
private int age;
private String name;
public User() {
}
public User(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class StreamDemo2 {
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User(1, 22, "zhangsan1"));
list.add(new User(2, 30, "lisi2"));
list.add(new User(3, 27, "wangwu3"));
list.add(new User(4, 53, "zhaoliu4"));
list.add(new User(5, 42, "zhang5"));
list.add(new User(6, 12, "san6"));
list.stream().forEach((t) -> {
System.out.println(t);
});
}
}
运行结果:
User{id=1, age=22, name='zhangsan1'}
User{id=2, age=30, name='lisi2'}
User{id=3, age=27, name='wangwu3'}
User{id=4, age=53, name='zhaoliu4'}
User{id=5, age=42, name='zhang5'}
User{id=6, age=12, name='san6'}
// 过滤,排序,限制
list.stream().filter((user) -> {
return user.getAge() % 2 == 0;
}).sorted((o1, o2) -> {
return o1.getAge() - o2.getAge();
}).limit(3).forEach(System.out::println);
运行结果:
User{id=6, age=12, name='san6'}
User{id=1, age=22, name='zhangsan1'}
User{id=2, age=30, name='lisi2'}
// 存储了修改之后的数据
List<User> users = list.stream().filter((user) -> {
return user.getAge() % 2 == 0;
}).sorted((o1, o2) -> {
return o1.getAge() - o2.getAge();
}).limit(3).collect(Collectors.toList()); //Collectors.toSet() 快捷键var
List<Integer> collect = list.stream().map(User::getId).collect(Collectors.toList());
collect.forEach(System.out::println);
1
2
3
4
5
6
// 使用年龄进行分组
Map<Integer, List<User>> collect = list.stream().collect(Collectors.groupingBy(User::getAge));
Iterator<Map.Entry<Integer, List<User>>> iterator = collect.entrySet().iterator();
while (iterator.hasNext()) {
// 获取集合中的数据
Map.Entry<Integer, List<User>> entry = iterator.next();
Integer age = entry.getKey();
List<User> value = entry.getValue();
System.out.println(age + "\t" + value);
}
运行结果:
22 [User{id=1, age=22, name='zhangsan1'}, User{id=4, age=22, name='zhaoliu4'}]
42 [User{id=5, age=42, name='zhang5'}, User{id=6, age=42, name='san6'}]
27 [User{id=3, age=27, name='wangwu3'}]
30 [User{id=2, age=30, name='lisi2'}]