原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10748817.html

一、概述

Stream操作简称流操作,这里的流与IO流毫无关系,这里的流指的是流式操作,就是流水线操作。

Stream流操作主要包包括三大模块:创建流操作、中间流操作、终结流操作。

其中创建流主要是创建Stream对象。每个Stream对象只能使用一次终结操作。

中间流操作指的是各种中间流操作方法,比如去重、过滤、排序等

终结流操作指的结果操作,终结操作的目的是产生最终结果。

二、创建流

2.1 基于数组创建流

  1. public class StreamTest {
  2. public static void createStream() {
  3. // 通过数组生成流
  4. int[] ints = {1,2,3,4,5,6};
  5. IntStream s1 = Arrays.stream(ints);
  6. Stream s2 = Stream.of("111","222","333");
  7. String[] ss = {"123","321","456","654"};
  8. Stream<String> s3 = Arrays.stream(ss);
  9. }
  10. }

3.2 通过构建器生成流

  1. public class StreamTest {
  2. public static void createStream() {
  3. // 通过构建器生成流
  4. Stream<Object> s4 = Stream.builder().add("123").add("321").add("444").add("@21").build();
  5. }
  6. }

3.3 基于集合生成流

  1. public class StreamTest {
  2. public static void createStream() {
  3. // 通过集合生成流
  4. List<String> lists = Arrays.asList("123","321","1212","32321");
  5. Stream<String> s5 = lists.stream();
  6. Stream<String> s6 = lists.parallelStream();// 并行流
  7. }
  8. }

3.4 创建空流

  1. public class StreamTest {
  2. public static void createStream() {
  3. // 创建空流
  4. Stream<String> s7 = Stream.empty();
  5. }
  6. }

3.5 基于函数创建无限流

  1. public class StreamTest {
  2. public static void createStream() {
  3. // 创建无限流
  4. Stream.generate(()->"number"+new Random().nextInt()).limit(100).forEach(System.out::println);
  5. Stream.iterate(0,n -> n+2).limit(10).forEach(System.out::println);
  6. }
  7. }

三、流中间操作

这里的流中间操作指的是该操作的返回值仍然是流。

序号 操作 方法 说明 备注
1 filter Stream filter(Predicate<? super T> predicate) 返回当前流中满足参数predicate过滤条件的元素组成的新流 过滤器
2 map Stream map(Function<? super T, ? extends R> mapper) 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新流 函数
3 mapToInt IntStream mapToInt(ToIntFunction<? super T> mapper) 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Int流 函数
4 mapToLong LongStream mapToLong(ToLongFunction<? super T> mapper) 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Long流 函数
5 mapToDouble DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Double流 函数
6 flatMap Stream flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) 根据给定的mapper作用于当前流的每个元素,将结果组成新的流来返回 扁平函数
7 flatMapToInt IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) 根据给定的mapper作用于当前流的每个元素,将结果组成新的Int流来返回 扁平函数
8 flatMapToLong LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) 根据给定的mapper作用于当前流的每个元素,将结果组成新的Long流来返回 扁平函数
9 flatMapToDouble DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) 根据给定的mapper作用于当前流的每个元素,将结果组成新的Double流来返回 扁平函数
10 distinct Stream distinct() 返回去掉当前流中重复元素之后的新流 去重
11 sorted Stream sorted() 返回当前流中元素排序之后的新流,需要元素类型实现Comparable 排序
12 sorted Stream sorted(Comparator<? super T> comparator) 返回当前流中元素排序之后的新流,需要传递一个Comparator 排序
13 peek Stream peek(Consumer<? super T> action) 针对流中的每个元素执行操作action 查阅
14 limit Stream limit(long maxSize) 返回指定的数量的元素组成的新流 限制
15 skip Stream skip(long n) 返回第n个之后的元素组成的新流 跳过

扁平函数,就是将当前流的每个元素通过执行给定的mapper操作,从而扩充,释放每个元素内的子元素,从而形成一个由所有子元素组成的新流,比如当前流是包含N个字符串的流,使用这个方法,可以获取到包含字符串中字符组成的流。

3.1 filter

filter方法是过滤器方法,针对的是流中所有元素,满足条件的元素将会被保留以组成新的流。

  1. public class StreamTest {
  2. public static void filterTest(List<String> list){
  3. list.stream()
  4. .filter(e -> e.length() > 4 && e.length()<7)// 过滤掉长度小于等于4,大于等于7的元素
  5. .peek(System.out::println)// 查阅中间流结果
  6. .collect(Collectors.toList());
  7. }
  8. public static void main(String[] args) {
  9. List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
  10. filterTest(list);
  11. }
  12. }

