案例需求
按照下面的要求完成集合的创建和遍历
创建一个集合,存储多个字符串元素
把集合中所有以"张"开头的元素存储到一个新的集合
把"张"开头的集合中的长度为3的元素存储到一个新的集合
遍历上一步得到的集合
原始方式示例代码
package com.itheima.streamdemo;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
/*
* 创建一个集合,存储多个字符串元素
"张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"
把集合中所有以"张"开头的元素存储到一个新的集合
把"张"开头的集合中的长度为3的元素存储到一个新的集合
遍历上一步得到的集合
*
* */
public class MyStream1 {
public static void main(String[] args) {
ArrayList
ArrayList
//遍历list1把张开头的元素添加到list2中。
for (String s : list1) {
if (s.startsWith("张")) {
list2.add(s);
}
}
//遍历list2集合,把其中长度为3的元素,再添加到list3中,
ArrayList
for (String s : list2) {
if (s.length() == 3) {
list3.add(s);
}
}
for (String s : list3) {
System.out.println(s);
}
//Stream流
list1.stream().filter(s -> s.startsWith("张"))
.filter(s -> s.length()==3)
.forEach(s -> System.out.println(s));
}
}
Stream流的好处
直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
Stream流把真正的函数式编程风格引入到Java中
代码简洁
Stream流的三类方法
获取Stream流
中间方法
流水线上的操作
一次操作完毕之后,还可以继续进行其他操作
终结方法
一个Stream流只能有一个终结方法
是流水线上的最后一个操作
生成Stream流的方式
Collection体系集合 单列集合
使用默认方法stream()生成流, default Stream
Map体系集合 双列集合
把Map转成Set集合,间接的生成流、 可以先通过keySet或者entrySet获取一个Set集合,在获取Stream流
数组
通过Arrays中的静态方法stream生成流
同种数据类型的多个数据
通过Stream接口的静态方法of(T… values)生成流
1,2,3,4,5…….
"aaa","bbb","ccc"……
使用Stream.of(T…values)生成流
package com.itheima.streamdemo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Stream;
/*
* Stream流的获取
* 单列集合:集合对象.Stream();
* 双列集合:不能直接获取,需要间接获取
* 集合对象.keySet().stream();
* 集合对象.entrySet.stream();
*数组:Arrays.stream(数组名);
* 同种数据类型的多个数据:Stream.of(数据1,数据2,数据3.。。。。)
*
* */
public class MyStream2 {
public static void main(String[] args) {
//单列集合
//method1();
//双列集合
//method2();
//数组
//method3();
//同种数据类型的多个数据
method4();
}
public static void method4() {
Stream.of(1,2,3,4,5,6,7,8).forEach(s-> System.out.println(s));
}
public static void method3() {
int \[\]arr={1,2,3,4,5};
Arrays.stream(arr).forEach(s-> System.out.println(s));
}
public static void method2() {
HashMap<String,Integer> hm=new HashMap<>();
hm.put("zhangsan",23);
hm.put("lisi",24);
hm.put("wangwu",25);
hm.put("zhaoliu",26);
hm.put("qianqi",27);
//双列集合不能直接获取Streatm流
//KeySet
//先获取到所有的键
//再把这个Set集合中所有的键放到Stream流中
hm.keySet().stream().forEach(s -> System.out.println(s));
//entrySet
//先获取到所有的键值对对象
//再把这个Set集合中所有的键值对对象放到Stream流中
hm.entrySet().stream().forEach(s-> System.out.println(s));
}
public static void method1() {
ArrayList<String> list=new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
// Stream
// stream.forEach(s -> System.out.println(s));
list.stream().forEach(s -> System.out.println(s));
}
}
概念
中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作
常见方法
方法名
说明
Stream
用于对流中的数据进行过滤
Stream
返回此流中的元素组成的流,截取前指定参数个数的数据
Stream
跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static
合并a和b两个流为一个流
Stream
返回由该流的不同元素(根据Object.equals(Object) )组成的流
filter代码演示
Stream
用于对流中的数据进行过滤
Predicate接口中的方法
boolean test(T t):对给定的参数进行判断,返回一个布尔值
package com.itheima.streamdemo;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class MyStream3 {
public static void main(String[] args) {
ArrayList
//filter方法获取流中的每一个数据
//而test方法中的s,就依次表示流中的每一个数据
//我们只要在test方法中对s进行判断就可以了,
//如果判断的结果为true,则当前的数据留下
//如果判断的结果为false,则当前的数据就不要
// list.stream().filter(
// new Predicate
// @Override
// public boolean test(String s) {
// boolean result = s.startsWith("张");
// return result;
// }
// }
// ).forEach(s -> System.out.println(s));
//因为Predicate接口中只有一个抽象方法test
//所以我们能使用lambda表达式来简化
// list.stream().filter(
// (String s) -> {
// boolean result = s.startsWith("张");
// return result;
// }
// ).forEach(s -> System.out.println(s));
list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));
}
}
limit&skip&concat&distinct代码演示
package com.itheima.streamdemo;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class MyStream4 {
public static void main(String[] args) {
ArrayList
//Stream
//list.stream().limit(2).forEach(s -> System.out.println(s));
//Stream
//list.stream().skip(2).forEach(s -> System.out.println(s));
//static
ArrayList
// Stream
// Stream
// Stream
// stream3.forEach(s -> System.out.println(s));
//Stream.concat(list.stream(),list2.stream()).forEach(s -> System.out.println(s));
//Stream
list.stream().distinct().forEach(s -> System.out.println(s));
}
}
概念
终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作
常见方法
方法名
说明
void forEach(Consumer action)
对此流的每个元素执行操作
long count()
返回此流中的元素数
代码演示
void forEach(Consumer action)
对此流的每个元素执行操作
Consumer接口中的方法 void accept(T t):对给定的参数执行此操作
package com.itheima.streamdemo;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class MyStream5 {
public static void main(String[] args) {
ArrayList
//void forEach(Consumer action)对此流的每个元素执行操作
//Consumer接口中的方法 void accept(T t):对给定的参数执行此操作
//method1(list);
// long count()返回此流中的元素数
long count = list.stream().count();
System.out.println(count);
}
public static void method1(ArrayList<String> list) {
//在forEach方法的底层 ,会循环获取到流中的每一个数据
//并循环调用accept方法,并把每一个数据传递给accept方法
//s就依次表示了流中的每一个数据
//所以,我们只要在accept方法中,写上处理的业务逻辑就可以了
list.stream().forEach(
new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
}
);
//lambda表达式的简化格式
//是因为Consumer接口中,只有一个accept方法
list.stream().forEach(s -> System.out.println(s));
}
}
需求:过滤元素并遍历集合
定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
将集合中的奇数删除,只保留偶数
遍历集合得到2,4,6,8,10
package com.itheima.streamdemo;
import java.util.ArrayList;
import java.util.List;
/*
*需求:过滤元素并遍历集合
定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
将集合中的奇数删除,只保留偶数
遍历集合得到2,4,6,8,10
*
*
* */
public class MyStream6 {
public static void main(String[] args) {
ArrayList
for (int i = 1; i <= 10; i++) {
list.add(i);
}
list.stream().filter(number -> number%2==0).forEach(number-> System.out.println(number));
System.out.println("==============");
for (Integer integer : list) {
System.out.println(integer);
}
}
}
使用Stream流的方式操作完毕之后,我想把流中的数据保存起来,该怎么办
概念
对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中
常用方法
方法名
说明
R collect(Collector collector)
把结果收集到集合中
工具类Collectors提供了具体的收集方式
方法名
说明
public static
把元素收集到List集合中
public static
把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper)
把元素收集到Map集合中
代码演示
收集到list和set单列集合中
package com.itheima.streamdemo;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/*
*需求:过滤元素并遍历集合
定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
将集合中的奇数删除,只保留偶数
遍历集合得到2,4,6,8,10
*
*
* */
public class MyStream7 {
public static void main(String[] args) {
ArrayList
for (int i = 1; i <= 10; i++) {
list.add(i);
}
list.add(10);
list.add(10);
list.add(10);
list.add(10);
list.add(10);
//filter负责过滤数据的
//collect负责收集数据,
//获取流中剩余数据,但是他不负责创建容器,也不负责把数据添加到容器中
//Collectors.toList():在底层创建一个List集合,并把所有数据添加到List集合中
List
.collect(Collectors.toList());
System.out.println(list1);
Set<Integer> set = list.stream().filter(number -> number % 2 == 0)
.collect(Collectors.toSet());
System.out.println(set);
}
}
收集到双列集合中
练习:
创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
”zhangsan“,23
”lisi“,24
”wangwu“,25
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
public static Collector toMap(Function keyMap,Function valueMapper):把元素收集到Map集合中
package com.itheima.streamdemo;
import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;
/*
* 创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
”zhangsan“,23
”lisi“,24
”wangwu“,25
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
*
* */
public class MyStream8 {
public static void main(String[] args) {
ArrayList
list.add("zhangsan,23");
list.add("lisi,24");
list.add("wangwu,25");
Map<String, Integer> map = list.stream().filter(
s -> {
String\[\] split = s.split(",");
int age = Integer.parseInt(split\[1\]);
return age >= 24;
}
//collection方法只能获取到流中剩余的每一个数据
//在底层不能创建容器,也不能把数据添加到容器当中
//Collectors.toMap 创建一个集合,并将数据添加到集合当中
//s依次表示流中的每一个数据
//第一个lambda表达式就是如何获取到map中的键
//第二个lambda表达式就是如何获取到map中的值
).collect(Collectors.toMap(
s -> s.split(",")\[0\],
s -> Integer.parseInt(s.split(",")\[1\])));
System.out.println(map);
}
}
案例需求
现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
男演员只要名字为3个字的前两人
女演员只要姓杨的,并且不要第一个
把过滤后的男演员姓名和女演员姓名合并到一起
把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
代码实现
演员类
package com.itheima.streamdemo;
public class Actor {
private String name;
public Actor() {
}
public Actor(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Actor{" +
"name='" + name + '\\'' +
'}';
}
}
测试类
package com.itheima.streamdemo;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.stream.Stream;
/**
* 现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
* 1.男演员只要名字为3个字的前两人
* 2.女演员只要姓杨的,并且不要第一个
* 3.把过滤后的男演员姓名和女演员姓名合并到一起
* 4.把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
* 演员类Actor,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
*/
public class MyStream9 {
public static void main(String[] args) {
ArrayList
manList.add("张国立");
manList.add("张晋");
manList.add("刘烨");
manList.add("郑伊健");
manList.add("徐峥");
manList.add("王宝强");
ArrayList<String> womanList = new ArrayList<>();
womanList.add("郑爽");
womanList.add("杨紫");
womanList.add("关晓彤");
womanList.add("张天爱");
womanList.add("杨幂");
womanList.add("赵丽颖");
//男演员只要名字为3个字的前两个人
Stream<String> stream1=manList.stream().filter(name -> name.length() == 3).limit(2);
//女演员只要姓杨的,并且不要第一个
Stream<String> stream2=womanList.stream().filter(name-> name.startsWith("杨")).skip(1);
Stream.concat(stream1,stream2).forEach(name->{
Actor actor = new Actor(name);
System.out.println(actor);
});
}
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章