打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
java8Stream

Stream

介绍

java8添加了一个抽象流Stream,可以让我们像写sql一样操作集合元素。Stream将要处理的元素看做是一种流, 在管道中传输,并进行处理,最后由终止操作得到处理的结果。

什么是Stream?

Stream是一个来自特定元素队列并支持聚合操作

  • 元素是具体类型的对象,形成一个队列。
  • 数据源是流的来源。
  • 聚合操作是类似sql一样的操作,比如filter, map, reduce, find, match, sorted等。
  • Stream自己不会存储元素。
  • Stream不会改变源对象。
  • Stream操作是延迟执行的。

创建流

串行流

stream():即单线程的方式去操作流

并行流

parallelStream():即多线程方式去操作流

@Test	public void test() {		//1通过Collection提供的stream()和parallelStream()方法		List<String> list = Arrays.asList("a","b","c");		Stream<String> stream1 = list.stream();		Stream<String> stream2 = list.parallelStream();				//2通过Arrays的静态方法stream()		String[] strs= {"a","b","c"};		Stream<String> stream3 = Arrays.stream(strs);				//3通过Stream类中的静态方法of()		Stream<String> stream4 = Stream.of("a","b","c");				//4通过Stream类的iterate方法生成无限流		Stream<Integer> stream5 = Stream.iterate(0, (x)->x+1);				//5通过Stream的generate方法生成无限流		Stream.generate(()->Math.random());			}

中间操作

过滤

使用 filter(Predicate<? super T> predicate)来按照一定规则对流中元素进行过滤

@Test	public void test() {		List<Integer> list = Arrays.asList(1,2,3,4,5);		Stream<Integer> stream = list.stream();		stream = stream.filter((x)->x.compareTo(2)>0);				stream.forEach(System.out::println);	}输出:345@Test	public void test2() {		List<Integer> list = Arrays.asList(1,2,3,4,5);		Stream<Integer> stream = list.stream();		stream = stream.filter(				(x)->{			System.out.println(x);			return x.compareTo(2)>0;}			);	}结果:没有任何输出,这也就是前面说的Stream操作是延迟执行的,只有当终止操作这些中间操作才会依次执行

截断

使元素的个数不超过指定的数目

@Test	public void test() {		List<Integer> list = Arrays.asList(1,2,3,4,5);		Stream<Integer> stream = list.stream();		stream=stream.limit(3);		stream.forEach(System.out::println);	}输出:123可以看到只输出了给定个元素

跳过元素

跳过流中前几个元素

@Test	public void test4() {		List<Integer> list = Arrays.asList(1,2,3,4,5);		Stream<Integer> stream = list.stream();		stream=stream.skip(2);		stream.forEach(System.out::println);	}输出:345跳过了前两个元素

唯一筛选

两个元素通过hashCode()判断两个元素是否相同

@Test	public void test5() {		List<Integer> list = Arrays.asList(1,2,3,4,5,5);		Stream<Integer> stream = list.stream();		stream.distinct().forEach(System.out::println);	}输出:12345

映射

map(method)接受一个方法,把流中的元素按照方法进行转换

@Test	public void test() {		List<String> list = Arrays.asList("a","b","c");		Stream<String> stream = list.stream();		stream=stream.map((x)->x.toUpperCase());		stream.forEach(System.out::println);	}输出:ABC

flatMap(method)也是接受一个函数作为参数,但是与map,不同的是如果这个函数生成的本来就是流,它会把函数生成流中的元素加到流中

//这个函数本身就生成流public static Stream<Character> toStream(String s){  List<Character> list=new ArrayList<Character>();  char[] chs = s.toCharArray();  for (char c : chs) {    list.add(c);  }  Stream<Character> stream = list.stream();  return stream;}@Testpublic void test() {  List<String> list = Arrays.asList("aaa","bbb","ccc");  Stream<Stream<Character>> stream =   //由于函数本身就生成流,所以流中加入的还是流  list.stream().map(StreamTest::toStream);  //遍历的时候需要先从流中取出流,在遍历  stream.forEach((s)->s.forEach(System.out::println));}//然而我们可以使用flatMap进行改进@Testpublic void test() {  List<String> list = Arrays.asList("aaa","bbb","ccc");  list.stream().flatMap(StreamTest::toStream).forEach(System.out::println);}输出:aaabbbccc

终止操作

所有匹配

当所有元素都匹配时,allMatch(Predicate<? super T> predicate)才会返回true

@Testpublic void test() {  List<String> list = Arrays.asList("aaa","bbb","ccc");  boolean allMatch = list.stream().allMatch((s)->s.length()>2);  System.out.println(allMatch);}输出:true

任一匹配

当Stream中任一一个元素匹配时,anyMatch(Predicate<? super T> predicate)返回true

@Testpublic void test() {  List<String> list = Arrays.asList("aaa","bbb","ccc");  boolean anyMatch = list.stream().anyMatch((s)->s.equals("bbb"));  System.out.println(anyMatch);}输出:true

所有不匹配

当Stream中所有的元素都不匹配时,noneMatch(Predicate<? super T> predicate)返回true

@Testpublic void test() {  List<String> list = Arrays.asList("aaa","bbb","ccc");  boolean noneMatch = list.stream().noneMatch((s)->s.equals("ddd"));  System.out.println(noneMatch);}输出:true

第一个元素

返回当前流中的第一个元素

@Testpublic void test() {  List<Integer> list = Arrays.asList(1,2,3,4,5);  Optional<Integer> findFirst = list.stream().findFirst();  System.out.println(findFirst.get());}输出:1

任一一个元素

返回当前流中的任一一个元素

@Testpublic void test() {  List<Integer> list = Arrays.asList(1,2,3,4,5);  Optional<Integer> findAny = list.stream().findAny();  System.out.println(findAny.get());}输出:1//使用并行流试试@Testpublic void test13() {	List<Integer> list = Arrays.asList(1,2,3,4,5);	Optional<Integer> findAny =   		list.parallelStream().findAny();	System.out.println(findAny.get());}输出:3

流中元素个数

返回流中的元素个数

@Testpublic void test14() {  List<Integer> list = Arrays.asList(1,2,3,4,5);  long count = list.stream().count();  System.out.println(count);}输出:5

流中的最大值

返回流中元素的最大值

@Testpublic void test15() {  List<Integer> list = Arrays.asList(1,2,3,4,5);  Optional<Integer> max = list.stream().max(Integer::compare);  System.out.println(max.get());}输出:5

流中的最小值

返回流中的最小值

@Testpublic void test16() {  List<Integer> list = Arrays.asList(1,2,3,4,5);  Optional<Integer> min = list.stream().min(Integer::compare);  System.out.println(min.get());}输出:1

规约

将流中的元素反复结合得到一个最终值

@Testpublic void test() {  List<Integer> list = Arrays.asList(1,2,3,4,5);  Optional<Integer> reduce = list.stream().reduce(Integer::sum);  System.out.println(reduce.get());  Integer reduce2 = list.stream().reduce(0, (x,y)->{    System.out.println(x+"->"+y);    return x+y;  });  System.out.println(reduce2);}输出:150->11->23->36->410->515

可以看到当使用(T identity, BinaryOperator accumulator)时,identity即为最初和流中元素进行运算的,所以值不能为空,所以返回的不是Optional

收集

将流转换成其他形式

@Testpublic void test() {  List<Integer> list = Arrays.asList(1,2,3,4,5,5);  Set<Integer> collect = list.stream().collect(Collectors.toSet());  System.out.println(collect);}输出:[1, 2, 3, 4, 5]@Testpublic void test() {		List<Integer> list = Arrays.asList(1,2,3,4,5,5);		Optional<Integer> collect = list.stream().collect(Collectors.maxBy(Integer::compareTo));		System.out.println(collect.get());}输出:5class Stu{	String name;	Integer age;	String gender;	public Stu(String name, Integer age, String gender) {		super();		this.name = name;		this.age = age;		this.gender = gender;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public Integer getAge() {		return age;	}	public void setAge(Integer age) {		this.age = age;	}	public String getGender() {		return gender;	}	public void setGender(String gender) {		this.gender = gender;	}	@Override	public String toString() {		return "Stu [name=" + name + ", age=" + age + ", gender=" + gender + "]";	}	}//一级分组@Test	public void test() {		List<Stu> list = Arrays.asList(				new Stu("张三",20,"男"),				new Stu("李四",22,"女"),				new Stu("王五",18,"男"),				new Stu("赵六",20,"女"),				new Stu("田七",22,"女")				);		Map<String, List<Stu>> collect = 				list.stream().collect(Collectors.groupingBy(Stu::getGender));		System.out.println(collect);	}输出:{女=[Stu [name=李四, age=22, gender=女], Stu [name=赵六, age=20, gender=女], Stu [name=田七, age=22, gender=女]], 男=[Stu [name=张三, age=20, gender=男], Stu [name=王五, age=18, gender=男]]}//二级分组@Testpublic void test21() {  List<Stu> list = Arrays.asList(    new Stu("张三",20,"男"),    new Stu("李四",22,"女"),    new Stu("王五",18,"男"),    new Stu("赵六",20,"女"),    new Stu("田七",22,"女")  );  Map<Integer, Map<String, List<Stu>>> collect = list.stream()    .collect(Collectors.groupingBy(Stu::getAge, Collectors.groupingBy(Stu::getGender)));  System.out.println(collect);}输出:{18={男=[Stu [name=王五, age=18, gender=男]]}, 20={女=[Stu [name=赵六, age=20, gender=女]], 男=[Stu [name=张三, age=20, gender=男]]}, 22={女=[Stu [name=李四, age=22, gender=女], Stu [name=田七, age=22, gender=女]]}}//分区@Testpublic void test22() {  List<Stu> list = Arrays.asList(    new Stu("张三",20,"男"),    new Stu("李四",22,"女"),    new Stu("王五",18,"男"),    new Stu("赵六",20,"女"),    new Stu("田七",22,"女")  );  Map<Boolean, List<Stu>> collect = list.stream()    .collect(Collectors.partitioningBy((e)->((Stu)e).getAge()>20));  System.out.println(collect);}输出:{false=[Stu [name=张三, age=20, gender=男], Stu [name=王五, age=18, gender=男], Stu [name=赵六, age=20, gender=女]], true=[Stu [name=李四, age=22, gender=女], Stu [name=田七, age=22, gender=女]]}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
jdk8-lambda表达式的使用
优雅编程之这样使用CollectionUtils,你就“正常”了(三十五)
Java中ArrayList remove会遇到的坑
java8关于steam流的日常操作
Java8中Lambda表达式的10个例子
Java基础之Java8中map和flatMap的使用
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服