执行结果为:

  1. asdaa
  2. 3e3e3e

filter方法的参数是Predicate类型,这个函数式接口用于获取一个参数返回一个boolean值,整个参数作为过滤条件。

3.2 map

map方法可以理解为函数,需要针对流中的每个元素执行,然后将执行的结果组成新的流返回。

  1. public class StreamTest {
  2. public static void mapTest(List<String> list){
  3. list.stream()
  4. .map(e -> "@" + e)// 为每个元素执行操作:添加前缀
  5. .peek(System.out::println)// 查阅中间流结果
  6. .collect(Collectors.toList());
  7. }
  8. public static void main(String[] args) {
  9. List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
  10. mapTest(list);
  11. }
  12. }

执行结果为:

  1. @123
  2. @456
  3. @789
  4. @1101
  5. @asdaa
  6. @3e3e3e
  7. @2321eew
  8. @212121121

map方法的参数类型为Function,该函数式接口用于接受一个参数,返回一个结果。

mapToInt、mapToLong、mapToDouble方法是map方法的扩展,其参数分别为ToIntFunction、ToLongFunction、ToDoubleFunction,分别接受一个参数,返回指定类型的值,分别为int、long、double,那么定义方法的时候就要注意返回值的类型了,必须一致,最后组成的新流就是一个int或long或double元素流(IntStream、LongStream、DoubleStream)。

mapToInt的简单使用(其他类似):

  1. public class StreamTest {
  2. public static void mapToIntTest(List<String> list){
  3. list.stream()
  4. .mapToInt(e -> e.length())// 以元素的长度为新流
  5. .peek(System.out::println)// 查询中间结果
  6. .toArray();
  7. }
  8. public static void main(String[] args) {
  9. List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
  10. mapToIntTest(list);
  11. }
  12. }

执行结果为:

  1. 3
  2. 3
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 9

3.3 flatMap

flatMap和map还是有点关系的,都是针对流中的每一个元素进行操作,将结果组成新流,不过flatMap含有一层扩展之意,就是当流中元素包含子元素的时候,通过该方法,获取到元素的子元素,并将子元素组成新流返回。

  1. public class StreamTest {
  2. public static void flatMap(List<String> list){
  3. list.stream()
  4. .filter(e -> e.length()>5 && e.length()<7)
  5. .peek(System.out::println)
  6. .map(e -> e.split(""))// 将每个字符串元素分解为字符数组
  7. .flatMap(Arrays::stream)//将每个字符数组并转化为流
  8. .peek(System.out::println)
  9. .collect(Collectors.toList());
  10. }
  11. public static void main(String[] args) {
  12. List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
  13. flatMap(list);
  14. }
  15. }

执行结果为:

  1. 3e3e3e
  2. 3
  3. e
  4. 3
  5. e
  6. 3
  7. e

flatMapToInt、flatMapToLong、flatMapToDouble类似于之前的mapToInt之类。

3.4 distinct

distinct方法用于去重,很简单。

  1. public class StreamTest {
  2. public static void distinctTest(){
  3. int[] int1 = {1,2,3,4};
  4. int[] int2 = {5,3,7,1};
  5. List<int[]> ints = Arrays.asList(int1,int2);
  6. ints.stream()
  7. .flatMapToInt(Arrays::stream)
  8. .distinct()
  9. .peek(System.out::println)
  10. .toArray();
  11. }
  12. public static void main(String[] args) {
  13. distinctTest();
  14. }
  15. }

执行结果为:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 7

结果中显而易见,重复的1和3被去除了。

3.5 sorted

sorted表示对流中的元素进行排序,需要使用Conparable和Comparator。

  1. public class StreamTest {
  2. public static void sortedTest(List<String> list){
  3. System.out.println("----自然顺序:");
  4. list.stream().sorted().peek(System.out::println).collect(Collectors.toList());
  5. System.out.println("----指定排序:");
  6. list.stream().sorted((a,b) -> a.length()-b.length()).peek(System.out::println).collect(Collectors.toList());
  7. }
  8. public static void main(String[] args) {
  9. List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
  10. sortedTest(list);
  11. }
  12. }

