
package Demo;
import java.util.ArrayList;
public class StreamDemo {
/*
需求:按照下面的要求完成集合的创建和遍历
1. 创建一个集合,存储多个字符串元素
2. 把集合中所有以"菜"开头的元素存储到一个新的集合
3. 把"菜"字开头的集合的长度为3的元素存储到一个新的集合
4. 遍历上一步得到的集合
*/
public static void main(String[] args) {
// 1. 创建一个集合,存储多个字符串元素
ArrayList<String> s = new ArrayList<String>();
s.add("菜xk");
s.add("菜徐琨");
s.add("菜鸡");
s.add("鸡你太美");
s.add("打篮球");
// 2. 把集合中所有以"菜"开头的元素存储到一个新的集合
ArrayList<String> s1 = new ArrayList<String>();
for (String ss1 : s) {
if (ss1.startsWith("菜")){
s1.add(ss1);
}
}
// System.out.print(s1);
// 3. 把"菜"字开头的集合的长度为3的元素存储到一个新的集合
ArrayList<String> s2 = new ArrayList<String>();
for (String ss2 : s1){
if (ss2.length()==3){
s2.add(ss2);
}
}
// 4. 遍历上一步得到的集合
for (String ss3 : s2){
System.out.println(ss3);
}
System.out.println("-------------------------------------------------");
//Stream流来改进
//s.stream().filter(ss ->ss.startsWith("菜")).filter(ss-> ss.length()==3).forEach(ss -> System.out.println(ss));
// ss -> System.out.println(ss)可以改进为System.out::println
s.stream().filter(ss -> ss.startsWith("菜")).filter(ss-> ss.length()==3).forEach(System.out::println);
// 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:生成流、过滤姓菜、过滤长度为3、逐一打印
}
}
输出内容为:
菜xk
菜徐琨
菜xk
菜徐琨
重点代码:
s.stream().filter(ss -> ss.startsWith(“菜”)).filter(ss-> ss.length()==3).forEach(System.out::println);

