Stream流
1.stream流是元素的集合
2.可以支持串行和并行的对原有流进行操作并生成新的流
(愚以为他就是跟iterator类似的东西,把集合里面的东西直接进行操作,简化了操作流程同时提高b格,同时也是jdk8新增的。下面是源码)
/** * Returns a sequential {@code Stream} with this collection as its source. * * <p>This method should be overridden when the {@link #spliterator()} * method cannot return a spliterator that is {@code IMMUTABLE}, * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()} * for details.) * * @implSpec * The default implementation creates a sequential {@code Stream} from the * collection's {@code Spliterator}. * * @return a sequential {@code Stream} over the elements in this collection * @since 1.8//jdk8新增 */ default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); }
同时他是collection类的一个default方法,直接调用就可以,但是map不行所以怕map不开心就给map增加了一些consumer接口来操作里面的元素。
允许接口中存在默认方法也是jdk8的一个新增特性之一
1.Stream流的操作流程
1.集合先变成流
下面是集合变成流的几种方法,毕竟只是笔记我也没有全部记下来,就记几个我认为好记又好用的。
a list.stream() //串行的流转换
b list.parallelStream()//并行的流转换,串行和并行在某些情况下必然存在着速度差异
c Stream.of // 使用Stream的方法来进行流转换
问题:这里提出一个问题,那么Stream的of方法到底是并行还是穿行呢?
public static<T> Stream<T> of(T... values) { return Arrays.stream(values); }
通过源码发现,其实of方法调用的还是stream()方法。
2.通过操作符来操作流(操作符又能分为中间操作符和最终操作符)
(图片来自:@程序员的内心独白)
绿色的就是中间操作符,蓝色的就是最终操作符。
中间操作符可以有很多,类似于我在使用tkMapper中的通用mapper来拼接sql语句,但是最终操作符只能有一个。
2.stream的中间操作符和最终操作符
在这里我直接引用别人对操作符描写的帖子了,感谢老铁!
https://blog.csdn.net/qq_28410283/article/details/80633292
下面是我对其中几个操作符的使用
package stream; import java.util.ArrayList; import java.util.List; import java.util.function.Function; import java.util.stream.Stream; /** * @ Author :fqg * @ Date :Created in 19:06 2020/8/12 */ public class StreamDemo { static class People{ String name; int age; public People(String name, int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString(){ return "People { " + " name :" + name + " age :" + age +" }"; } } public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(5); list.add(2); list.add(7); list.add(0); list.add(0); list.add(0); list.stream().sorted().filter(num -> num !=1 ).forEach(System.out::print); System.out.println(); System.out.println("-----------distinct nad sorted by me----------------"); list.stream().distinct().sorted((o1,o2)->{return o2 - o1;}).forEach(System.out::print); System.out.println(); System.out.println("-------------map--------------"); //map可以自定义让流变成另外一种类型的流,包括类 list.stream().sorted().map(new Function<Integer, String>() { @Override public String apply(Integer integer) { return "i am" + integer; } }).distinct().forEach(System.out::print); System.out.println(); Stream.of("fqg:22", "cjh:21").map(new Function<String, People>() { @Override public People apply(String s) { String[] strs = s.split(":"); People people = new People(strs[0], Integer.parseInt(strs[1])); return people; } }).forEach(people -> System.out.println("people = " + people)); //match匹配 System.out.println("-----------match---------"); boolean bool = Stream.of("fqg:22", "cjh:21").map(new Function<String, People>() { @Override public People apply(String s) { String[] strs = s.split(":"); People people = new People(strs[0], Integer.parseInt(strs[1])); return people; } }).anyMatch(people -> "fqg".equals(people.getName()));//部分匹配 System.out.println(bool);//true bool = Stream.of("fqg:22", "cjh:21").map(new Function<String, People>() { @Override public People apply(String s) { String[] strs = s.split(":"); People people = new People(strs[0], Integer.parseInt(strs[1])); return people; } }).allMatch(people -> "fqg".equals(people.getName()));//全部匹配 System.out.println(bool);//false //count System.out.println("----------count----------"); long count = list.stream().distinct().count();//返回的是long类型的 System.out.println(count); } }
运行结果
问题:
1.Foreach和for循环一样么?
如果在循环体中有复杂的业务、调用远程接口或数据库就用stream,因为stream是多线程方式并行执行,但是其调用线程池必然会消耗性能,所以简单的操作固然还是for循环效率高。你说谁好谁坏还是要根据实际的业务场景来