执行结果为:

  1. ----自然顺序:
  2. 1101
  3. 123
  4. 212121121
  5. 2321eew
  6. 3e3e3e
  7. 456
  8. 789
  9. asdaa
  10. ----指定排序:
  11. 123
  12. 456
  13. 789
  14. 1101
  15. asdaa
  16. 3e3e3e
  17. 2321eew
  18. 212121121

当调用无参的sorted方法时,采用自然排序法排序,当使用指定比较器的方式时,可以自由指定排序规则。

3.6 limit

limit可用于从首个元素开始截取N个元素,组成新流返回。

  1. public class StreamTest {
  2. public static void limitTest(List<String> list){
  3. list.stream().limit(2).peek(System.out::println).collect(Collectors.toList());
  4. }
  5. public static void main(String[] args) {
  6. List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
  7. limitTest(list);
  8. }
  9. }

执行结果为:

  1. 123
  2. 456

3.7 skip

skip表示放弃N个元素,将剩余元素组成新流返回。

  1. public class StreamTest {
  2. public static void skipTest(List<String> list){
  3. list.stream().skip(2).peek(System.out::println).collect(Collectors.toList());
  4. }
  5. public static void main(String[] args) {
  6. List<String> list = Arrays.asList("123","456","789","1101","asdaa","3e3e3e","2321eew","212121121");
  7. skipTest(list);
  8. }
  9. }

执行结果为:

  1. 789
  2. 1101
  3. asdaa
  4. 3e3e3e
  5. 2321eew
  6. 212121121

放弃了前2个元素,将剩余元素组成了新流。

四、流终结操作

序号 操作 方法 说明 备注
1 forEach void forEach(Consumer<? super T> action) 对流中的每个元素执行指定的操作action 遍历
2 forEachOrdered void forEachOrdered(Consumer<? super T> action) 如果有序,则按序遍历流中元素,针对每个元素执行指定操作 按序遍历
3 toArray Object[] toArray() 返回一个包含流中所有元素的数组 数组化
4 toArray A[] toArray(IntFunction<A[]> generator) 返回一个包含流中所有元素的参数指定类型的数组 数组化
5 reduce T reduce(T identity, BinaryOperator accumulator) 以给定初始值为基础归纳流中元素,返回一个值 归纳
6 reduce Optional reduce(BinaryOperator accumulator) 直接归纳流中的元素,返回一个封装有结果的Optional 归纳
7 reduce <U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner) 以给定的初始值为基础,(并行)归纳流中元素,最后将各个线程的结果再统一归纳,返回一个值 归纳
8 collect <R, A> R collect(Collector<? super T, A, R> collector) 根据给定的收集器收集元素 归纳
9 collect R collect(Supplier supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner) 根据给定的各个参数归纳元素 归纳
10 max Optional max(Comparator<? super T> comparator) 根据给定的比较器,返回流中最大元素的Optional表示 最大值
11 min Optional min(Comparator<? super T> comparator) 根据给定的比较器,返回流中最小元素的Optional表示 最小值
12 count long count() 返回流中元素的个数 计数
13 anyMatch boolean anyMatch(Predicate<? super T> predicate) 校验流中是否有满足给定条件的元素 校验
14 allMatch boolean allMatch(Predicate<? super T> predicate) 校验流中的元素是否全部满足给定条件 校验
15 noneMatch boolean noneMatch(Predicate<? super T> predicate) 校验流中的元素是否全不满足给点条件 校验
16 findFirst Optional findFirst() 返回首个元素的Optional表示,如果为空流,返回空的Optional 返回首个元素
17 findAny Optional findAny() 如果流中有元素,则返回第一个元素的Optional表示,否则返回一个空的Optional 校验是否为空流

4.1 forEach和forEachOrdered

forEach就是遍历操作,针对流中的每个元素做最后的操作。

  1. public class StreamTest {
  2. public static void forEachTest(List<String> list){
  3. list.stream().parallel().forEach(System.out::println);
  4. }
  5. public static void forEachOrderedTest(List<String> list){
  6. list.stream().parallel().forEachOrdered(System.out::println);
  7. }
  8. public static void main(String[] args) {
  9. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  10. forEachTest(list);
  11. System.out.println("----------");
  12. forEachOrderedTest(list);
  13. }
  14. }

执行结果为:

  1. asdaa
  2. 212121121
  3. 789
  4. 1101
  5. 2321eew
  6. 3e3e3e
  7. 456
  8. 123
  9. ----------
  10. 123
  11. 456
  12. 789
  13. 1101
  14. 212121121
  15. asdaa
  16. 3e3e3e
  17. 2321eew

