Stream流
相当于把数据源加载到一条流水线上,即 在一条传输管道中对数据进行操作,
26.1 获取Stream流
获取方式 | 方法名 | 说明 |
---|---|---|
单列集合 | default Stream stream() | Collection中的默认方法 |
双列集合 | 无 | 无法直接使用stream流 |
public static Stream stream(T[] array) | Arrays工具类中的静态方法 | |
一堆零散数据 | public static Stream of(T… values) | Stream接口中的静态方法 |
双列集合 无Stream流 无法直接使用stream流
需要先把双列集合中数据转换成单列集合的数据
Stream流作用:结合Lambda表达式,简化集合、数组的操作。
import java.util.ArrayList;
import java.util.Collections;
public class Test {
public static void main(String[] args) {
//单列集合==default Stream<E> stream() == Collection中的默认方法
// 创建单列集合
ArrayList<String> list = new ArrayList<>();
// 添加元素给集合
Collections.addAll(list,"a","b","c");
// // 1.获取Stream流
// Stream<String> stream1 = list.stream();
// // 循环打印Stream流的每个元素
// stream1.forEach(new Consumer<String>() {
// @Override
// public void accept(String s) {
// s:依次表示流水线上的每一个数据
// System.out.println(s);
// }
// });
// 2.获取Stream流并循环打印每个元素
list.stream().forEach(s -> System.out.print(s+" "));
//a b c
}
}
import java.util.HashMap;
public class Test02 {
public static void main(String[] args) {
//双列集合 无Stream流 无法直接使用stream流
// 需要先把双列集合中数据转换成单列集合的数据
// 创建集合
HashMap<String,Integer> map = new HashMap<>();
// 添加数据
map.put("a",1);
map.put("b",2);
map.put("c",3);
// 1.获取双列集合中所有的键,并放入单例集合中
// 通过存放键的单例集合获取Stream流
map.keySet().stream().forEach(s -> System.out.println(s));
// a b c
// 2.获取键值对 ,并放入单列集合中
//通过存放键值对的单列集合获取Stream流
//Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();
// stream.forEach(s-> System.out.println(s));
map.entrySet().stream().forEach(s-> System.out.println(s));
//a=1 b=2 c=3
}
}
import java.util.Arrays;
public class Test03 {
public static void main(String[] args) {
//数组 public static <T> Stream<T> stream(T[] array) Arrays工具类中的静态方法
int[] arr1 = {1,2,3};
String[] arr2 = {"你","好"};
Arrays.stream(arr1).forEach(s-> System.out.println(s));
// 1 2 3
Arrays.stream(arr2).forEach(s -> System.out.println(s));
//你 好
// Stream接口中静态方法of的细节
//方法的形参是一个可变参数,可以传递一堆零散数据,也可以传覅地数组
//但是数组必须是引用数据类型
//如果是基本数据类型,会把整个数组当作一个元素,放到Stream中
Stream.of(arr1).forEach(s-> System.out.println(s));
//[I@7ba4f24f
Stream.of(arr2).forEach(s-> System.out.println(s));
//你 好
}
}
import java.util.stream.Stream;
public class Test04 {
public static void main(String[] args) {
//一堆零散数据 public static<T> Stream<T> of(T... values) Stream接口中的静态方法
Stream.of(1,2,3).forEach(s-> System.out.println(s));
Stream.of("a","b").forEach(s-> System.out.println(s));
}
}
26.2 Stream流中间方法
方法名 | 说明 |
---|---|
Stream filter(Predicate<? super T> predicate) | 过滤 |
Stream limit(long maxSize) | 获取前几个元素 |
Stream skip(long n) | 跳过前几个元素 |
Stream distinct() | 元素去重,依赖(hashCode和equals方法) |
static Stream concat(Stream a,Stream b) | 合并a和b两个流为一个流 |
Stream map(Function<super T, R> mapper) | 转换流中的数据类型 |
1.中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
2.修改Stream流中的数据,不会影响原来集合或者数组中的数据
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
//1.中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
// 2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
// 创建集合
ArrayList<String> list = new ArrayList<>();
ArrayList<String> list1 = new ArrayList<>();
// 给集合添加元素
Collections.addAll(list,"水果","水瓶","苹果","苹果");
Collections.addAll(list1,"葡萄","西瓜");
//1.filter 过滤
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
// true:留下当前元素;
// false:当前元素舍弃
return s.startsWith("水");
}
}).forEach(s-> System.out.println(s));//水果 水瓶
list.stream().filter(s -> s.startsWith("水")).forEach(s -> System.out.println(s));
//水果 水瓶
//注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,
// 建议使用链式编程
// Stream<String> stream1 = list.stream().filter(s -> s.startsWith("水"));
// Stream<String> stream2 = stream1.filter(s -> s.length() == 1);
// stream1.filter(s -> s.length()==2);//此行运行时异常
System.out.println();
// 2.limit 获取前几个元素
list.stream().limit(1).forEach(s -> System.out.println(s));
//水果
//3. skip 跳过前几个元素
list.stream().skip(2).forEach(s -> System.out.println(s));
//苹果
// 4.distinct 元素去重,依赖(hashCode和equals方法)
//distinct底层是利用HashSet去重的
list.stream().distinct().forEach(s->System.out.println(s)); //水果 水瓶 苹果
// 5.concat 合并a和b两个流为一个流
Stream.concat(list.stream(),list1.stream()) .forEach(s -> System.out.println(s));
//水果 水瓶 苹果 葡萄 西瓜
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
public class Test02 {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 给集合添加元素
Collections.addAll(list,"水果-1","水瓶-2","苹果-3");
// map 转换流中的数据类型
// 将String -> Integer
//apply的形参s:依次表示流里面的每一个数据
//返回值:表示转换之后的数据
//当map方法执行完毕之后,流上的数据就变成了整数
//所以在下面forEach当中,s依次表示流里面的每一个数据,
//这个数据现在就是整数了
//第一个类型:流中原本的数据类型
//第二个类型:要转成之后的类型
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String[] arr = s.split("-");
String numString = arr[1];
int i = Integer.parseInt(numString);
return i;
}
}).forEach(s-> System.out.println(s));//1 2 3
// 简化写法
// map里的s表示流里的每一个数据:"水果-1","水瓶-2","苹果-3"
// s.split("-"):表示一个数组:如:[水果, 1]....
//s.split("-")[1]:数组里的第二个元素,类型为字符串
list.stream()
.map(s -> Integer.parseInt(s.split("-")[1]))
.forEach(s-> System.out.println(s));
}
}
26.3 Stream流终结方法(一)
方法名 | 说明 |
---|---|
void forEach(Consumer action) | 遍历 |
long count() | 统计 |
toArray() | 收集流中的数据,放到数组中 |
collection(Collection collection) | 收集流中数据,放到集合中 |
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.IntFunction;
public class Test03 {
public static void main(String[] args) {
// 创建集合
ArrayList<String> list = new ArrayList<>();
// 给集合添加元素
Collections.addAll(list,"水果-1","水瓶-2","苹果-3");
// 1.遍历
//Consumer的泛型:表示流中数据的类型
//accept方法的形参s:依次表示流里面的每一个数据
//方法体:对每一个数据的处理操作(打印)
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
list.forEach(s -> System.out.println(s));
// 2.统计
long count = list.stream().count();
System.out.println(count);//3
// 3.收集
Object[] obj = list.stream().toArray();
String s = Arrays.toString(obj);
System.out.println(s);//[水果-1, 水瓶-2, 苹果-3]
//IntFunction的泛型:具体类型的数组
//apply的形参:流中数据的个数,要跟数组的长度保持一致
//apply的返回值:具体类型的数组
//方法体:就是创建数组
//toArray方法的参数的作用:负责创建一个指定类型的数组
//toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
//toArray方法的返回值:是一个装着流里面所有数据的数组
String[] strArr = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(strArr));
//[水果-1, 水瓶-2, 苹果-3]
}
}
26.4 Stream流终结方法(二)
collect(Collector collector) 收集流中的数据,放到集合中 (List Set Map)
如果我们要收集到Map集合当中,键不能重复,否则会报错
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Test04 {
public static void main(String[] args) {
// 创建集合并添加数据
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张三-男-18","李四-男-19","小红-女-19");
//收集List集合当中
//需求:把所有的男性收集起来
List<String> newlist1 = list.stream()
//过滤性别为男的
.filter(s -> "男".equals(s.split("-")[1]))
// 收集过滤后性别为男的,并放入一个和集合中
.collect(Collectors.toList());
// 打印集合
System.out.println(newlist1);//[张三-男-18, 李四-男-19]
//收集Set集合当中
//需求:我要把所有的男性收集起来
Set<String> newlist2 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(newlist2);
// 收集到Map集合中
//谁作为键,谁作为值.
//所有的男性收集起来
//键:姓名。 值:年龄
Map<String, Integer> map = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
/*
* toMap : 参数一表示键的生成规则
* 参数二表示值的生成规则
*
* 参数一:
* Function泛型一:表示流中每一个数据的类型
* 泛型二:表示Map集合中键的数据类型
*
* 方法apply形参:依次表示流里面的每一个数据
* 方法体:生成键的代码
* 返回值:已经生成的键
*
* 参数二:
* Function泛型一:表示流中每一个数据的类型
* 泛型二:表示Map集合中值的数据类型
*
* 方法apply形参:依次表示流里面的每一个数据
* 方法体:生成值的代码
* 返回值:已经生成的值
* */
.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("-")[2]);
}
}
));
System.out.println(map);//{李四=19, 张三=18}
// 简写
Map<String, String> map1 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(
s -> s.split("-")[0],
s -> s.split("-")[2]
));
System.out.println(map1);//{李四=19, 张三=18}
// main ending.....
}
}