Stream流的用法:
public class Mystream1 {
public static void main(String[] args) {
//集合的批量添加
List<String> list = new ArrayList<String>();
list.add("张三丰");
list.add("张无忌");
list.add("周芷若");
list.add("乔峰");
list.add("李明远");
list.add("张一");
//保留张开头的,过滤掉长度是3的
//只有list集合有流
list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
}
}
运行结果:![](https://img-blog.csdnimg.cn/f12fccafeb1945d28b6ab38222dd634d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6JC95ZCO5bCx6KaB5oyo5omT,size_20,color_FFFFFF,t_70,g_se,x_16)
Stream流的思想
- 就是一条流水线。
- 获取方法-中间方法-终结方法
Stream流的三类方法
- 获取Stream流
创建一条流水线,并把数据放到流水线上准备进行操作。
- 中间方法
流水线上的操作。
一次操作完毕之后,还可以继续进行其他操作。
- 终结方法
一个Stream流只能有一个终结方法,是流水线上的最后一个方法。
Stream流的获取方法
- 单列集合
可以使用Collection接口中的默认方法stream()生成流、
private static void method1() {
//单列集合
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//展示流的数据方法-forEach
list.stream().forEach(s -> System.out.println(s) );
}
}
- 双列集合
间接的生成流,可以先通过keySet或者entrySet获取一个Set集合,再获取Stream流。
private static void method2() {
HashMap<String,Integer> hm = new HashMap<>();
hm.put("zhangsan",23);
hm.put("lisi",24);
hm.put("wangwu",25);
hm.put("zhaoliu",23);
hm.put("hou",28);
hm.put("shi",29);
//双列集合不能直接获取stream流,通过keySet,entrySet间接获取流
//keySet,先获取到所有的键
//再把这个set集合中所有的键放到Stream中
hm.keySet().stream().forEach(s -> System.out.println(s));
//entrySet,先获取到所有的键值对对象
//再把这个Set集合中所有的键值对对象放到stream流中。
hm.entrySet().stream().forEach(s -> System.out.println(s));
}
- 数组
Arrays中的静态方法stream生成流。
//怎么用数组调用到流,并展示出来
private static void method3() {
int[] arr ={1,7,3,2,9};
Arrays.stream(arr).forEach(s -> System.out.println(s));
}
- 同种数据累类型的多个数据
1,2,3,4,5....
"aaa","bbb","ccc",...
使用Stream.of(T...value)生成流。
private static void method4() {
Stream.of(1,2,3,4,5,6,7,9,8).forEach(s-> System.out.println(s));
}
package com.itheima.myreflect2.Student.sreatmdemo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Stream;
/**
* @program: Myset
* @description: 创建Stream流的几种方式
* @author: xuejingjing
* @create: 2021-06-12 23:33
**/
public class Mystream2 {
public static void main(String[] args) {
//单列集合
// method1();
//双列集合
method2();
//数组
method3();
//同种数据类型的多个数据
method4();
}
private static void method4() {
Stream.of(1,2,3,4,5,6,7,9,8).forEach(s-> System.out.print(s));
}
//怎么用数组调用到流,并展示出来
private static void method3() {
int[] arr ={1,7,3,2,9};
Arrays.stream(arr).forEach(s -> System.out.print(s+" "));
}
//怎么用Map调用到流并展示出来
private static void method2() {
HashMap<String,Integer> hm = new HashMap<>();
hm.put("zhangsan",23);
hm.put("lisi",24);
hm.put("wangwu",25);
hm.put("zhaoliu",23);
hm.put("hou",28);
hm.put("shi",29);
//双列集合不能直接获取stream流,通过keySet,entrySet间接获取流
//keySet,先获取到所有的键
//再把这个set集合中所有的键放到Stream中
hm.keySet().stream().forEach(s -> System.out.println(s));
//entrySet,先获取到所有的键值对对象
//再把这个Set集合中所有的键值对对象放到stream流中。
hm.entrySet().stream().forEach(s -> System.out.println(s));
}
//怎么用单列集合list调用到流并展示出来
private static void method1() {
//单列集合
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//展示流的数据方法-forEach
list.stream().forEach(s -> System.out.println(s) );
}
}
Stream流中常见的中间方法:
public class Mystream3 {
//stream<T> filter(perdicate predicate):过滤
//predicate接口中的方法 boolean test(T t):对给定的参数的进行判断,返回一个boolean值
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张三边");
list.add("张接电话");
list.add("经济的好坏");
list.add("张电脑手机");
list.add("大家都不");
list.add("四百九十九");
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
//仅仅是过滤,还需显示看下是否过滤成功
boolean isResult = s.startsWith("张");
return isResult;
}
}).forEach(ss-> System.out.println(ss));
结果:
分别用匿名内部类,lambal表达式,lambal最简化的方式 ,提高代码简洁性:
public class Mystream3 {
//stream<T> filter(perdicate predicate):过滤
//predicate接口中的方法 boolean test(T t):对给定的参数的进行判断,返回一个boolean值
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张三边");
list.add("张接电话");
list.add("经济的好坏");
list.add("张电脑手机");
list.add("大家都不");
list.add("四百九十九");
//先获取一个Stream流
//filter方法获取流中的每一个数据
//而test方法中的s,就依次表示流中的每一个数据,
//我们只要在test方法中对s进行判断就可以额,
//如果判断的结果为true,则当前的数据留下
//如果判断的结果为false,则当前数据就不要。
//filter方法获取流中的每一个数据
//test方法中的s,就依次表示流中的每一个数据。
//我们只要在test方法中对s进行判断就可以了。
//如果判断的结果是true,则当前的数据留下。
//如果判断的结果是false,则当前的数据就不要、
/**
* 1.匿名内部类的写法
* 可以用lambal表达式简化。
* 可以转化的条件是:接口中只有一个抽象方法
*/
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
//仅仅是过滤,还需显示看下是否过滤成功
boolean isResult = s.startsWith("张");
return isResult;
}
}).forEach(ss-> System.out.println(ss));
System.out.println("=======================");
//因为Predicate接口中只有一个抽象方法test,所以我们可以使用lamdba表达式来简化
list.stream().filter(
(String s)->{ boolean isResult = s.startsWith("张");
return isResult;
}).forEach(s-> System.out.println(s));
//如果lambal中的形参只有一个,那么形参类型可以省略
//如果lambal中的方法体只有一行,那么return ;{}都可以省略
System.out.println("=======================");
list.stream().filter((s)->s.startsWith("张")).forEach(s-> System.out.println(s));
注意:
s表示流中的每一个数据;过滤条件;
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张三边");
list.add("张接电话");
list.add("经济的好坏");
list.add("张电脑手机");
list.add("大家都不");
list.add("四百九十九");
// Stream<T> limit (long maxSize);截取指定参数个数的数据
list.stream().limit(2).forEach(s -> System.out.println(s));
public class Mystream4 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张三边");
list.add("张接电话");
list.add("经济的好坏");
list.add("张电脑手机");
list.add("大家都不");
list.add("四百九十九");
list.add("张无忌");
ArrayList<String> listAnother = new ArrayList<>();
list.add("新港东路");
list.add("环市东路");
list.add("东风东路");
list.add("赤岗北路");
list.add("越秀南路");
list.add("一德路");
list.add("中山大道");
// Stream<T> limit (long maxSize);截取指定参数个数的数据
list.stream().limit(2).forEach(s -> System.out.println(s));
System.out.println("====================================");
//stream<T> skip(long n);//跳过指定参数个数的数据
list.stream().skip(2).forEach(s-> System.out.println(s));
//static<T> stream<T> concat(Stream a ,Stream b) //合并a,b两个流为一个流
System.out.println("======================================");
// Stream.concat(list.stream(),listAnother.stream()).forEach(s-> System.out.println(s));
//stream<T> distinct() ;去除流中重复的元素,依赖(Hashcode和equals方法)
System.out.println("======================================");
list.stream().distinct().forEach(s-> System.out.println(s));
}
}
Stream流中常见的终结方法:
/**
* @program: Myset
* @description: stream流常用的终结方法
* @author: xuejingjing
* @create: 2021-06-13 00:49
**/
public class Mystream5 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张三边");
list.add("张接电话");
list.add("经济的好坏");
list.add("张电脑手机");
list.add("大家都不");
list.add("四百九十九");
list.add("四百九十九");
//new Consumer为什么会出现覆盖的方法?
// list.stream().forEach(new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);
// }
// });
// list.stream().forEach((s)-> System.out.println(s)});
//void forEach(consumer action);对此流的每一个元素执行操作
//consumer接口中的方法 void accept(T t);//对给定的参数执行此操作
//在forEach方法的底层,他会循环获取到流中的每一个数据,
//并循环调用accept方法,并把每一个数据传递给accept方法
//s就一次表示流中的每一个数据,所以,我们只要在accept方法中,协商处理的业务逻辑就可以了。
list.stream().forEach(
new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
}
);
System.out.println("=========================");
//lambda表达式的简化格式
//是因为Consumer接口中,只有一个抽象accept方法
list.stream().forEach(
(String s)->{
System.out.println(s);
}
);
System.out.println("=========================");
//lambda表达式还是可以进一步简化的
list.stream().forEach(s-> System.out.println(s));
//返回此流中的元素数
long count = list.stream().count();
System.out.println(count);
}
}
Stream流-不能直接修改数据源中的数据,(Demo如下)
/**
* @program: Myset
* @description: stream流的收集方法
* 结论:在stream流中无法直接修改集合,数组等数据源中的数据。
* * 练习:
* * 定义一个集合,并添加一些证书1,2,3,4,5,6,7,8,9,10
* * 将集合中的奇数删除,只保留偶数
* * 遍历集合得到2,4,6,8,10
* @author: xuejingjing
* @create: 2021-12-17 02:50
**/
public class Mystream7 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
//过滤条件
list.stream().filter((integer)->integer.intValue() % 2 == 0).forEach(s-> System.out.println(s));
System.out.println("==============================================");
list.stream().filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
if (integer.intValue() % 2 == 0) {
return true;
} else {
return false;
}
}
}).forEach(s -> {
System.out.println(s);
});
for (Integer integer : list) {
System.out.print(integer);
}
}
}
Stream流的收集方法
public class Mystream6 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
list.add(10);
list.add(10);
list.add(10);
//过滤条件
// list.stream().filter((integer) -> integer.intValue() % 2 == 0).forEach(s -> System.out.println(s));
//filter负责过滤数据
//collect负责收集数据
//Collection.toList()在底层会创建一个List集合,并把所有的数据添加到List集合中。
List<Integer> listCollection = list.stream().filter((integer) -> integer.intValue() % 2 == 0).collect(Collectors.toList());
System.out.println(listCollection);
Set<Integer> set = list.stream().filter((per) -> per.intValue() % 2 == 0).collect(Collectors.toSet());
System.out.println(set);
}
}
/**
* @program: Myset
* @description: 收集方法-toMap
* @author: xuejingjing
* @create: 2021-12-17 03:22
**/
public class Mystream8 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("zhangsan,22");
list.add("lisi,23");
list.add("wangwu,24");
list.add("hong,25");
list.add("zhu,26");
list.add("li,27");
Map<String, Integer> map = list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
String[] split = s.split(",");
String s1 = split[1];
if (Integer.parseInt(s1) >= 24) {
return true;
} else {
return false;
}
}
}).collect(
Collectors.toMap((String s) -> {
return s.split(",")[0];
}, (String s) -> {
return Integer.parseInt(s.split(",")[1]);
}));
System.out.println(map);
}
}