1.Stream流
1.1体验Stream流
需求:创建一个集合,存储多个字符串元素
把集合中所有以“张”开头的何元素存储在到一个新的集合
把“张”开头的集合中长度为3的元素存储到一个新的集合
遍历上一步的到的集合
public class StreamDemo {
public static void main(String[] args) {
ArrayList
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//把“张”开头的集合中长度为3的元素存储到一个新的集合
ArrayList
for (String s : list) {
if(s.startsWith("张") && s.length()==3){
arrayList.add(s);
System.out.println(s);
}
}
System.out.println("---------------");
//使用流Stream来改进
//list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(System.out::println);
}
}
使用Stream流的方式完成过滤操作
list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(System.out::println);
直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:生成流,过滤姓张,过滤长度为3,逐一打印
Stream流把真正的函数式编程风格引入到java中
1.2Stream流的生成方式
Stream流的使用
通过数据源(集合,数组等)生成流
list.stream()
中间操作
一个流后面可以跟随零个或多个中间操作,其目的主要是打开流,做出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个操作使用
filter()
终结操作
一个流只能有一个中介操作,当这个操作执行后,流就被使用“光了”,无法再被操作。所以这必定是流的最后一个操作
forEach()
Stream流的常见的生成方式
Collection体系的集合可以使用默认方法stream()生成流:default Stream
Map体系的集合间接的生成流
数组可以通过Stream接口的静态方法of(T...values)生成流
public class StreamDemo1 {
public static void main(String[] args) {
ArrayList
Stream
HashSet
Stream
HashMap
Stream
Stream
Stream
//数组可以通过Stream接口的静态方法of(T...value)生成流
String[] strArray = {"hello","jacy","afsif"};
Stream
Stream
Stream
Stream
}
}
1.3Stream流的常见中间操作方法
Stream
predicate 接口中的方法 boolean test(T t):对给定的参数进行判断,返回一个布尔值
Stream
Stream
Stream
Stream
Stream
Function接口中的方法 Rapply(T t)
InStream mapToLn(ToIntFunction mapper):返回一个InStream其中包含给定函数应用于此流的元素的结果
Instream:表示原始int流
ToInFunction接口中的方法 int applyAsInt(T value)
public class StreamDemo2 {
public static void main(String[] args) {
//创建一个集合,存储多个字符串元素
ArrayList
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:把list集合中以张开头的元素在控制台输出
list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
System.out.println("----------------------");
//需求2:把list集合中长度为3的元素在控制台输出
list.stream().filter(s->s.length()==3).forEach(System.out::println);
System.out.println("----------------------");
//需求:把list集合中以张开头的,长度为3的元素在控制台输出
list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(System.out::println);
}
}
public class StreamDemo3 {
public static void main(String[] args) {
ArrayList
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:取前三个数据在控制台输出
list.stream().limit(3).forEach(System.out::println);
System.out.println("--------------------------");
//需求:跳过3个元素,把剩下的与三俗在控制台输出
list.stream().skip(3).forEach(System.out::println);
System.out.println("--------------------------");
//需求3:跳过2个元素,把剩下的元素中2个在控制台输出
list.stream().skip(2).limit(3).forEach(System.out::println);
}
}
public class StreamDemo4 {
public static void main(String[] args) {
ArrayList
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求:取前四个数据组成一个流
Stream
//stream.forEach(System.out::println);使用这个虽然会可以输出,但是会导致流关闭,下面就不可以使用concat(),会报错
//System.out.println("-------------------");
//需求:跳过两个数据组成一个流
Stream
//stream1.forEach(System.out::println);使用这个虽然会可以输出,但是会导致流关闭,下面就不可以使用concat(),会报错
//System.out.println("-------------------");
//需求:合并需求1和需求2得到的流,并把结果在控制台输出
//list.stream().limit(4).skip(2).forEach(System.out::println);
//Stream.concat(stream,stream1).forEach(System.out::println);
//System.out.println("-----------------------");
//需求4:合并需求1和需求2得到的流,并把结果在控制台输出,,要求字符串元素不能重复
Stream.concat(stream,stream1).distinct().forEach(System.out::println);//foreach有关流的作用
}
}
public class StreamDemo5 {
public static void main(String[] args) {
ArrayList
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:按照字母顺序把数据在控制台输出
list.stream().sorted().forEach(System.out::println);
System.out.println("--------------------------");
//需求2:按照字符串长度把数据在控制台输出
list.stream().sorted((s1,s2)->{
int num = s1.length()-s2.length();
int num2 = num == 0?s1.compareTo(s2):num;
return num2;
}).forEach(System.out::println);
}
}
public class StreamDemo6 {
public static void main(String[] args) {
ArrayList
list.add("10");
list.add("20");
list.add("30");
list.add("40");
list.add("50");
list.add("60");
//需求1:将集合中的字符串数据转换为整数之后在控制台输出
//list.stream().map(s->Integer.parseInt(s)).forEach(System.out::println);
//list.stream().map(Integer::parseInt).forEach(System.out::println);
//list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
//int sum()返回此流中元素的总和
int sum = list.stream().mapToInt(Integer::parseInt).sum();
System.out.println(sum);
}
}
1.4Stream流的常见终结操作方法
Stream流的常见终结方法
void foreach(Consumer action):对此流的每个元素执行操作
Consumer接口中的方法 void accept(T t):对给定的参数执行此操作
long count():返回此流中的元素数
public class StreamDemo7 {
public static void main(String[] args) {
ArrayList
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
list.add("张无忌");
//需求1:把集合中的元素在控制台输出
list.stream().forEach(System.out::println);
//需求2:统计集合中有几个以张开头的元素,并把统计结果在控制台输出
long count = list.stream().filter(s -> s.startsWith("张")).count();
System.out.println(count);
}
}
1.5Stream流的练习
现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作:男演员只要名字为3个字的前三个人
女演员只要姓林的,并且不要第一个
把过滤后的男演员姓名和女演员姓名合并到一起
把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
public class StreamDemo8 {
public static void main(String[] args) {
ArrayList
manList.add("周润发");
manList.add("成龙");
manList.add("刘德华");
manList.add("吴京");
manList.add("周星驰");
manList.add("李连杰");
ArrayList
womanList.add("林心如");
womanList.add("张曼玉");
womanList.add("林青霞");
womanList.add("柳岩");
womanList.add("林志玲");
womanList.add("王祖贤");
//需求1:男演员只要名字为3个字的前三人
Stream
//需求2:女演员只要姓林的,并且不要第一个
Stream
//需求3:把过滤后的男演员姓名和女演员姓名合并到一起
Stream
//需求4: 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
//stream.map(Actor::new).forEach(System.out::println);
//stream.map(Actor::new).forEach(s-> System.out.println(s.getName()));
//把所有的流都链接在一起
Stream.concat(manList.stream().filter(s -> s.length() == 3).limit(3),
womanList.stream().filter(s -> s.startsWith("林")).skip(1)).map(Actor::new)
.forEach(s-> System.out.println(s.getName()));
}
}
1.6Stream流的手机操作
对数据使用Stream流的方式操作完毕后,我想把流中的数据书籍到集合中,该怎么办?
Stream流的收集方法
R collect(Collector collect)
但是这个收集方法的参数是一个Collector接口
工具类Collector提供了具体的收集方式
public static
public static
public static
public class StreamDemo9 {
public static void main(String[] args) {
ArrayList
list.add("林青霞");
list.add("张曼玉");
list.add("王祖贤");
list.add("柳岩");
list.add("张敏");
//需求1:得到名字3个字的流
Stream
//需求2:把使用Stream流操作完毕的数据存储收集到list集合中并且遍历
List
for (String name : names) {
System.out.println(name);
}
System.out.println("--------------------------");
//需求3:创建set集合
HashSet
set.add(10);
set.add(20);
set.add(30);
set.add(40);
set.add(50);
//需求4:得到年龄大于25的流
Stream
//需求5:把使用流操作完毕的数据收集到set集合中遍历
Set
for (Integer age : setAges) {
System.out.println(age);
}
//需求6:定义一个字符串数组,每一个字符串数组由姓名数据和年龄数据组成
String[] strArray = {"林青霞,30","张曼玉,35","王祖贤4,5","柳岩,25"};
//需求7:得到字符串中年龄数据大于28的数据
Stream
//需求8:把使用Stream流操作完毕的数据收集到map集合中遍历,字符串中的姓名做键,年龄做值
Map
for (String key : map.keySet()) {
String value = map.get(key);
System.out.println(key+":"+value);
}
}
}



