目录
初识Stream流
在Java中,Stream流是一种用于处理集合类(如List、Set和Map)中元素的工具。Stream API 引入于 Java 8,它允许我们以声明式的方式进行数据操作。使用 Stream API 可以使代码更简洁、更易读,同时利用并行处理来提升性能。
Stream流的使用步骤
Stream流的使用步骤如下
1. 先获取一条Stream流(流水线),并把数据放上去;
2. 使用中间方法对流水线上的数据进行操作;
3. 使用终结方法对流水线上的数据进行操作。
获取Stream流
如下表所示不同数据类型获取Stream流的方式各不相同。
单列集合获取Stream流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c", "d", "e");
// 获取流水线,并打印元素
list.stream().forEach(e -> System.out.printf(e));//abcde
双列集合获取Stream流
双列集合可以通过两种方式获取Stream流
1. 通过hm.keySet().stream()获取集合中所有的键的stream流;
2. 通过hm.entrySet().stream()获取集合中所有键值对的stream流。、
代码示例
HashMap<String, Integer> hm = new HashMap<>();
hm.put("aaa", 111);
hm.put("bbb", 222);
hm.put("ccc", 333);
hm.put("ddd", 444);
//第1种获取stream流的方法:获取集合中的所有键
hm.keySet().stream().forEach(e-> System.out.println(e));
/*
aaa
ccc
bbb
ddd
*/
//第2种获取stream的流方法:获取集合中的所有键值对
hm.entrySet().stream().forEach(e-> System.out.println(e));
/*
aaa=111
ccc=333
bbb=222
ddd=444
*/
数组获取Stream流
数组可以通过两种方式获取Stream流
1. 通过Arrays.stream(arr)方法获取Stream流;
2. 通过Stream.of(arr)方法获取Stream流,因为该方法的形参是不可变参数,因此可以传入数组类型。但弊端在于,传入数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,放到Stream流当中,因此并不建议使用该方法获取数组的Stream流。
示例代码
int[] arr = {1, 2, 3};
String[] strings = {"a", "b", "c"};
// 1.通过Arrays.stream()获取stream流
Arrays.stream(arr).forEach(e -> System.out.println(e));
/*
1
2
3
*/
// 2.通过Stream.of()获取stream流(不建议使用)
Stream.of(arr).forEach(e-> System.out.println(e)); //[I@3b9a45b3
Stream.of(strings).forEach(e -> System.out.println(e));
/*
a
b
c
*/
零散数据获取Stream流
零散数据可以通过Stream.of()的方式获取stream流,但是需要保证传入的数据类型都是相同的。
Stream.of("a", "b", "c").forEach(e -> System.out.println(e));
/*
a
b
c
*/
Stream.of(1,2,3).forEach(e-> System.out.println(e));
/*
1
2
3
*/
Stream流的中间方法
Stream<T> filter(Predicate<? super T> predicate) // 过滤
Stream<T> limit(long maxSize) // 获取前几个元素
Stream<T> skip(long n) // 跳过前几个元素
Stream<T> distinct() // 元素去重,依赖(hashCode和equals方法)
static<T>Stream<T>concat(Stream a,Stream b) // 合并a和b两个流为一个流
Stream<R> map(Function<T ,R> mapper) // 转换流中的数据类型
注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
filter
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "张三", "张三丰", "赵敏", "张良", "李四");
//filter:过滤 需求:留下以张开头的字符串
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
//如果返回值为true,表示留下当前数据
//如果返回值为false,表示舍弃当前数据
return s.startsWith("张");
}
}).forEach(e -> System.out.println(e));
//链式编程:留下以张开头且长度为3的字符串
list.stream().filter(s -> s.startsWith("张"))
.filter(s -> s.length() == 3)
.forEach(e -> System.out.println(e));
Stream<String> stream1 = list.stream();
Stream<String> stream2 = stream1.filter(s -> s.startsWith("张"));
Stream<String> stream3 = stream1.filter(s -> s.length() == 3);//报错:stream1已经被使用过一次,不可再次被使用
limit、skip
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "张三", "张三丰", "赵敏", "张良", "李四");
//获取前3个数据
list.stream().limit(3).forEach(e-> System.out.printf(e+" "));//张无忌 周芷若 张三
//跳过前4个数据
list.stream().skip(4).forEach(e-> System.out.printf(e+" "));//赵敏 张良 李四
distinct
注意:distinct底层依赖hashCode和equals两个方法对集合中的元素进行去重,如果集合中的元素类型是自定义类,则需要重写这两个方法。
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张三", "张三", "张三", "张三", "赵敏", "张良", "李四");
list.stream().distinct().forEach(e-> System.out.printf(e+" "));//张三 赵敏 张良 李四
concat
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1, "张三", "张三");
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2, "李四", "李四");
Stream.concat(list1.stream(),list2.stream()).forEach(e-> System.out.printf(e+" ")); //张三 张三 李四 李四
map
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-12", "赵敏-22", "张良-8", "李四-26");
//需求:获取字符串的数字部分
//Function<E, T>,E代表元素原来的类型,T代表元素转换后的类型
//需要保证apply返回值类型与T相同
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
//将字符串进行分割
String[] arr = s.split("-");
//取出字符串的年龄部分
String ageString = arr[1];
int age = Integer.parseInt(ageString);
return age;
}
}).forEach(e-> System.out.println(e));
//Lambda简化
list.stream().map(s->Integer.parseInt(s.split("-")[1]))
.forEach(e-> System.out.println(e));
Stream流的终结方法
void forEach(Consumer action) //遍历
long count() //统计
toArray() //收集流中的数据,放到数组中
collect(Collector collector) //收集流中的数据,放到集合中(List,Set,Map)
toArray
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "赵敏", "张良", "周芷若");
//转换成Object类型的数组
Object[] objects = list.stream().toArray();
//转换成指定类型的数组
String[] strings1 = list.stream().toArray(new IntFunction<String[]>() {
@Override
//value表示的是stream流中元素的个数
public String[] apply(int value) {
return new String[value];
}
});
//Lambda简化
String[] strings2 = list.stream().toArray(value -> new String[value]);
collect
通过collect方法将Stream流转换为List、Set集合,代码如下
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-男-12", "张无忌-男-12", "赵敏-女-19", "张三丰-男-25", "周芷若-女-22", "张良-男-28", "谢广坤-男-30");
//将性别为"男"的元素搜集到List集合中,元素不去重
List<String> newList = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
//将性别为"男"的元素搜集到Set集合中,元素去重
Set<String> newSet = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
通过collect方法将Stream流转换为Map集合,注意需要保证键的唯一性,代码如下
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-男-12", "赵敏-女-19", "张三丰-男-25", "周芷若-女-22", "张良-男-28", "谢广坤-男-30");
//将性别为"男"的元素搜集到Set集合中,规定键为姓名,值为年龄
Map<String, Integer> collect = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
/*
*
* toMap: 参数1表示键的生成规则
* 参数2表示值的生成规则
*
* 参数1:
* Function<流中每一个数据的类型,Map集合中键的数据类型>(){
* public Map集合中键的数据类型 apply(流中每一个数据的类型 s){
* 生成键的代码
* 返回键;
* }
* }
*
*
*参数2:
* Function<流中每一个数据的类型,Map集合中值的数据类型>(){
* public Map集合中值的数据类型 apply(流中每一个数据的类型 s){
* 生成值的代码
* 返回值;
* }
* }
*
* */
.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.valueOf(s.split("-")[2]);
}
}));
//Lambda表达式简化
Map<String, Integer> collect1 = list.stream()
.collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.valueOf(s.split("-")[2])));
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » Java—Stream流
发表评论 取消回复