Java作为一门火热的编程语言,为当今的互联网世界立下了汗马功劳,如今她已经25 岁了,从诞生至今随着时间的推移,Java已经更新换代到了Java14了,但是根据JetBrains发布的调查结果来看,Java8,即JDK1.8仍是最常被使用的一个版本,她向我们提供了很多方便的新接口,今天来讲一下Stream这个新特性。
Stream也是一个流,不过和一般的IO流有一些不一样的地方。
Stream是在Java.util.Stream包路径下,主要作用就是对集合数据进行查找过滤等操作,是一种高效且易用的数据处理方式。
对于一般规模的数据其实和普通的集合没有什么太大的区别,但是数据一旦规模很大,Stream的效果就很明显了。它会将数据处理为一种流。
在大数据领域有一个Stream流实时框架
Stream和Collection的区别:
操作流程比较简单(和IO流类似):
首先创建一个数据源类
public class Student implements Comparable{
private Integer id;
private String name;
private Integer age;
private Double score;
public Student(Integer id, String name, Integer age, Double score) {
this.id = id;
this.name = name;
this.age = age;
this.score = score;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public Double getScore() {
return score;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setScore(Double score) {
this.score = score;
}
@Override
public int compareTo(Object o) {
Student o1=(Student)o;
return o1.getAge()-this.getAge();
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
创建数据(仅仅是为了方便数据的写入)
public class StudentData {
public static List <Student> getStudents(){
ArrayList <Student> students=new ArrayList<>();
students.add(new Student(1,"赤",21,89.5));
students.add(new Student(2,"橙",22,90.5));
students.add(new Student(3,"黄",23,87.1));
students.add(new Student(4,"绿",24,89.7));
return students;
}
}
public static void test1() {
List<Student> students = StudentData.getStudents();
// 第一种 返回一个顺序流
Stream<Student> stream = students.stream();
// 第二种 返回一个并行流
Stream<Student> stream1 = students.parallelStream();
}
public static void test2() {
// 获取一个整形Stream
int[] arr = {1, 34, 2, 54, 56, 34};
IntStream stream = Arrays.stream(arr);
}
public static void test3() {
Stream<String> stringStream = Stream.of("A", "B", "C", "D");
Stream.of(
new Student(1, "Chuki", 20, 90.5),
new Student(2, "Zorina", 20, 99.9)
);
}
public static void test4() {
// 每隔5个数取一次,从0开始,此时就会无限循环
// 相当于:
// for (int i = 0; ; ) {
// i += 5;
// }
Stream<Integer> iterate = Stream.iterate(0, t -> t + 5);
// 取出一个随机数
Stream<Double> generate = Stream.generate(Math::random);
}
filter——接收lambda,从流中排除某些操作;
limit——截断流,使其元素不超过给定对象
skip(n)——跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
distinct——筛选,通过流所生成元素的hashCode()和equals去除重复元素
public static void test5() {
/**
* 写成System.out::println这种语法叫做方法引用。该功能特性也是JDK8以后引入的,你可以把它看成lambdas表达式的语法糖
* 可以用lambdas表达式改写成以下代码:list.forEach((t) -> System.out.println(t));
* 这样还不明白的话,也可以这样:list.forEach((String t)-> System.out.println(t));
* 这样的效果跟System.out::println是一样
*/
List<Student> list = StudentData.getStudents();
// 过滤:过滤出所有年龄大于22岁的同学
System.out.println("=============");
list.stream().filter(item -> item.getAge() > 22).forEach(System.out::println);
// 截断流:筛选出前三条
list.stream().limit(3).forEach(System.out::println);
// 跳过元素:跳过前两个元素
list.stream().skip(2).forEach(System.out::println);
System.out.println("================");
// 过滤重复元素
list.stream().distinct().forEach(System.out::println);//没有重复的,根据hashcode判断
}
map——接受Lambda,将元素转换成其他形式或提取信息。接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
public static void test6() {
//map操作
List<String> list = Arrays.asList("hello", "word", "chuki");
Stream<String> stream = list.stream();
//将每一个小写字母都转换为大写字母映射
stream.map(str -> str.toUpperCase()).forEach(System.out::println);
//筛选出所有的年龄,再过滤出所有大于23的年龄
List<Student> students = StudentData.getStudents();
Stream<Student> stream1 = students.stream();
//将流中的每一值转换为另一个值
Stream<Integer> stream2 = stream1.map(Student::getAge);
stream2.filter(age -> age > 23).forEach(System.out::println);
}
在这里插入图片描述
sorted()——自然排序(Comparable)
sorted(Comparator com)——定制排序(Comparator)
public static void test7() {
// 自然排序
List<Integer> list = Arrays.asList(4, 8, 6, 5, 2, 3, 1, 7);
Stream<Integer> stream = list.stream();
stream.sorted().forEach(System.out::println);
// 对象排序,对象排序可以先实现comparable接口或者直接指定
// 第一种:先实现comparabl
System.out.println("=========年龄从大到小排序==========");
List<Student> students = StudentData.getStudents();
students.stream().sorted().forEach(System.out::println);
// 第二种:直接指定comparator
System.out.println("==========年龄从小到大排序==========");
List<Student> students1 = StudentData.getStudents();
students1.stream().sorted((e1, e2) -> (int) (e1.getAge() - e2.getAge())).forEach(System.out::println);
}
allMatch–检查是否匹配所有元素
anyMatch–检查是否至少匹配一个元素
noneMatch–检查是否没有匹配所有元素
findFirst–返回第一个元素
findAny–返回当前流中的任意元素
count–返回流中元素的总个数
max–返回流中最大值
min–返回流中最小值
public static void test8() {
List<Student> list = StudentData.getStudents();
//判断所有的学生年龄是否都大于20岁
boolean allMatch = list.stream().allMatch(student -> student.getAge() > 20);
//判断是否存在学生的年龄大于20岁
boolean anyMatch = list.stream().anyMatch(student -> student.getAge() > 20);
//判断是否不存在学生叫小白
boolean noneMatch = list.stream().noneMatch(student -> student.getName().equals("黄"));
//查找第一个学生
Optional<Student> first = list.stream().findFirst();
//查找当前流中的元素
Optional<Student> any = list.stream().findAny();
//查找所有的学生数量
long count = list.stream().count();
//查找成绩大于90的数量
long count1 = list.stream().filter(student -> student.getScore() > 90).count();
//查找学生的最高分数
Stream<Double> doubleStream = list.stream().map(student -> student.getScore());
Optional<Double> max = doubleStream.max(Double::compareTo);
System.out.println(max);
}
reduce–归约操作可以将流中元素反复结合起来,得到一个值
public static void test9() {
//计算数的总和
List<Integer> list = Arrays.asList(4, 5, 6, 1, 8, 9, 2, 3, 7);
Integer reduce = list.stream().reduce(0, Integer::sum);
System.out.println(reduce);
//计算学生总分
List<Student> students = StudentData.getStudents();
Stream<Double> doubleStream = students.stream().map(Student::getScore);
Optional<Double> reduce1 = doubleStream.reduce(Double::sum);
System.out.println(reduce1.get());
}
collect:将流转换为其他形式,接收一个Collector接口实现,用于给Stream中汇总的方法
public static void test10() {
//返回一个list
List<Student> students = StudentData.getStudents();
List<Student> list = students.stream().filter(student -> student.getScore() > 88).collect(Collectors.toList());
System.out.println(list);
//返回一个set
Set<Student> set = students.stream().filter(s -> s.getAge() > 23).collect(Collectors.toSet());
System.out.println(set);
}
List<Student> list = students.stream().filter(student -> student.getScore() > 88).collect(Collectors.toList());
System.out.println(list);
//返回一个set
Set<Student> set = students.stream().filter(s -> s.getAge() > 23).collect(Collectors.toSet());
System.out.println(set);
}
stream基本的语法就是这样,你会发现Stream就像是一个下具一样,可以帮我们分析处理数据,极其的好用,但是目前还不知道其效率如何。
根据网上一位大佬的内存时间分析,其实在数据量比较庞大的时候,Stream可以为我们节省大量的时间。