1.1 Stream流
package Java36.Demo1;
import java.util.ArrayList;
import java.util.Iterator;
public class demo1 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<String>();
array.add("林青霞");
array.add("张曼玉");
array.add("王祖贤");
array.add("柳岩");
array.add("张敏");
array.add("张无忌");
//集合中以张开头的存储到新集合
ArrayList<String> zhangList = new ArrayList<String>();
for(String s:array){
if(s.startsWith("张")){
zhangList.add(s);
}
}
System.out.println(zhangList);
//张开头的集合中长度为3的元素存储到新集合
ArrayList<String> zhangsanList = new ArrayList<String>();
for (String s:zhangList){
if (s.length()==3){
zhangsanList.add(s);
}
}
System.out.println(zhangsanList);
//遍历集合
for(String s:zhangsanList){
System.out.println(s);
}
// Iterator<String> it = zhangsanList.iterator();
// while(it.hasNext()){
// String s = it.next();
// System.out.println(s);
// }
System.out.println("---------");
//Stream流改写
array.stream().filter(s->s.startsWith("张")).filter(s -> s.length()==3).forEach(s-> System.out.println(s));
}
}
使用Stream流完成过滤的代码
- array.stream().filter(s->s.startsWith(“张”)).filter(s -> s.length()==3).forEach(s-> System.out.println(s));
- 生成流,过滤姓张的,过滤长度为3,逐一打印
- Stream流是把真正的函数式编程风格引入到Java中
1.2 Stream流的生成方式
Stream流的使用
- 生成流
通过数据源(数组、集合等)生成流
如 array.Stream() - 中间操作
一个流后面可以跟随0个或多个中间操作,其目的主要是打开流,做出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个使用
如 filter() - 终结操作
一个流只能有一个终结操作,当这个操作被执行之后,流就无法被操作了
如 forEach()
Stream流常见的生成方式
- Collection体系的集合可以使用默认方法Stream()生成流
- Map体系的集合间接生成流
- 数组可以通过Stream接口的静态方法of(T…values)生成流
package Java36.Demo1;
import java.util.*;
import java.util.stream.Stream;
/*
- Collection体系的集合可以使用默认方法Stream()生成流
- Map体系的集合间接生成流
- 数组可以通过Stream接口的静态方法of(T...values)生成流
* */
public class demo3 {
public static void main(String[] args) {
//Collection体系的集合可以使用默认方法Stream()生成流
List<String> list = new ArrayList<String>();
Stream<String> listStream = list.stream();
Set<String> set = new HashSet<String>();
Stream<String> setStream = set.stream();
//Map体系的集合间接生成流
Map<String,Integer> map = new HashMap<String,Integer>();
Stream<String> keyStream = map.keySet().stream();//获得键的集合,再生成键的Stream流
Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String, Integer>> enteyStream = map.entrySet().stream();
//数组可以通过Stream接口的静态方法of(T...values)生成流
String[] strArray = {"hello","world","java"};
Stream<String> strArrayStream = Stream.of(strArray);
Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
}
}
1.3 Stream流的常见中间操作方法
- Stream filter(Predicate<? super T> predicate) :返回由与此给定谓词匹配的此流的元素组成的流。
package Java36.Demo1;
import java.util.ArrayList;
public class demo4 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<String>();
array.add("林青霞");
array.add("张曼玉");
array.add("王祖贤");
array.add("柳岩");
array.add("张敏");
array.add("张无忌");
array.stream().filter((String s)->{
return s.startsWith("张");
}).forEach(System.out::println);
System.out.println("--------------");
array.stream().filter(s->s.length()==3).forEach(s-> System.out.println(s));
System.out.println("---------------");
array.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s-> System.out.println(s));
}
}
- Stream limit(long maxSize) :返回由此流的元素组成的流,截短长度不能超过 maxSize
- Stream skip(long n) :跳过指定参数个数的数据,返回由该流的剩余元素组成的流
package Java36.Demo1;
import java.util.ArrayList;
public class demo5 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<String>();
array.add("林青霞");
array.add("张曼玉");
array.add("王祖贤");
array.add("柳岩");
array.add("张敏");
array.add("张无忌");
//取前三个元素输出
array.stream().limit(3).forEach(s-> System.out.println(s));
//跳过3个元素,把剩下的元素在控制台输出
array.stream().skip(3).forEach(s-> System.out.println(s));
//跳过两个元素,把剩下的元素中的前2个在控制台输出
array.stream().skip(2).limit(2).forEach(s-> System.out.println(s));
}
}
- static Stream concat(Stream<? extends T> a, Stream<? extends T> b) :创建一个连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。
- Stream distinct() :返回由该流的不同元素(根据 Object.equals(Object) )组成的流。
package Java36.Demo1;
import java.util.ArrayList;
import java.util.stream.Stream;
/*
- static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) :创建一个连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。
- Stream<T> distinct() :返回由该流的不同元素(根据 Object.equals(Object) )组成的流。
* */
public class demo6 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<String>();
array.add("林青霞");
array.add("张曼玉");
array.add("王祖贤");
array.add("柳岩");
array.add("张敏");
array.add("张无忌");
//取前四个数据组成一个流
Stream<String> s1 = array.stream().limit(4);
//跳过两个数据组成一个流
Stream<String> s2 = array.stream().skip(2);
//合并前两个流,并输出
// Stream.concat(s1,s2).forEach(System.out::println);
//合并前两个需求,并输出不重复的字符串元素
Stream.concat(s1,s2).distinct().forEach(System.out::println);
}
}
- Stream sorted() :返回由此流的元素组成的流,根据自然顺序排序。
- Stream sorted(Comparator<? super T> comparator) :返回由该流的元素组成的流,根据提供的 Comparator进行排序。
package Java36.Demo1;
import java.util.ArrayList;
import java.util.Comparator;
/*
- Stream<T> sorted() :返回由此流的元素组成的流,根据自然顺序排序。
- Stream<T> sorted(Comparator<? super T> comparator) :返回由该流的元素组成的流,根据提供的 Comparator进行排序。
* */
public class demo7 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<String>();
array.add("linqingxia");
array.add("zhangmanyu");
array.add("wangzuxian");
array.add("liuyan");
array.add("zhangmin");
array.add("zhangwuji");
//按照字母顺序将数据在控制台输出
array.stream().sorted().forEach(s-> System.out.println(s));
System.out.println("----------------");
//按照字符串长度把数据在控制台输出
//Comparator接口也是只有一个抽象方法,因此可使用Lambda表达式
// array.stream().sorted(new Comparator<String>() {
// @Override
// public int compare(String s1, String s2) {
// return s1.length()-s2.length();
// }
// }).forEach(s-> System.out.println(s));
// array.stream().sorted((s1,s2)->s1.length()-s2.length()).forEach(s-> System.out.println(s));
array.stream().sorted((s1,s2)->{
int num1 = s1.length()-s2.length();
int num2 = num1 == 0?s1.compareTo(s2):num1;
return num2;
}).forEach(s-> System.out.println(s));
}
}
- Stream map(Function<? super T,? extends R> mapper) :返回由给定函数应用于此流的元素的结果组成的流。
- IntStream mapToInt(ToIntFunction<? super T> mapper) :返回一个 IntStream ,其中包含将给定函数应用于此流的元素的结果。
package Java36.Demo1;
import java.util.ArrayList;
public class demo89 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<String>();
array.add("10");
array.add("20");
array.add("30");
array.add("40");
array.add("50");
array.add("60");
//将集合中的字符串数据转换为整数之后在控制台输出
array.stream().map(s ->Integer.parseInt(s)).forEach(System.out::println);
array.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
//int sum()
//返回此流中元素的总和。
int result = array.stream().mapToInt(Integer::parseInt).sum();
System.out.println(result);
}
}
1.4 Stream流的常见终结操作方法
Stream流常见的终结操作方法:
- void forEach(Consumer<? super T> action) :对此流的每个元素执行操作。
- long count() :返回此流中的元素数。
package Java36.Demo1;
import java.util.ArrayList;
public class demo9 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<String>();
array.add("林青霞");
array.add("张曼玉");
array.add("王祖贤");
array.add("柳岩");
array.add("张敏");
array.add("张无忌");
//把集合中的元素在控制台输出
array.stream().forEach(System.out::println);
//统计以张开头的元素,并把统计结果在控制台输出
long count = array.stream().filter(s -> s.startsWith("张")).count();
System.out.println(count);
}
}
Stream流的练习:
package Java36.Demo1;
import java.util.ArrayList;
import java.util.stream.Stream;
public class demo10 {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<String>();
list1.add("周润发");
list1.add("成龙");
list1.add("刘德华");
list1.add("吴京");
list1.add("周星驰");
list1.add("李连杰");
ArrayList<String> list2 = new ArrayList<String>();
list2.add("林心如");
list2.add("张曼玉");
list2.add("林青霞");
list2.add("柳岩");
list2.add("林志玲");
list2.add("王祖贤");
//男演员只要名字为三个字的前三人
Stream<String> stream1 = list1.stream().filter(s -> s.length() == 3).limit(3);
//女演员只要姓林的且不要第一个
Stream<String> stream2 = list2.stream().filter(s -> s.startsWith("林")).skip(1);
//把过滤后的男演员和女演员姓名合并到一起
Stream<String> stream = Stream.concat(stream1, stream2);
//把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
// stream.map(Actor::new).forEach(System.out::println);
stream.map(Actor::new).forEach(p-> System.out.println(p.getName()));
}
}
Stream的收集操作
- <R,A> R collect(Collector collector)
- 这个收集方法的参数时一个Collector接口
工具类Collectors提供了具体的收集方式
- static Collector toList() :把元素收集到List集合中 。
- static Collector toSet() :把元素收集到Set集合中 。
- static Collector toMap(Function keyMapper, Function valueMapper) :把元素收集到Map中。
package Java36.Demo1;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class demo11 {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<String>();
array.add("林青霞");
array.add("张曼玉");
array.add("王祖贤");
array.add("柳岩");
array.add("张敏");
array.add("张无忌");
//得到名字为3个字的流
Stream<String> stream1 = array.stream().filter(s -> s.length() == 3);
//使用Stream流把数据收集到List集合中并遍历
List<String> names = stream1.collect(Collectors.toList());
for (String n:names){
System.out.println(n);
}
//创建Set集合对象
Set<Integer> set = new HashSet<Integer>();
set.add(10);
set.add(20);
set.add(30);
set.add(40);
set.add(50);
set.add(60);
//得到大于30的流
Stream<Integer> stream2 = set.stream().filter(age -> age > 30);
//遍历set集合中的对象
Set<Integer> ages = stream2.collect(Collectors.toSet());
for (Integer age:ages){
System.out.println(age);
}
//定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组成
String[] strArrays = {"林青霞,30","张曼玉,35","王祖贤,33","柳岩,25"};
//得到年龄大于28的流
Stream<String> arraystream = Stream.of(strArrays).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);
//使用Stream流操作完毕的数据收集到Map集合,姓名为键,年龄为值
Map<String, Integer> map = arraystream.collect(Collectors.toMap(s -> s.split(",")[0],s -> Integer.parseInt(s.split(",")[1])));
//遍历map集合
Set<String> keySet = map.keySet();
for (String key:keySet){
Integer value = map.get(key);
System.out.println(key+","+value);
}
}
}