Stream 流

上一篇下一篇
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)

来个例子(后面也都用这个例子):
有一批学生记录:

名字平均分作弊次数
小红750
小明800
小刚951
小亮850
小白700
小强993

要求过滤出没作弊,且平均分不低于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 深入,并行数据
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值