二者都是遍历操作,从结果是可以看出来,如果是单线程(也就是不加parallel方法的情况)那么二者结果是一致的,但是如果采用并行遍历,那么就有区别了,forEach并行遍历不保证顺序(顺序随机),forEachOrdered却是保证顺序来进行遍历的。

4.2 toArray

  1. public class StreamTest {
  2. public static void toArrayTest(List<String> list){
  3. Object[] objs = list.stream().filter(e -> e.length()>6).toArray();
  4. String[] ss = list.stream().filter(e -> e.length()>6).toArray(String[]::new);
  5. }
  6. public static void main(String[] args) {
  7. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  8. toArrayTest(list);
  9. }
  10. }

toArray有两个方法,一个是无参方法,一个有参方法。

无参方法返回的只能是Object[]数组类型,而有参方法,可以指定结果数组类型,此乃二者区别。

使用有参方法可以直接完成类型转换,一次到位。

4.4 reduce

reduce方法有三个重载的方法,

  1. public interface Stream<T> extends BaseStream<T, Stream<T>> {
  2. Optional<T> reduce(BinaryOperator<T> accumulator);// 编号1
  3. T reduce(T identity, BinaryOperator<T> accumulator);// 编号2
  4. <U> U reduce(U identity,
  5. BiFunction<U, ? super T, U> accumulator,
  6. BinaryOperator<U> combiner);// 编号3
  7. }

这三个方法的作用其实是一样的,就是归纳总结的意思。

首先看编号1方法,只有一个参数accumulator,这是一个累加器,方法的作用就是将这个累加器作用到流中的每一个元素,他需要两个输入参数,有一个输出参数,意思是对两个元素执行某些操作,返回一个结果,然后将这个结果与下一个元素作为参数再输入该方法,执行操作后再返回一个新结果,以此类推,直到最后一个元素执行完毕,返回的就是最终结果,因为流中的元素我们是不确定的,那么我们就无法确定reduce的结果,因为如果流为空,那么将会返回null,所以使用Optional作为返回值,妥善处理null值。

再看编号2方法,在编号1方法的基础上加了一个identity,且不再使用Optional,为什么呢,因为新加的identity其实是个初始值,后续的操作都在这个值基础上执行,那么也就是说,,如果流中没有元素的话,还有初始值作为结果返回,不会存在null的情况,也就不用Optional了。

再看编号3方法,在编号2方法的基础上又加了一个参数combiner,其实这个方法是用于处理并行流的归纳操作,最后的参数combiner用于归纳各个并行的结果,用于得出最终结果。

那么如果不使用并行流,一般使用编号2方法就足够了。

示例:

  1. public class StreamTest {
  2. public static void reduceTest(){
  3. List<Integer> ints = Arrays.asList(1,2,3,4,5,6,7,8,9);
  4. Optional<Integer> optional = ints.stream().reduce(Integer::sum);
  5. System.out.println(optional.get());
  6. System.out.println("-------------");
  7. Integer max = ints.stream().reduce(Integer.MIN_VALUE, Integer::max);
  8. System.out.println(max);
  9. System.out.println("-------------");
  10. Integer min = ints.parallelStream().reduce(Integer.MAX_VALUE, Integer::min, Integer::min);
  11. System.out.println(min);
  12. }
  13. public static void main(String[] args) {
  14. reduceTest();
  15. }
  16. }

执行结果为:

  1. 45
  2. -------------
  3. 9
  4. -------------
  5. 1

4.5 collect

collect操作是Stream中最强大的方法了,几乎可以得到任何你想要的结果,collect方法有两个重载方法:

  1. public interface Stream<T> extends BaseStream<T, Stream<T>> {
  2. <R> R collect(Supplier<R> supplier,
  3. BiConsumer<R, ? super T> accumulator,
  4. BiConsumer<R, R> combiner);// 编号1
  5. <R, A> R collect(Collector<? super T, A, R> collector);// 编号2
  6. }

collect是收集的意思,这里的作用就是收集归纳,将流中的数据映射为各种结果。

首先看看编号1方法,有三个参数:supplier用于生成一个R类型的结果容器来盛放结果,accumulator累加器用于定义盛放的方式,其中T为一个元素,R为结果容器,第三个参数combiner的作用是将并行操作的各个结果整合起来。

  1. public class StreamTest {
  2. public static void collectTest1(List<String> list){
  3. ArrayList<String> arrayList = list.stream().skip(4).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
  4. arrayList.forEach(System.out::println);
  5. }
  6. public static void main(String[] args) {
  7. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  8. collectTest1(list);
  9. }
  10. }