Collection体系的集合可以使用 默认方法stream() 生成流
default Stream stream()
Map体系的集合间接的生成流
数组可以通过Stream接口的 静态方法of(T…values) 生成流
Stream流的使用
package Demo;
import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Stream;
public class StreamDemo2 {
public static void main(String[] args) {
// Collection体系的集合可以使用默认方法stream()生成流 default Stream stream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();//list集合下生成的流
Set<String> set = new HashSet<>();
Stream<String> stream1 = set.stream();//set集合下生成的流
// Map体系的集合间接的生成流
Map<String, Integer> map = new HashMap<>();
//键的流
Set<String> strings = map.keySet();
Stream<String> stream2 = strings.stream();
//值得流
Collection<Integer> values = map.values();
Stream<Integer> stream3 = values.stream();
//键值对的流
Stream<Map.Entry<String, Integer>> stream4 = map.entrySet().stream();
// 数组可以通过Stream接口的静态方法of(T...values)生成流 注意:可变参数就是数组哦
int[] array = {8, 5, 6};
Stream<int[]> array1 = Stream.of(array);//数组流
}
}
| 方法名 | 方法说明 |
|---|---|
| Stream< T > filter(Predicate predicate);(Predicate接口中的方法 boolean test(T t)):对给定的参数进行判断,返回一个布尔值 | 用于对流中的数据进行过滤 |
| Stream< T > limit(long maxSize); | 返回此流中的元素组成的流,截取前指定参数个数的数据 |
| Stream< T > skip(long n); | 返回此流中的元素组成的流,截取前指定参数个数的数据,返回由该流的剩余元素组成的流 |
| static Stream< T > concat(Stream a,Stream b); | 合并a和b两个流为一个流 |
| static Stream< T > distinct(); | 返回由流中不同的元素(根据Object equals(Object))组成的流 |
| Stream< T >sorted(); | 返回由此流的元素组成的流,根据自然顺序排序 |
| Stream< T > sorted(Comparator comparator);(Comparator接口中的方法 int compare(T o1,T o2) ) | 返回由此流的元素组成的流,根据Comparator进行排序 |
| < R > Stream< R > map(Function mapper);Function接口中的方法 R apply(T t)//返回想要的类型 | 返回由给定函数应用于此流的元素的结果组成的流 |
| IntStream mapToInt(ToIntFunction mapper);(IntStream:表示原始的int流)ToIntFunction:接口中的方法 int applyAsInt(T value)//返回指定的类型int int sum()返回此流中元素的和 | 返回一个IntStream其中包含将给定函数应用于此流的元素的结果 |
| void forEach(Consumer action); | 对此流的每个元素执行操作 |
| long count(); | 返回此流中的元素数 |
需求:按照下面的要求完成集合的创建和遍历
package Demo;
import java.util.ArrayList;
import java.util.List;
public class StreamDemo3 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素
List<String> as = new ArrayList<>();
as.add("菜坤");
as.add("iKun");
as.add("鸡你太美");
as.add("菜菜");
as.add("打篮球");
as.add("时长两年半");
as.add("rap");
//需求1:取前3个数据在控制台输出
as.stream().limit(3).forEach(System.out::println);
System.out.println("------");
//需求2:跳过3个元素,把剩下的元素在控制台输出
as.stream().skip(3).forEach(s-> System.out.println(s));
System.out.println("------");
//需求3:跳过2个元素,把剩下的元素中前2个在控制台输出
as.stream().skip(2).limit(2).forEach(System.out::println);
}
}
输出的内容:
菜坤
iKun
鸡你太美
菜菜
打篮球
时长两年半
rap
鸡你太美
菜菜
创建一个集合,存储多个字符串元素
package Demo;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class StreamDemo4 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素
List<String> as = new ArrayList<>();
as.add("菜徐琨");
as.add("时长两年半");
as.add("唱跳rap");
as.add("打篮球");
as.add("鸡你太美");
//创建一个集合,存储多个字符串元素
Stream<String> s1 = as.stream().limit(4);
//需求2:跳过2个数据组成一个流
Stream<String> s2 = as.stream().skip(2);
//需求3:合并需求1和需求2得到的流.并把结果在控制台输出
// Stream.concat(s1,s2).forEach(s-> System.out.println(s))+;
//注意:当时用一个流完成终结操作后,那么这个流也就结束了,再次生成需要重新调用
//需求3:合并需求1和需求2得到的流,并且元素不能相同,并把结果在控制台输出
Stream.concat(s1,s2).distinct().forEach(System.out::println);
}
}
输出的内容:
菜徐琨
时长两年半
唱跳rap
打篮球
鸡你太美
创建一个集合,存储多个字符串元素
package Demo;
import java.util.ArrayList;
import java.util.List;
public class StreamDemo5 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素
List<String> as = new ArrayList<>();
as.add("cxk1");
as.add("bxaxk");
as.add("dxxk4");
as.add("axk3");
as.add("cxk2");
//需求1:存储多个字符串元素,按照字母顺序把数据在控制台输出
as.stream().sorted().forEach(s-> System.out.println(s));
System.out.println("---------------------------");
//需求2:按照字母长度把数据在控制台输出
as.stream().sorted((s1,s2)->
{
int num = s1.length()-s2.length();
int num2 = num==0?s1.compareTo(s2):num;
return num2;
}
).forEach(System.out::println);
}
}
输出的内容为:
axk3
bxaxk
cxk1
cxk2
dxxk4
axk3
cxk1
cxk2
bxaxk
dxxk4
package Demo;
import java.util.ArrayList;
import java.util.List;
/*
Stream map(Function mapper):返回由给定函数应用于此流的元素的结果组成的流
Function接口中的方法 R apply(T t)//返回想要的类型
IntStream mapToInt(ToIntFunction mapper):返回一个IntStream其中包含将给定函数应用于此流的元素的结果
IntStream:表示原始的int流
ToIntFunction:接口中的方法 int applyAsInt(T value)//返回指定的类型int int sum()返回此流中元素的和
*/
public class StreamDemo6 {
public static void main(String[] args) {
//创建一个集合,存储多个字符创元素
List<String> ls = new ArrayList<>();
ls.add("2000");
ls.add("3");
ls.add("1");
ls.add("18");
//需求:将集合中的字符串数据转换为整数之后在控制台输出
// ls.stream().map(i->Integer.valueOf(i)).forEach(i-> System.out.println(i));
ls.stream().map(Integer::valueOf).forEach(System.out::println);//方法的引用
System.out.println("------------------------------");
//需求:将集合中的字符串数据转换为特制的数据类型之后在控制台输出总和
int sum = ls.stream().mapToInt(s -> Integer.parseInt(s)).sum();
System.out.println(sum);
}
}
void forEach(Consumer action): 对此流的每个元素执行操作
consumer接口中的方法 void accept(T t): 给定的参数执行次操作
long count():返回此流中的元素数
package Demo;
import java.util.ArrayList;
public class StreamDemo7 {
public static void main(String[] args) {
/*
Stream流的常见终结操作方法
void forEach(Consumer action): 对此流的每个元素执行操作
consumer接口中的方法 void accept(T t): 给定的参数执行次操作
long count():返回此流中的元素数
*/
//创建一个集合,存储多个字符串元素
ArrayList<String> ss = new ArrayList<>();
ss.add("菜徐琨");
ss.add("菜头");
ss.add("小黑子");
ss.add("鸡你太美");
ss.add("时长两年半");
ss.add("爱打篮球");
//需求1:把集合的元素在控制台输出
// ss.stream().forEach(s-> System.out.println(s));
ss.stream().forEach(System.out::println);
System.out.println("-------------------");
//需求2:统计集合中有几个以"菜"开头的元素,并把统计结果在控制台输出
long cou = ss.stream().filter(sss -> sss.startsWith("菜")).count();
System.out.println("以\"菜\"开头的元素元素个数有"+cou+"个");
}
}
对数据使用Stream流的方式操作完毕后,我想把流中的数据收集到集合中,该怎么办呢?
Stream流的收集方法
| 方法名 | 方法说明 |
|---|---|
| R collect(Collector collector); | 但是这个收集方法的参数是一个Collector接口 |
工具类Collectors提供了具体的收集方式
| 方法名 | 方法说明 |
|---|---|
| public static < T > Collector toList(); | 把元素收集到List集合中 |
| public static < T > Collector toSet(); | 把元素收集到Set集合中 |
| public Collection toMap(Function keyMapper,Function valueMapper); | 把元素收集到Map集合中 |
package Demo;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamDemo9 {
public static void main(String[] args) {
//创建List集合对象
List<String> list = new ArrayList<String>();
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
//需求1:得到名字为3个字的流
Stream<String> stringStream = list.stream().filter(s -> s.length() == 3);
//需求2:把使用Stream流操作完毕的数据收集到List集合中并遍历
List<String> stringList = stringStream.collect(Collectors.toList());
for (String x:stringList){
System.out.println(x);
}
//创建Set集合对象
HashSet<Integer> set = new HashSet<>();
set.add(10);
set.add(20);
set.add(30);
set.add(33);
set.add(35);
//需求3:得到年龄大于25的流
Stream<Integer> integerStream = set.stream().filter(age -> age > 25);
//需求4:把使用Stream流操作完毕的数据收集到Set集合中并遍历
Set<Integer> integerSet = integerStream.collect(Collectors.toSet());
for (Integer x : integerSet){
System.out.println(x);
}
//定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成
String[] strArray={"林青霞,30","张曼玉,35","王祖贤,33","柳岩,25"};
//需求5:得到字符串中年龄数据大于28的流
Stream<String> stringStream1 = Stream.of(strArray).filter(s -> Integer.valueOf(s.split(",")[1]) > 28);
//需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,年龄作值
Map<String, String> map1 = stringStream1.collect(Collectors.toMap(key -> key.split(",")[0], (value -> value.split(",")[1])));
Set<String> strings = map1.keySet();
for (String key : strings) {
String s = map1.get(key);
System.out.println(key+" "+s);
}
}
}
输出的内容:
林青霞
张曼玉
王祖贤
33
35
30
林青霞 30
王祖贤 33
张曼玉 35
package Demo;
import java.util.ArrayList;
import java.util.stream.Stream;
//演员类Actor已经提供,里面有一个成员变量,一个构造方法,以及成员变量对应的get/set方法
class Actor{
private String name;
public Actor() {
}
public Actor(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class StreamDemo8 {
/*
现在有两个Arraylist集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
男演员只要名字为3个字的前三人
女演员只要姓坤的,并且不要第一个
把过滤后的男演员姓名和女演员姓名个并在一起
把上一步的操作后的元素作为构造方法的参数创建演员对象,遍历数据
演员类Actor已经提供,里面有一个成员变量,一个构造方法,以及成员变量对应的get/set方法
*/
public static void main(String[] args) {
//男
ArrayList<String> boys = new ArrayList<>();
boys.add("菜徐琨");
boys.add("喜羊羊");
boys.add("美羊羊");
boys.add("懒洋洋");
boys.add("沸羊羊");
boys.add("鸡你太美");
//女
ArrayList<String> girs = new ArrayList<>();
girs.add("坤坤1");
girs.add("坤坤2");
girs.add("坤坤3");
girs.add("坤坤4");
girs.add("坤坤5");
girs.add("坤坤6");
girs.add("坤坤7");
//男演员只要名字为3个字的前三人
Stream<String> boy1 = boys.stream().limit(3);
//女演员只要姓坤的,并且不要第一个
Stream<String> gir2 = girs.stream().skip(1);
//把过滤后的男演员姓名和女演员姓名个并在一起
Stream<String> co = Stream.concat(boy1, gir2);
//把上一步的操作后的元素作为构造方法的参数创建演员对象,遍历数据
co.map((Actor::new)).forEach(s-> System.out.println(s.getName()));
//(Actor::new) 相当于 Actor s -> return new Actor(s)
}
}
输入的内容:
菜徐琨
喜羊羊
美羊羊
坤坤2
坤坤3
坤坤4
坤坤5
坤坤6
坤坤7