文章目录
1. Java Stream流
1.1 Stream流简介
1. Stream 流介绍
- Stream 流是 Java8 提供给开发者的一组 操作集合 的 API。
- 它将要处理的元素看作是一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选、排序、聚合等。
2. Stream 流的好处
假设有以下字符串 "1"
,"2"
,"123"
,"234"
,"12345"
,我们想要获得长度大于4的字符串。以下提供两种写法.
- 未使用 stream流
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
// 创建新集合,用来存储过滤后的字符串元素
ArrayList<String> newList = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("123");
list.add("234");
list.add("12345");
// 把长度大于4的字符串存储
for(String s:list) {
if(s.length()>4)
newList.add(s);
}
// 输出 newList
for(String s:newList){
System.out.println(s);
}
}
}
- 使用 stream 流
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("123");
list.add("234");
list.add("12345");
// Stream 流写法
list.stream().filter(s -> s.length() > 4).forEach(System.out::println);
}
}
好处:
1. 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义
2. Stream流把真正的函数式编程风格引入到Java中
3. 可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码
4. 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象
1.2 Stream流的常见生成方式
1. Stream流的思想
2. 生成Stream流的方式
-
Collection体系集合
使用默认方法stream()生成流, default Stream stream() -
Map体系集合
把Map转成Set集合,间接的生成流 -
数组
通过Stream接口的静态方法of(T… values)生成流
3. 代码演示
import java.util.*;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
//Collection体系的集合可以使用默认方法stream()生成流
List<String> list = new ArrayList<String>();
Stream<String> listStream = list.stream();
Set<String> set = new HashSet<String>();
Stream<String> setStream = set.stream();
//Map体系的集合间接的生成流
Map<String,Integer> map = new HashMap<String, Integer>();
Stream<String> keyStream = map.keySet().stream();
Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();
//数组可以通过Stream接口的静态方法of(T... values)生成流
String[] strArray = {"hello","world","java"};
Stream<String> strArrayStream = Stream.of(strArray);
Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
Stream<Integer> intStream = Stream.of(10, 20, 30);
}
}
1.3 Stream流中间操作方法
1. 概念
- 中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作。
2. 常见方法
方法名 | 说明 |
---|---|
Stream filter(Predicate predicate) | 用于对流中的数据进行过滤 |
Stream limit(long maxSize) | 返回此流中的元素组成的流,截取前指定参数个数的数据 |
Stream skip(long n) | 跳过指定参数个数的数据,返回由该流的剩余元素组成的流 |
static Stream concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
Stream distinct() | 返回由该流的不同元素(根据Object.equals(Object) )组成的流 |
Stream sorted() | 返回由此流的元素组成的流,根据自然顺序排序 |
Stream sorted(Comparator comparator) | 返回由该流的元素组成的流,根据提供的Comparator进行排序 |
Stream map(Function mapper) | 返回由给定函数应用于此流的元素的结果组成的流 |
IntStream mapToInt(ToIntFunction mapper) | 返回一个IntStream其中包含将给定函数应用于此流的元素的结果 |
3. filter代码演示
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("黄晓明");
list.add("张三");
list.add("张无忌");
list.add("李子明");
list.add("樊星辰");
list.add("李双双");
// 把list集合中以张开头的元素在控制台输出
list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
System.out.println("--------");
// 把list集合中长度为3的元素在控制台输出
list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
System.out.println("--------");
// 把list集合中以张开头的,长度为3的元素在控制台输出
list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() ==
3).forEach(System.out::println);
}
}
4. limit&skip代码演示
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("黄晓明");
list.add("张三");
list.add("张无忌");
list.add("李子明");
list.add("樊星辰");
list.add("李双双");
// 取前3个数据在控制台输出
list.stream().limit(3).forEach(System.out::println);
System.out.println("--------");
// 跳过3个元素,把剩下的元素在控制台输出
list.stream().skip(3).forEach(System.out::println);
System.out.println("--------");
// 跳过2个元素,把剩下的元素中前2个在控制台输出
list.stream().skip(2).limit(2).forEach(System.out::println);
}
}
5. concat&distinct代码演示
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("黄晓明");
list.add("张三");
list.add("张无忌");
list.add("李子明");
list.add("樊星辰");
list.add("李双双");
// 取前4个数据组成一个流
Stream<String> s1 = list.stream().limit(4);
// 跳过2个数据组成一个流
Stream<String> s2 = list.stream().skip(2);
// 合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
Stream.concat(s1,s2).distinct().forEach(System.out::println);
}
}
6. sorted代码演示
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("huangxiaoming");
list.add("zhangsan");
list.add("zhangwuji");
list.add("liziming");
list.add("fanxingchen");
list.add("lishuangshuang");
// 按照字母顺序把数据在控制台输出
list.stream().sorted().forEach(System.out::println);
//按照字符串长度把数据在控制台输出
list.stream().sorted((s1,s2) -> {
int num = s1.length()-s2.length();
int num2 = num==0?s1.compareTo(s2):num;
return num2;
}).forEach(System.out::println);
}
}
7. map&mapToInt代码演示
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("10");
list.add("20");
list.add("30");
list.add("40");
list.add("50");
// 将集合中的字符串数据转换为整数之后在控制台输出
// list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println);
// list.stream().map(Integer::parseInt).forEach(System.out::println);
// list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
//int sum() 返回此流中元素的总和
int result = list.stream().mapToInt(Integer::parseInt).sum();
System.out.println(result);
}
}
1.4 Stream流终结操作方法
1. 概念
终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作。
2. 常见方法
方法名 | 说明 |
---|---|
void forEach(Consumer action) | 对此流的每个元素执行操作 |
long count() | 返回此流中的元素数 |
3. 代码演示
import java.util.ArrayList;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
// 创建一个集合,存储多个字符串元素
ArrayList<String> list = new ArrayList<String>();
list.add("黄晓明");
list.add("张三");
list.add("张无忌");
list.add("李子明");
list.add("樊星辰");
list.add("李双双");
// 把集合中的元素在控制台输出
// list.stream().forEach(System.out::println);
// 统计集合中有几个以张开头的元素,并把统计结果在控制台输出
long count = list.stream().filter(s -> s.startsWith("张")).count();
System.out.println(count);
}
}
1.5 Stream流的收集操作
1. 概念
对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中。
2. 常用方法
方法名 | 说明 |
---|---|
R collect(Collector collector) | 把结果收集到集合中 |
3. 工具类Collectors提供了具体的收集方式
方法名 | 说明 |
---|---|
public static Collector toList() | 把元素收集到List集合中 |
public static Collector toSet() | 把元素收集到Set集合中 |
public static Collector toMap(Function keyMapper,Function valueMapper) | 把元素收集到Map集合中 |
4. 代码演示
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo {
public static void main(String[] args) {
//创建List集合对象
List<String> list = new ArrayList<String>();
list.add("小红");
list.add("小明");
list.add("小王");
list.add("小蓝");
// 得到名字为3个字的流
Stream<String> listStream = list.stream().filter(s -> s.length() == 3);
// 把使用Stream流操作完毕的数据收集到List集合中并遍历
List<String> names = listStream.collect(Collectors.toList());
for(String name : names) {
System.out.println(name);
}
//创建Set集合对象
Set<Integer> set = new HashSet<Integer>();
set.add(10);
set.add(20);
set.add(37);
set.add(31);
set.add(35);
// 得到年龄大于25的流
Stream<Integer> setStream = set.stream().filter(age -> age > 25);
// 把使用Stream流操作完毕的数据收集到Set集合中并遍历
Set<Integer> ages = setStream.collect(Collectors.toSet());
for(Integer age : ages) {
System.out.println(age);
}
//定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成
String[] strArray = {"小红,20", "小明,29", "小王王,33", "小白,25"};
// 得到字符串中年龄数据大于28的流
Stream<String> arrayStream = Stream.of(strArray).filter(s ->
Integer.parseInt(s.split(",")[1]) > 28);
// 把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,年龄作值
Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s ->
s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
Set<String> keySet = map.keySet();
for (String key : keySet) {
Integer value = map.get(key);
System.out.println(key + "," + value);
}
}
}