执行结果:

  1. 212121121
  2. asdaa
  3. 3e3e3e
  4. 2321eew

例子中,第一个:ArrayList::new表示创建一个新的ArrayList集合,第二个 ArrayList::add表示将元素一个一个添加到之前的集合中,第三个ArrayList::addAll表示将多个线程的ArrayList集合一个一个的整体添加到第一个集合中,最终整合出一个最终结果并返回。

然后我们重点来看看编号2方法。

它只需要一个Collector类型的参数,这个Collector可以称呼为收集器,我们可以随意组装一个收集器来进行元素归纳。

Collector是定义来承载一个收集器,但是JDK提供了一个Collectors工具类,在这个工具类里面预实现了N多的Collector供我们直接使用,之前的Collectors.toList()就是其用法之一。具体见下文。

  1. public class StreamTest {
  2. public static void collectTest2(List<String> list){
  3. Set<String> set = list.stream().skip(4).collect(Collectors.toSet());
  4. set.forEach(System.out::println);
  5. }
  6. public static void main(String[] args) {
  7. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  8. collectTest2(list);
  9. }
  10. }

执行结果为:

  1. 212121121
  2. 2321eew
  3. 3e3e3e
  4. asdaa

4.6 max\min

通过给定的比较器,得出流中最大\最小的元素,为避免null返回,这里使用Optional来封装返回值。

  1. public class StreamTest {
  2. public static void maxMinTest(List<String> list){
  3. System.out.println("长度最大:" + list.stream().max((a,b)-> a.length()-b.length()));
  4. System.out.println("长度最小:" + list.stream().min((a,b)-> a.length()-b.length()));
  5. }
  6. public static void main(String[] args) {
  7. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  8. maxMinTest(list);
  9. }
  10. }

执行结果为:

  1. 长度最大:Optional[212121121]
  2. 长度最小:Optional[123]

4.7 count

count是无参方法,用于计数,返回流中元素个数。

  1. public class StreamTest {
  2. public static void countTest(List<String> list){
  3. System.out.println("元素个数为:" + list.stream().count());
  4. }
  5. public static void main(String[] args) {
  6. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  7. countTest(list);
  8. }
  9. }

执行结果为:

  1. 元素个数为:8

4.8 anyMatch

该方法需要一个Predicate参数,用于校验流中的元素,只要有一个满足规则,则返回true,全不满足,返回false。

  1. public class StreamTest {
  2. public static void anyMatchTest(List<String> list){
  3. System.out.println(list.stream().anyMatch(e -> e.length()>10));
  4. System.out.println(list.stream().anyMatch(e -> e.length()>8));
  5. }
  6. public static void main(String[] args) {
  7. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  8. anyMatchTest(list);
  9. }
  10. }

执行结果为:

  1. false
  2. true

4.9 allMatch

该方法同样需要一个Predicate参数,用于校验流中的所有元素,只有全部满足规则才能返回true,只要有一个不满足则返回false。

  1. public class StreamTest {
  2. public static void allMatchTest(List<String> list){
  3. System.out.println(list.stream().allMatch(e -> e.length()>1));
  4. System.out.println(list.stream().allMatch(e -> e.length()>3));
  5. }
  6. public static void main(String[] args) {
  7. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  8. allMatchTest(list);
  9. }
  10. }

执行结果为:

  1. true
  2. false

4.10 noneMatch

该方法同样需要一个Predicate参数,用于校验流中的所有元素,只有所有元素都不满足规则的情况下返回true,否则返回false。

  1. public class StreamTest {
  2. public static void noneMatchTest(List<String> list){
  3. System.out.println(list.stream().noneMatch(e -> e.length()>10));
  4. System.out.println(list.stream().noneMatch(e -> e.length()>8));
  5. }
  6. public static void main(String[] args) {
  7. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  8. noneMatchTest(list);
  9. }
  10. }

执行结果为:

  1. true
  2. false

4.11 findFirst

该方法无参数,主要用于获取流中的第一个元素,如果流无序,那么可能返回任意一个。

  1. public class StreamTest {
  2. public static void findFirstTest(List<String> list){
  3. System.out.println(list.stream().parallel().findFirst().get());
  4. }
  5. public static void main(String[] args) {
  6. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  7. findFirstTest(list);
  8. }
  9. }

执行结果为:

  1. 123

4.12 findAny

