作用
结合了Lambda表达式,简化集合、数组的操作
Stream流的使用步骤
先得到一条Stream流(流水线),并把数据放上去
数据的类型 | 方法名 | 说明 |
单列集合 | 单列集合名.stream () | Collection中 的默认方法 |
双列集合 | 双列集合名.keySet().stream () | 先进行预处理再 转化为Stream流 |
双列集合名.entrySet().stream () | ||
数组 | Arrays.stream (T[] array) | Arrays工具类中 的静态方法 |
一堆零散数据 | Stream.of (T... values) | Stream接口中 的静态方法 |
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.stream.Stream;
public class Test1 {
public static void main(String[] args) {
//单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "aa", "bb", "cc", "dd");
list.stream().forEach(s -> System.out.println(s));
//aa
//bb
//cc
//dd
//双列集合获取Stream流
HashMap<String, String> hm = new HashMap<>();
hm.put("苹果", "apple");
hm.put("香蕉", "banana");
hm.put("橘子", "orange");
//方式1:只获取键
hm.keySet().stream().forEach(s -> System.out.println(s));
//苹果
//香蕉
//橘子
//方式2:获取键值对对象
hm.entrySet().stream().forEach(s -> System.out.println(s));
//苹果=apple
//香蕉=banana
//橘子=orange
hm.entrySet().stream().forEach(s -> System.out.println(s.getValue()));
//apple
//banana
//orange
hm.entrySet().stream().forEach(s -> System.out.println(s.getKey()));
//苹果
//香蕉
//橘子
//数组获取Stream流
String[] arr = {"cat", "dog", "pig"};
Arrays.stream(arr).forEach(s -> System.out.println(s));
//cat
//dog
//pig
//同种类型的一堆数据
Stream.of(1, 2, 3).forEach(s -> System.out.println(s));
//1
//2
//3
}
}
使用中间方法对流水线上的数据进行操作
注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
注意2: 修改Stream流中的数据,不会影响原来集合或者数组中的数据
名称 | 说明 |
Stream<T> filter (过滤条件) | 过滤 |
Stream<T> limit (long maxSize) | 获取前几个元素 |
Stream<T> skip (long n) | 跳过前几个元素 |
Stream<T> distinct() | 元素去重,依赖 (hashCode和equals方法) |
Stream.concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
Stream<R> map(Function<T,R> mapper) | 转换流中的数据类型 |
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Test2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-23", "李四-24", "王五-25");
//过滤,留下姓张的
//匿名内部类
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
//参数s代表流中的每一个元素
//返回值为true代表该元素留下
//返回值为false代表该元素被过滤
return s.startsWith("张");
}
}).forEach(s -> System.out.println(s));//张三-23
//简化为lambda表达式
list.stream()
.filter(s -> s.startsWith("张"))
.forEach(s -> System.out.println(s));
//张三-23
//获取前几个元素
list.stream().limit(2)
.forEach(s -> System.out.println(s));
//张三-23
//李四-24
//跳过前几个元素
list.stream().skip(2)
.forEach(s -> System.out.println(s));
//王五-25
System.out.println("-----------------");
//元素去重
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1, "苹果", "苹果", "香蕉", "橘子");
list1.stream().distinct().forEach(s -> System.out.println(s));
//苹果
//香蕉
//橘子
//合并a和b两个流为一个流
Stream.concat(list.stream(), list1.stream())
.forEach(s -> System.out.println(s));
//张三-23
//李四-24
//王五-25
//苹果
//苹果
//香蕉
//橘子
//转换流中的数据类型,将list中字符串中的年龄以int类型输出
//匿名内部类
//第一个泛型表示元素原来的类型
//第二个泛型表示元素转化后的类型
//参数s代表流中每一个元素
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[1]);
}
}).forEach(s -> System.out.println(s));
//23
//24
//25
//简化为lambda表达式
list.stream()
.map(s -> Integer.parseInt(s.split("-")[1]))
.forEach(s -> System.out.println(s));
//23
//24
//25
}
}
使用终结方法对流水线上的数据进行操作
名称 | 说明 |
void forEach(Consumer action) | 遍历 |
long count() | 统计 |
toArray() | 收集流中的数据,放到数组中 |
collect(Collector collector) | 收集流中的数据,放到集合中 |
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.IntFunction;
public class Test3 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "苹果", "橘子", "香蕉");
//遍历
//匿名内部类
list.stream().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
//形参s代表流中每一个元素
System.out.println(s);
}
});
//lambda表达式
list.stream().forEach(s -> System.out.println(s));
//苹果
//橘子
//香蕉
//统计
long count = list.stream().count();
System.out.println(count);
//3
//收集流中的数据,放到数组中
//toArray方法的参数的作用:负责创建一个指定类型的数组
//toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
//toArray方法的返回值:是一个装着流里面所有数据的数组
//空参默认生成的是Object类型的数组
Object[] arr1 = list.stream().toArray();
System.out.println(Arrays.toString(arr1));
//[苹果, 橘子, 香蕉]
//生成指定类型的数组:
//匿名内部类
//IntFunction的泛型:具体类型的数组
//apply的形参:流中数据的个数,要跟数组的长度保持一致
//apply的返回值:具体类型的数组
//方法体:就是创建数组
String[] arr2 = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
//lambda表达式
String[] arr3 = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(arr3));
//[苹果, 橘子, 香蕉]
}
}
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Test4 {
public static void main(String[] args) {
//collect(Collector collector) 收集流中的数据,放到集合中
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三-23", "张弓长-23", "李四-24", "王五-25");
//收集流中的数据,放到集合中,要求收集后的数据都姓张
//list集合
List<String> newList = list.stream()
.filter(s -> s.startsWith("张"))
.collect(Collectors.toList());
System.out.println(newList);
//[张三-23, 张弓长-23]
//Set集合,可以去重
Set<String> newSet = list.stream()
.filter(s -> s.startsWith("张"))
.collect(Collectors.toSet());
System.out.println(newSet);
//[张三-23, 张弓长-23]
//Map集合
//确定键是姓名,值是年龄
//匿名内部类
//Collectors.toMap方法有两个参数
//第一个是键的规则
//第二个是值的规则
//Function有两个泛型
//第一个泛型是元素原来的类型
//第二个泛型是元素转换后的类型
//apply方法中
//s表示每一个流中的数据
//返回值就代表集合中的键和值
Map<String, Integer> newMap = list.stream()
.collect(Collectors.toMap(
new Function<String, String>() {
@Override
public String apply(String s) {
return s.split("-")[0];
}
}
,
new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[1]);
}
}));
System.out.println(newMap);
//{李四=24, 张三=23, 王五=25, 张弓长=23}
//lambda表达式
list.stream()
.collect(Collectors.toMap(s -> s.split("-")[0],
s -> Integer.parseInt(s.split("-")[1])));
System.out.println(newMap);
//{李四=24, 张三=23, 王五=25, 张弓长=23}
}
}