Stream流
初识Stream流
Stream流把真正的函数式编程风格引入到java中 案例:需求: 创建集合,存储多个字符串元素;把集合中“张”开头的字符串存储到另外的集合中;把“张”开头的集合中的长度大于3的元素存储到另外集合中;遍历上一步得到的集合。
public class StreamDemo {
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> zhang = new ArrayList<String>();
for(String s:array){
if(s.startsWith("张")){
zhang.add(s);
}
}
System.out.println( "zhang集合:"+zhang);
ArrayList<String> zhang3 = new ArrayList<String>();
for(String s :zhang){
if(s.length() == 3){
zhang3.add(s);
}
}
System.out.println("zhang3集合:" + zhang3);
System.out.println("-----------");
array.stream().filter(s->s.startsWith("张")).filter(s-> s.length() == 3).forEach(s-> System.out.println(s));
* 注意:
* 意思:array.stream生成流、过滤张、过滤长度为3、forEach逐一打印
System.out.println("简化");
array.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==3).forEach(System.out::println);
}
}
Stream流的生成方式
Stream的使用:
1 生成流
通过数据源(集合、数组等)生成流
list.stream()
2 中间操作
一个流后面可以跟随零个或多个中间操作,其目的主要是打开流,做出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个操作使用。
filter()
3 终结操作
一个流只能有一个终结操作,当这个操作执行后,流就被使用“光”了,无法再被操作。
forEach()
Stream流的常见生成方式:
1 Collection体系的集合可以使用默认方法stream()生成流
default Stream< E > stream()
2 Map 体系的集合间接的生成流
可以使用方法keySet方法、values方法、entrySet方法
3 数组可以通过Stream接口的静态方法of(T...values)生成流
其中静态方法of(T....values)是可变参数。
* Stream.of(T...values)
代码:
public class StreamDemo1 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
Stream<String> listStream = list.stream();
Set<String> set = new HashSet<String>();
Stream<String> setStream = set.stream();
Map<String,Integer> map = new HashMap<String, Integer>();
Stream<String> keyStrem = map.keySet().stream();
Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String, Integer>> kvStream = map.entrySet().stream();
String[] strArray = {"you","are","my","pretty","sunshine"};
Stream<String> strArray1 = Stream.of(strArray);
Stream<String> strStream2 = Stream.of("hello", "world");
Stream<Integer> integerStream = Stream.of(10, 20, 30);
}
}
Stream流的中间操作方式
中间操作方法:
方法名 | 说明 |
---|
Stream < T > filter(Predicate predicate) | 用于对流中的数据进行过滤 Predicate接口中的方法,boolean test(T t):对给定的参数进行操作,返回一个布尔值 | Stream< T > limit(long maxSize) | 返回此流中的元素组成的流,截取前指定参数个数的数据 | Stream< T > skip(long n) | 跳过指定参数个数的数据,返回由该流的剩余元素组成的流 | static < T > Stream < T > concat(Stream a,Stream b) | 合并a和b两个流为一个流 | Stream< T > distinct() | 返回由该流的不同元素(Object.equals(Object))组成的流 | Stream< T > sorted() | 返回由此流的元素组成的流,根据自然顺序排序 | Stream< T > sorted(Comparator comparator | 返回由该留的元素组成的流,根据提供的Comparator进行排序 Comparator接口中的方法 int compare(T o1,T o2) | < R > Stream < R > map(Function mapper) | 返回由给定函数应用于此流的元素的结果组成的流 Function接口中的方法 R apply(T t) | IntStream mapToInt(ToIntFunction mapper) | 返回一个IntStream,其中包含将给定函数应用于此流的元素的结果 IntStream 表示原始int流ToIntFunction接口中的方法 int applyAsInt(T value) 其中IntStream接口中有方法int sum() 返回此流中元素的总和 |
案例1:filter
public class StreamDemo2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("林俊杰");
list.add("张信哲");
list.add("王一博");
list.add("胡夏");
list.add("张杰");
list.add("张艺兴");
list.stream().filter((String s) -> s.startsWith("张")).forEach((String s)-> System.out.println(s));
list.stream().filter(s->s.startsWith("张")).forEach(System.out::println);
System.out.println("-----------------");
list.stream().filter(s->s.length() == 3).forEach(System.out::println);
System.out.println("------");
list.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(System.out::println);
}
}
案例2:limit skip
public class StreamDemo3 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("林俊杰");
list.add("张信哲");
list.add("王一博");
list.add("胡夏");
list.add("张杰");
list.add("张艺兴");
list.stream().limit(3).forEach(System.out::println);
System.out.println("-------");
list.stream().skip(3).forEach(System.out::println);
System.out.println("-----");
list.stream().skip(2).limit(2).forEach(System.out::println);
}
}
案例3:dictinct concat
public class StreamDemo4 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("林俊杰");
list.add("张信哲");
list.add("王一博");
list.add("胡夏");
list.add("张杰");
list.add("张艺兴");
Stream<String> s1 = list.stream().limit(4);
Stream<String> s2 = list.stream().skip(2);
System.out.println("---------");
Stream.concat(s1, s2).distinct().forEach(System.out::println);
}
}
案例4:sorted
public class StreamDemo5 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("linqingxia");
list.add("zhangmanyu");
list.add("wangzuxian");
list.add("liuyan");
list.add("zhangmin");
list.add("zhagnwuji");
list.stream().sorted((s1,s2)->{
int sum = s1.length()-s2.length();
int sum2 = sum == 0?s1.compareTo(s2):sum;
return sum2;
}).forEach(System.out::println);
}
}
案例5:map mapToInt
public class StreamDemo6 {
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");
int result = array.stream().mapToInt(Integer::parseInt).sum();
System.out.println(result);
}
}
Stream流的常见终结操作方法
方法名 | 说明 |
---|
viod forEach(Consumer action) | 对此流的每个元素执行操作 Consumer接口中的方法 void accept(T t)对给定的参数执行此操作 | long count() | 返回此流中的元素个数 |
案例:
public class StreamDemo7 {
public static void main(String[] args) {
ArrayList<String> list= new ArrayList<String>();
list.add("林俊杰");
list.add("张信哲");
list.add("王一博");
list.add("刘维");
list.add("张杰");
list.add("张艺兴");
long result = list.stream().filter(s -> s.startsWith("张")).count();
System.out.println(result);
}
}
Stream流练习
需求: 有两个ArrayList集合,分别存储6名男演员和6名女演员名称,完成如下操作: 1 男演员只要名字为三个字的前三个人 2 女演员只要姓林的,并且不要第一个人 3 把过滤后的男演员名字和女演员名字合并在一起 4 把上一个步操作后的元素作为构造方法的参数创建演员对象,遍历数据 演员类Actor,有一个成员变量,一个带参构造方法,以为其对应的get/set方法
public class StreamDemo {
public static void main(String[] args) {
ArrayList<String> manList = new ArrayList<String>();
manList.add("周润发");
manList.add("成龙");
manList.add("刘德华");
manList.add("吴京");
manList.add("周星驰");
manList.add("李连杰");
ArrayList<String> womanList = new ArrayList<String>();
womanList.add("林心如");
womanList.add("张嘉倪");
womanList.add("林黛玉");
womanList.add("柳岩");
womanList.add("林志玲");
womanList.add("王祖贤");
Stream<String> manStream = manList.stream().filter(s->s.length() ==3).limit(3);
Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);
Stream<String> conStream = Stream.concat(manStream, womanStream);
conStream.map(Actor::new).forEach(p-> System.out.println(p.getName()));
}
}
Stream流的收集操作
- 对数据使用Stream流的方式后,把流中的数据收集到集合中,收集方法是:R collect(Collector collector)
- 参数Collector 是一个接口interface,interface Collector< T,A,R >
- 工具类Collectors类实现了各种有用的还原操作的Collector
- Collector类提供了具体的收集方法:
方法名 | 说明 |
---|
public static < T > Collector toList() | 把元素收集到List集合中 | public static < T > Collector toSet() | 把元素收集到Set集合中 | public static < T > Collector toMap(Function keyMapper,Function valueMapper) | 把元素收集到Map集合中 |
案例:
public class test7 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("林俊杰");
list.add("张信哲");
list.add("王一博");
list.add("刘维");
Set<Integer> set = new HashSet<Integer>();
set.add(10);
set.add(20);
set.add(30);
set.add(33);
set.add(35);
String[] strArray = {"林俊杰,30","张信哲,35","王一博,33","刘维,25"};
Stream<String> ageStream = Stream.of(strArray).filter(s ->
Integer.parseInt(s.split(",")[1]) >28 );
Map<String,Integer> map = ageStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
Set<String> keySet = map.keySet();
for(String key:keySet){
Integer value = map.get(key);
System.out.println("姓名:" + value + ", " + "年龄:" + key);
}
}
}
|