该方法无参数,主要用于获取流中的任一元素。

  1. public class StreamTest {
  2. public static void findAnyTest(List<String> list){
  3. System.out.println(list.stream().parallel().findAny().get());
  4. }
  5. public static void main(String[] args) {
  6. List<String> list = Arrays.asList("123","456","789","1101","212121121","asdaa","3e3e3e","2321eew");
  7. findAnyTest(list);
  8. }
  9. }

执行结果为:

  1. asdaa

五、总结

流式操作代码描述性强,易理解,而且功能强大,可以简化很多集合操作。在我们需要对集合数据进行处理的时候,不妨试试使用流式操作来实现。

参考:

Java基础系列-Stream的更多相关文章

  1. Java基础系列-Collector和Collectors

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10748925.html 一.概述 Collector是专门用来作为Stream的coll ...

  2. 2015年12月28日 Java基础系列(六)流

    2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流

  3. Java基础(十一) Stream I/O and Files

    Java基础(十一) Stream I/O and Files 1. 流的概念 程序的主要任务是操纵数据.在Java中,把一组有序的数据序列称为流. 依据操作的方向,能够把流分为输入流和输出流两种.程 ...

  4. Java基础系列--static关键字

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/8477914.html 一.概述 static关键字是Java诸多关键字中较常使用的一个,从 ...

  5. Java基础系列-ArrayList

    原创文章,转载请标注出处:<Java基础系列-ArrayList> 一.概述 ArrayList底层使用的是数组.是List的可变数组实现,这里的可变是针对List而言,而不是底层数组. ...

  6. Java基础系列-二进制操作

    原创文章,转载请标注出处:<Java基础系列-二进制操作> 概述 Java源码中涉及到大量的二进制操作,非常的复杂,但非常的快速. Java二进制表示法 首先了解下二进制,二进制是相对十进 ...

  7. Java基础系列-equals方法和hashCode方法

    原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述         equals方法和hashCode方法都是有Object类定义的. publi ...

  8. Java基础系列-Comparable和Comparator

    原创文章,转载请标注出处:<Java基础系列-Comparable和Comparator> 一.概述         Java中的排序是由Comparable和Comparator这两个接 ...

  9. Java基础系列--HashMap(JDK1.8)

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...

随机推荐

  1. BZOJ_4517_[Sdoi2016]排列计数_组合数学

    BZOJ_4517_[Sdoi2016]排列计数_组合数学 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[ ...

  2. BZOJ_1058_[ZJOI2007]报表统计_STL

    BZOJ_1058_[ZJOI2007]报表统计_STL Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工 作,作为她的生日礼 ...

  3. Loadrunner下载脚本

    由于最近又在SGM做性能测试,扒拉出一篇去年5.6月份的一个脚本. 最近写的翻来看看其实也蛮简单的,还是就不放博客了. Action(){ //定义文件大小 int flen; //定义响应数据内容大 ...

  4. (2)STM32使用HAL库操作外部中断——理论讲解

    1.中断触发过程 对主程序压栈--把中断服务函数的地址写入到程序计数器(PC)--执行中断服务函数 2.中断向量表 中断服务函数的地址在STM32的手册上的中断向量表中(如下是一部分): 如上表所示, ...

  5. mybatis 异常Result Maps collection does not contain value for java.lang.String

    Result Maps collection does not contain value for java.lang.String 以上是我报的错. 只要报Result Maps collectio ...

  6. TensorFlow实现分布式计算

    摘要: 1.代码例子 内容: 1.代码例子 <TensorFlow实战>实现CNN处理CIFAR10数据,并模拟单机多个CPU同步数据并行计算 <TensorFlow实战>实现 ...

  7. 神奇的Scala Macro之旅(二)- 一个实例

    优化的日志方式 package macros_demo import scala.language.experimental.macrosimport org.slf4j._import scala. ...

  8. 我眼中的 Nginx(三):Nginx 变量和变量插值

    张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护.Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技术的 ...

  9. 《HelloGitHub》第 36 期

    公告 本期内容较多.本期共有 41 个项目:C# 项目(1),C++ 项目(1),CSS 项目(2),Go 项目(5),Java 项目(2),JavaScript 项目(5),Objective-C ...

  10. FreeSql 与 SqlSugar 性能测试(增EFCore测试结果)

    这篇文章受大家邀请,与 SqlSugar 做一次简单的性能测试对比.主要针对插入.批量插入.批量更新.读取性能的测试: 测试环境 .net core 2.2 FreeSql 0.3.17 sqlSug ...