上一篇 | 下一篇 |
---|---|
Lambda 表达式 | Stream 深入,并行数据 |
1、简介
java8 的新特性:Stream
流,提升开发效率,使代码更加简洁,主要是对集合中的数据进行各种操作。
2、流的创建
2.1、直接创建
import java.util.stream.Stream;
public class StreamTest {
Stream<String> stream = Stream.of("张三", "李四", "王五");
}
2.2、由数组转化
import java.util.stream.Stream;
public class StreamTest{
String[] fruitArray = new String[] {"张三", "李四", "王五"};
Stream<String> stream = Stream.of(fruitArray);
}
2.3、由集合转化
import java.util.stream.Stream;
public class StreamTest{
List<String> fruits = new ArrayList<>();
fruits.add("张三");
fruits.add("李四");
fruits.add("王五");
Stream<String> stream = fruits.stream();
}
2.4、流的迭代
集合提供的 forEach()
方法可以遍历集合中的元素,Stream
提供的迭代方法也叫forEach()
stream.forEach(System.out::println);
3、流数据过滤
filter() 方法
方法的参数是一个 Lambda 表达式:
->
后面的是条件语句,得用()
括起来(或者不用)而不应该用{}
.filter(student -> student.getCheatCount()==0 && student.getAverageScore()>=80)
来个例子(后面也都用这个例子):
有一批学生记录:
名字 | 平均分 | 作弊次数 |
---|---|---|
小红 | 75 | 0 |
小明 | 80 | 0 |
小刚 | 95 | 1 |
小亮 | 85 | 0 |
小白 | 70 | 0 |
小强 | 99 | 3 |
要求过滤出没作弊,且平均分不低于80的学生
传统的方法就是用判断语句。现在用 Stream
中的新 API
:
Student 类:
public class Student {
private String name;
private int averageScore;
private int cheatCount;
public Student(String name, int averageScore, int cheatCount) {
this.name = name;
this.averageScore = averageScore;
this.cheatCount = cheatCount;
}
public String toString(){
return name + ":" + averageScore;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAverageScore() {
return averageScore;
}
public void setAverageScore(int averageScore) {
this.averageScore = averageScore;
}
public int getCheatCount() {
return cheatCount;
}
public void setCheatCount(int cheatCount) {
this.cheatCount = cheatCount;
}
}
测试类:
import java.util.ArrayList;
import java.util.List;
public class StudentTest {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("小红", 75, 0));
students.add(new Student("小明", 80, 0));
students.add(new Student("小刚", 95, 1));
students.add(new Student("小亮", 85, 0));
students.add(new Student("小白", 83, 0));
students.add(new Student("小强", 99, 3));
students.add(new Student("小黑", 97, 0));
students.add(new Student("小蓝", 86, 0));
students.stream()
.filter(student -> student.getCheatCount()==0 && student.getAverageScore()>=80)
.forEach(student -> System.out.println(student.toString()));
}
}
输出结果:
小明:80
小亮:85
小白:83
小黑:97
小蓝:86
4、流数据映射
map() 方法
.map(object -> {
/**各种操作;
*最后return一个值;(如果代码简单可以不用return)
*/
});
并且 映射数据的类型 可以不同于 源数据类型(这极大提高了流的灵活性 和 扩展性 ,让流的后继操作更加方便):
public class MapTest {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(3, 2, 2);
numbers.stream()
.map(num -> {
return num + "加上这串文字"; //这里返回数据是 String 而源数据是 Integer
})
.forEach(System.out::println);
}
}
输出结果:
3加上这串文字
2加上这串文字
2加上这串文字
5、流数据排序
sorted() 方法
.sorted((... , ...) -> {
... ...
return ... ...;
})
比如实现学生按成绩升序排序:
students.stream()
// 实现升序排序
.sorted((student1, student2) -> {
return student1.getAverageScore() - student2.getAverageScore();
})
.forEach(System.out::println);
小知识点(排序)
无论是集合排序Collections.sort()
还是流排序sorted()
,都需要一个返回值,其实,返回正数表示两个相比较的元素需要交换位置,非整数则不需要。
6、流数据摘取
limit()
.limit(n)
表示摘取前n个数据,只能从流开头开始。
现在来实现一下:取没作弊且分数不小于75分的学生,降序排序,取前5名,如果分数大于等于85,输出
xxx优秀
,小于85输出xxx不错
import java.util.ArrayList;
import java.util.List;
public class StudentTest {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("小红", 75, 0));
students.add(new Student("小明", 80, 0));
students.add(new Student("小刚", 95, 1));
students.add(new Student("小亮", 85, 0));
students.add(new Student("小白", 83, 0));
students.add(new Student("小强", 99, 3));
students.add(new Student("小黑", 97, 0));
students.add(new Student("小蓝", 86, 0));
students.stream()
.filter(student -> student.getCheatCount() == 0 && student.getAverageScore() >= 75)
.sorted((student1, student2) -> {
return student2.getAverageScore() - student1.getAverageScore();
})
.limit(5)
.map(student -> {
if (student.getAverageScore() >= 85) {
return student.getName() + "优秀";
} else {
return student.getName() + "不错";
}
})
.forEach(student -> System.out.println(student.toString()));
}
}
输出结果:
小黑优秀
小蓝优秀
小亮优秀
小白不错
小明不错
7、流的设计思想
数据流的操作过程可以看做一个管道
使用Stream API
系统会帮助完成很多操作,大幅度简化了语法,开发者的注意重点转为数据计算的步骤不用太关心 变量类型等的转换。
Stream
的这种变化,特征就是函数式风格,弱化了面向对象的严格、完整的语法,重心变为通过函数来完成数据计算。
上一篇 | 下一篇 |
---|---|
Lambda 表达式 | Stream 深入,并行数据 |