stream流作用:
结合Lambda表达式,简化集合、数组操作
stream流使用步骤:
1、先获取Stream流(流水线),并把数据放上去
2、使用Stream流中的api进行各种操作
中间方法:过滤、打印 ===>方法调用完毕,还可以调用其它方法
终结方法:统计、打印 ===>最后一步,调用完毕,不能调用其他方法
stream流获取方式:
单列集合 | 使用Collection中默认方法 |
双列 | 集合无法直接使用stream流,先转换为entrySet,再使用流 |
数组 | Arrays工具类中静态方法 |
零散数据 | 只能打印引用数据类 |
/**
* 单列集合 default stream<E> stream() 使用Collection中默认的方法
*/
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list,10,20,30,40,50);
//1.获取stream流
Stream<Integer> stream = list.stream();
//2.使用中间方法处理流数据
//方式1:匿名内部类方式
stream.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
//3.使用终结方法结束stream流
System.out.println(integer);
}
});
//方式2:lambda方式
stream.forEach(s-> System.out.println(s));
/**
* 双列集合 无 无法直接使用stream流
*/
Map<String,Integer> students =new HashMap<String,Integer>();
students.put("小红",20);
students.put("小张",30);
students.put("小李",40);
//获取key的stream流
Set<String> set = students.keySet();
Stream<String> keys= set.stream();
//lambda方式,打印key
keys.forEach(key -> System.out.println(key));
//获取entrySet的stream流
Set<Map.Entry<String, Integer>> stus = students.entrySet();
//lambda方式,打印entrySet
stus.forEach(stu-> System.out.println(stu));
}
/**
* 数组 public static<T> Stream<T> stream(T[] array) Arrays工具类中的静态方法
*/
public static void main(String[] args) {
int[] arrs1={10,20,30,40,50,60};
//lambda遍历基本类型数组
Arrays.stream(arrs1).forEach(num -> System.out.println(num));
String[] arrs2={"10","20","30","40","50","60"};
//lambda遍历引用类型数组
Arrays.stream(arrs2).forEach(num -> System.out.println(num));
}
/**
* 一堆零散数据 public static<T> Stream<T> of(T...values) stream接口中静态方法
*/
int[] nums={10,20,30,40};
String[] strings={"10","20","30"};
//零散数据方式,只能打印引用类型数据,打印基本类型数据是整个对象地址
Stream.of(nums).forEach(num-> System.out.println(num));//打印[I@404b9385,无法正确预期打印结果,
Stream.of(strings).forEach(str-> System.out.println(str));
Stream流中间方法:
filter | 过滤 |
limit | 获取前几个元素 |
skip | 跳过前几个元素 |
distinct | 元素去重,依赖hashCode和equals方法 |
concat | Stream接口的静态方法,合并a和b两个流为一个流 |
map | 转换流中的数据类型 |
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList,"张三丰","张无忌","张三","李四","李天","王五");
//1、filter 过滤
arrayList.stream()//获取stream流
.filter(s -> s.length()==3 && s.startsWith("张"))//中间方法,设置条件,过滤流
.forEach(arr -> System.out.println(arr)); //终结方法,打印流
System.out.println("--------------------");
//2、limit 获取前几个元素
arrayList.stream()
.limit(3)
.forEach(arr-> System.out.println(arr));
System.out.println("--------------------");
//3、skip 跳过前几个元素
arrayList.stream()
.skip(3)
.forEach(arr -> System.out.println(arr));
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList,"张三丰","张三丰","张无忌","张无忌","张三","李四","李天","王五");
//1、distinct 元素去重,依赖hashCode和equals方法
arrayList.stream()
.distinct()
.forEach(arr-> System.out.println(arr));
System.out.println("--------------------");
//2、concat Stream流中的静态方法,合并a和b两个流为一个流
Stream.concat(
arrayList.stream(),arrayList.stream() //自动去重
);
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList,"张三丰-20","张无忌-30","张三-30","李四-40","李天-50","王五-25");
//map 转换流中的数据类型
//1、匿名内部类方式
arrayList.stream()
.map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
//将每个元素用"-"分割
String[] strings = s.split("-");
//取出年龄元素
String ageString = strings[1];
Integer age = Integer.valueOf(ageString);
return age;
}
}).forEach(arr -> System.out.println(arr));
//2、lambda方式
arrayList.stream() //获取流
.map(s ->"name:"+s.split("-")[0]+",value:"+s.split("-")[0]) //中间方法,处理流
.forEach(arr -> System.out.println(arr)); //终结方法,打印流
}
Stream流结束方法:
foreEach | 遍历 |
cout | 统计 |
toArray | 将流中的数据保存在数组中 |
/**
* 结束Stream流:forEach、count、toArray
*/
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList,"张三丰","张无忌","张三","李四","李天","王五");
//1、forEach
//方式1:匿名内部类
arrayList.stream().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//方式2:lambda方式
arrayList.forEach(s -> System.out.println(s));
//2、count
long length = arrayList.stream().count();
System.out.println(length);
//3、toArray 收集流中的数据放到数组中
Object[] objects = arrayList.stream().toArray();
System.out.println(Arrays.toString(objects));
//将string类型集合存放到,string类型数组中存储
//方式1:匿名内部类
String[] arr1 = arrayList.stream().toArray(new IntFunction<String[]>() {//泛型:存储数组的类型
@Override
public String[] apply(int value) {//返回类型:存储数组的类型 形参:集合长度
return new String[value]; //返回参数:集合长度数组
}
});
System.out.println(Arrays.toString(arr1));
//方式2:lambda方式
String[] arr2 = arrayList.stream().toArray((value) -> new String[value]);
System.out.println(Arrays.toString(arr2));
}
集合收集方法collect:
collect | 收集流中的数据,存放到集合中(List、Set、Map) 注:map集合中的键不能重复,否则会报错 |
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,
"张无忌-男-15","周芷若-女-14","赵敏-女-13",
"张强-男-20","张三丰-男-100","张翠山-男-40",
"张良-男-35","王二麻子-男-37","谢广坤-男-41");
//将男性,存入到List集合中(有序可重复)
List<String> list1 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
System.out.println(list1);
//将男性,存入到Set集合中(无序不重复)
Set<String> list2 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(list2);
//将男性,存入到Map集合中
//匿名内部类方式:
Map<String, Integer> map1 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(
Collectors.toMap(
//参数1:key的生成规则
new Function<String, String>() { //泛型1:流中每个数据的类型 泛型2:map集合中key的数值类型
@Override
public String apply(String s) {//形参:流中每个数据类型
return s.split("-")[0];//方法体:生成key的代码 返回值:生成的key
}
},
//参数2:value的生成规则
new Function<String, Integer>() { //泛型1:流中每个数据的类型 泛型2:map集合中value的数值类型
@Override
public Integer apply(String s) {//形参:流中每个数据类型
return Integer.valueOf(s.split("-")[2]);//方法体:生成value的代码 返回值:生成的value
}
}
));
System.out.println(map1);
//lambda方式:
Map<String, String> map2 =
list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(s -> s.split("-")[0], s -> s.split("-")[2]));
System.out.println(map2);
封装Stream流数据为JavaBean,并存入List集合中:
封装Bean过程:先使用map转换流分割数据,再封装到Bean中,最后转为List集合
ArrayList<String> womanList = new ArrayList<>();
ArrayList<String> manList = new ArrayList<>();
Collections.addAll(manList,"蔡坤坤,24","叶猴先,23","刘部天,22","吴倩,24","骨架,30","小萝莉,27");
Collections.addAll(womanList,"赵小应,24","杨颖,36","高圆圆,43","张甜甜,32","刘诗诗,35","杨小米,33");
//1、过滤出姓名长度为3的前两位男演员
Stream<String> manStream = manList.stream()
.filter(s -> s.split(",")[0].length() == 3)
.limit(2);
//2、过滤出跳过第1位为姓杨的女演员
Stream<String> womanStream = womanList.stream()
.filter(s -> s.split(",")[0].startsWith("杨"))
.skip(1);
//3、合并两个stream流
Stream<String> stream = Stream.concat(manStream, womanStream);
//4、将流中的数据封装成Actor对象,存入List集合中
List<Actor> actors =
stream.map(s -> new Actor( //使用map转换流,分隔字符串,并封装javaBean中
s.split(",")[0],
Integer.valueOf(s.split(",")[1]
)))
.collect(Collectors.toList());
for (Actor actor : actors) {
System.out.println(actor);
}
List<Actor> actors = //使用map转换流,分隔字符串,并封装javaBean中
stream.map(s ->
{
Actor actor = new Actor();
actor.setName(s.split(",")[0]);
actor.setAge(Integer.valueOf(s.split(",")[1]));
return actor;
}).collect(Collectors.toList());