Java8 Stream是一个非常好用的工具,结合Lambda表达式,可以非常方便的来操作各种集合。

文章目录

  • Stream知识图谱
  • Stream概述
  • Stream的创建
  • Stream的使用
    • 遍历/匹配(foreach/find/match)
    • 筛选(filter)
    • 聚合(max/min/count)
    • 映射(map/flatMap)
    • 归约(reduce)
    • 收集(collect)
      • 归集(toList/toSet/toMap)
      • 统计(count/averaging)
      • 分组(partitioningBy/groupingBy)
      • 接合(joining)
      • 归约(reducing)
    • 排序(sorted)
    • 提取/组合
  • 本文小结

Stream知识图谱


Stream概述

Java 8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的 Lambda ,给我们操作集合(Collection)提供了极大的便利。

那么什么是Stream?

Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。

Stream可以由数组或集合创建,对流的操作分为两种:

  1. 中间操作,每次返回一个新的流,可以有多个。
  2. 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。

另外,Stream有几个特性:

  1. stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。
  2. stream不会改变数据源,通常情况下会产生一个新的集合或一个值。
  3. stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

Stream的创建

Stream可以通过集合数组创建。

通过 java.util.Collection.stream() 方法用集合创建流

List<String> list = Arrays.asList("a", "b", "c");
// 创建一个顺序流
Stream<String> stream = list.stream();
// 创建一个并行流
Stream<String> parallelStream = list.parallelStream();

使用java.util.Arrays.stream(T[] array)方法用数组创建流

int[] array={1,3,5,6,8};
IntStream stream = Arrays.stream(array);

使用Stream的静态方法:of()、iterate()、generate()

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println);Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);

stream和parallelStream的简单区分: stream是顺序流,由主线程按顺序对流执行操作,而parallelStream是并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。例如筛选集合中的奇数,两者的处理不同之处:


如果流中的数据量足够大,并行流可以加快处速度。

除了直接创建并行流,还可以通过parallel()把顺序流转换成并行流:

Optional<Integer> findFirst = list.stream().parallel().filter(x->x>6).findFirst();

Stream的使用

在使用stream之前,先理解一个概念:Optional 。

Optional类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
更详细说明请见菜鸟教程

案例使用的员工类

package cn.wideth.util;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {private String name;  // 姓名private int salary; // 薪资private int age; // 年龄private String sex; //性别private String area;  // 地区}

遍历/匹配(foreach/find/match)

Stream也是支持类似集合的遍历和匹配元素的,只是Stream中的元素是以Optional类型存在的。Stream的遍历、匹配非常简单。

package cn.wideth.util;import java.util.Arrays;
import java.util.List;
import java.util.Optional;public class StreamTest {public static void main(String[] args) {List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);// 遍历输出符合条件的元素list.stream().filter(x -> x > 6).forEach(System.out::println);// 匹配第一个Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();// 匹配任意(适用于并行流)Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();// 是否包含符合特定条件的元素boolean anyMatch = list.stream().anyMatch(x -> x < 6);System.out.println("匹配第一个值:" + findFirst.get());System.out.println("匹配任意一个值:" + findAny.get());System.out.println("是否存在大于6的值:" + anyMatch);}
}

程序结果


筛选(filter)

筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。

案例一:筛选出Integer集合中大于7的元素,并打印出来

package cn.wideth.util;import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;public class StreamTest {public static void main(String[] args) {List<Integer> list = Arrays.asList(6, 7, 3, 8, 1, 2, 9);Stream<Integer> stream = list.stream();stream.filter(x -> x > 7).forEach(System.out::println);}
}

程序结果


聚合(max/min/count)

max、min、count这些字眼你一定不陌生,没错,在mysql中我们常用它们进行数据统计。Java stream中也引入了这些概念和用法,极大地方便了我们对集合、数组的数据统计工作。

案例一:获取String集合中最长的元素。

package cn.wideth.util;import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;public class StreamTest {public static void main(String[] args) {List<String> list = Arrays.asList("adnmbv", "admmvvt", "pvvot", "xbttangd", "wujkeoujgsd");Optional<String> max = list.stream().max(Comparator.comparing(String::length));System.out.println("最长的字符串:" + max.get());}
}

程序结果

案例二:获取Integer集合中的最大值。

package cn.wideth.util;import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;public class StreamTest {public static void main(String[] args) {List<Integer> list = Arrays.asList(7, 6, 9, 24, 11, 6,20);// 自然排序Optional<Integer> max = list.stream().max(Integer::compareTo);// 自定义排序Optional<Integer> max2 = list.stream().max(Comparator.naturalOrder());System.out.println("自然排序的最大值:" + max.get());System.out.println("自定义排序的最大值:" + max2.get());}
}

程序结果

案例三:获取员工工资最高的人。

package cn.wideth.util;import java.util.*;public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));personList.add(new Person("Anni", 8200, 24, "female", "New York"));personList.add(new Person("Owen", 9500, 25, "male", "New York"));personList.add(new Person("Alisa", 7900, 26, "female", "New York"));Optional<Person> max = personList.stream().max(Comparator.comparingInt(Person::getSalary));System.out.println("员工工资最大值:" + max.get().getSalary());}
}

程序结果

案例四:计算Integer集合中大于6的元素的个数。

package cn.wideth.util;import java.util.*;public class StreamTest {public static void main(String[] args) {List<Integer> list = Arrays.asList(7, 6, 4, 8, 2, 11, 9);long count = list.stream().filter(x -> x > 6).count();System.out.println("list中大于6的元素个数:" + count);}
}


映射(map/flatMap)

映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap:

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

案例一:英文字符串数组的元素全部改为大写。整数数组每个元素+3。

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;public class StreamTest {public static void main(String[] args) {String[] strArr = { "abcyd", "btycdd", "defdnhe", "fyubnTr" };List<String> strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());System.out.println("每个元素大写:" + strList);System.out.println("每个元素+3:" + intListNew);}
}

程序结果

案例二:将员工的薪资全部增加1000。

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));personList.add(new Person("Anni", 8200, 24, "female", "New York"));personList.add(new Person("Owen", 9500, 25, "male", "New York"));personList.add(new Person("Alisa", 7900, 26, "female", "New York"));// 不改变原来员工集合的方式List<Person> personListNew = personList.stream().map(person -> {Person personNew = new Person(person.getName(), 0, 0, null, null);personNew.setSalary(person.getSalary() + 10000);return personNew;}).collect(Collectors.toList());System.out.println("一次改动前:" + personList.get(0).getName() + "-->" + personList.get(0).getSalary());System.out.println("一次改动后:" + personListNew.get(0).getName() + "-->" + personListNew.get(0).getSalary());// 改变原来员工集合的方式List<Person> personListNew2 = personList.stream().map(person -> {person.setSalary(person.getSalary() + 10000);return person;}).collect(Collectors.toList());System.out.println("二次改动前:" + personList.get(0).getName() + "-->" + personListNew.get(0).getSalary());System.out.println("二次改动后:" + personListNew2.get(0).getName() + "-->" + personListNew.get(0).getSalary());}
}

程序结果

案例三:将两个字符数组合并成一个新的字符数组。

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class StreamTest {public static void main(String[] args) {List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");List<String> listNew = list.stream().flatMap(s -> {// 将每个元素转换成一个streamString[] split = s.split(",");Stream<String> s2 = Arrays.stream(split);return s2;}).collect(Collectors.toList());System.out.println("处理前的集合:" + list);System.out.println("处理后的集合:" + listNew);}
}

程序结果


归约(reduce)

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

案例一:求Integer集合的元素之和、乘积和最大值。

package cn.wideth.util;import java.util.Arrays;
import java.util.List;
import java.util.Optional;public class StreamTest {public static void main(String[] args) {List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);// 求和方式1Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);// 求和方式2Optional<Integer> sum2 = list.stream().reduce(Integer::sum);// 求和方式3Integer sum3 = list.stream().reduce(0, Integer::sum);// 求乘积Optional<Integer> product = list.stream().reduce((x, y) -> x * y);// 求最大值方式1Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);// 求最大值写法2Integer max2 = list.stream().reduce(1, Integer::max);System.out.println("list求和:" + sum.get() + "," + sum2.get() + "," + sum3);System.out.println("list求积:" + product.get());System.out.println("list求和:" + max.get() + "," + max2);}
}


程序结果

案例二:求所有员工的工资之和和最高工资。

package cn.wideth.util;import java.util.ArrayList;
import java.util.List;
import java.util.Optional;public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));personList.add(new Person("Anni", 8200, 24, "female", "New York"));personList.add(new Person("Owen", 9500, 25, "male", "New York"));personList.add(new Person("Alisa", 7900, 26, "female", "New York"));// 求工资之和方式1:Optional<Integer> sumSalary = personList.stream().map(Person::getSalary).reduce(Integer::sum);// 求工资之和方式2:Integer sumSalary2 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(),(sum1, sum2) -> sum1 + sum2);// 求工资之和方式3:Integer sumSalary3 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(), Integer::sum);// 求最高工资方式1:Integer maxSalary = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),Integer::max);// 求最高工资方式2:Integer maxSalary2 = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),(max1, max2) -> max1 > max2 ? max1 : max2);System.out.println("工资之和:" + sumSalary.get() + "," + sumSalary2 + "," + sumSalary3);System.out.println("最高工资:" + maxSalary + "," + maxSalary2);}
}

程序结果


收集(collect)

collect,收集,可以说是内容最繁多、功能最丰富的部分了。从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。

collect主要依赖java.util.stream.Collectors类内置的静态方法。

归集(toList/toSet/toMap)

因为流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。toList、toSet和toMap比较常用,另外还有toCollection、toConcurrentMap等复杂一些的用法。

下面用一个案例演示toList、toSet和toMap:

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;public class StreamTest {public static void main(String[] args) {List<Integer> list = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20);List<Integer> listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());List<Person> personList = new ArrayList<>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));personList.add(new Person("Anni", 8200, 24, "female", "New York"));Map<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000).collect(Collectors.toMap(Person::getName, p -> p));System.out.println("toList:" + listNew);System.out.println("toSet:" + set);System.out.println("toMap:" + map);}
}

程序结果


统计(count/averaging)

Collectors提供了一系列用于数据统计的静态方法:

  • 计数:count
  • 平均值:averagingInt、averagingLong、averagingDouble
  • 最值:maxBy、minBy
  • 求和:summingInt、summingLong、summingDouble
  • 统计以上所有:summarizingInt、summarizingLong、summarizingDouble

案例:统计员工人数、平均工资、工资总额、最高工资。

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));// 求总数Long count = personList.stream().collect(Collectors.counting());// 求平均工资Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));// 求最高工资Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));// 求工资之和Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));// 一次性统计所有信息DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));System.out.println("员工总数:" + count);System.out.println("员工平均工资:" + average);System.out.println("员工工资总和:" + sum);System.out.println("员工工资所有统计:" + collect);}
}

程序结果


分组(partitioningBy/groupingBy)

分区:将stream按条件分为两个Map,比如员工按薪资是否高于8000分为两部分。
分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。

案例:将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<>();personList.add(new Person("Tom", 8900, 24,"male", "New York"));personList.add(new Person("Jack", 7000, 22,"male", "Washington"));personList.add(new Person("Lily", 7800, 27,"female", "Washington"));personList.add(new Person("Anni", 8200, 22,"female", "New York"));personList.add(new Person("Owen", 9500, 28,"male", "New York"));personList.add(new Person("Alisa", 7900, 29,"female", "New York"));// 将员工按薪资是否高于8000分组Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));// 将员工按性别分组Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));// 将员工先按性别分组,再按地区分组Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));System.out.println("员工按薪资是否大于8000分组情况:" + part);System.out.println("员工按性别分组情况:" + group);System.out.println("员工按性别、地区:" + group2);}
}

程序结果


接合(joining)

joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));String names = personList.stream().map(p -> p.getName()).collect(Collectors.joining(","));System.out.println("所有员工的姓名:" + names);List<String> list = Arrays.asList("A", "B", "C");String string = list.stream().collect(Collectors.joining("-"));System.out.println("拼接后的字符串:" + string);}
}

程序结果


归约(reducing)

Collectors类提供的reducing方法,相比于stream本身的reduce方法,增加了对自定义归约的支持。

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<>();personList.add(new Person("Tom", 8900, 23, "male", "New York"));personList.add(new Person("Jack", 7000, 25, "male", "Washington"));personList.add(new Person("Lily", 7800, 21, "female", "Washington"));// 每个员工减去起征点后的薪资之和(这个例子并不严谨,但一时没想到好的例子)Integer sum = personList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j - 5000)));System.out.println("员工扣税薪资总和:" + sum);// stream的reduceOptional<Integer> sum2 = personList.stream().map(Person::getSalary).reduce(Integer::sum);System.out.println("员工薪资总和:" + sum2.get());}
}

程序结果


排序(sorted)

sorted,中间操作。有两种排序

sorted():自然排序,流中元素需实现Comparable接口
sorted(Comparator com):Comparator排序器自定义排序

案例:将员工按工资由高到低(工资一样则按年龄由大到小)排序

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;public class StreamTest {public static void main(String[] args) {List<Person> personList = new ArrayList<>();personList.add(new Person("Sherry", 9000, 24, "female", "New York"));personList.add(new Person("Tom", 8900, 22, "male", "Washington"));personList.add(new Person("Jack", 9000, 25, "male", "Washington"));personList.add(new Person("Lily", 8800, 26, "male", "New York"));personList.add(new Person("Alisa", 9000, 26, "female", "New York"));// 按工资升序排序(自然排序)List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName).collect(Collectors.toList());// 按工资倒序排序List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed()).map(Person::getName).collect(Collectors.toList());// 先按工资再按年龄升序排序List<String> newList3 = personList.stream().sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName).collect(Collectors.toList());// 先按工资再按年龄自定义排序(降序)List<String> newList4 = personList.stream().sorted((p1, p2) -> {if (p1.getSalary() == p2.getSalary()) {return p2.getAge() - p1.getAge();} else {return p2.getSalary() - p1.getSalary();}}).map(Person::getName).collect(Collectors.toList());System.out.println("按工资升序排序:" + newList);System.out.println("按工资降序排序:" + newList2);System.out.println("先按工资再按年龄升序排序:" + newList3);System.out.println("先按工资再按年龄自定义降序排序:" + newList4);}
}

程序结果


提取/组合

流也可以进行合并、去重、限制、跳过等操作。

流也可以进行合并、去重、限制、跳过等操作。

package cn.wideth.util;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class StreamTest {public static void main(String[] args) {String[] arr1 = { "a", "b", "c", "d" };String[] arr2 = { "d", "e", "f", "g" };Stream<String> stream1 = Stream.of(arr1);Stream<String> stream2 = Stream.of(arr2);// concat:合并两个流 distinct:去重List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());// limit:限制从流中获得前n个数据List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());// skip:跳过前n个数据List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());System.out.println("流合并:" + newList);System.out.println("limit:" + collect);System.out.println("skip:" + collect2);}
}

程序结果


本文小结

有关Java8中的Stream操作,主要就是这些,当需要使用的时候,就看下,用的多了,自然就掌握了这些。

Java8中的Stream相关推荐

  1. 【Java8新特性】面试官问我:Java8中创建Stream流有哪几种方式?

    写在前面 先说点题外话:不少读者工作几年后,仍然在使用Java7之前版本的方法,对于Java8版本的新特性,甚至是Java7的新特性几乎没有接触过.真心想对这些读者说:你真的需要了解下Java8甚至以 ...

  2. java8中的Stream用法详解

    项目github地址:bitcarmanlee easy-algorithm-interview-and-practice 欢迎大家star,留言,一起学习进步 1.为什么java8中加入Stream ...

  3. 巧用Java8中的Stream,让集合操作6到飞起!!!

    简介 java8也出来好久了,接口默认方法,lambda表达式,函数式接口,Date API等特性还是有必要去了解一下.比如在项目中经常用到集合,遍历集合可以试下lambda表达式,经常还要对集合进行 ...

  4. 通过stream去重_分享几种 Java8 中通过 Stream 对列表进行去重的方法

    几种列表去重的方法 在这里我来分享几种列表去重的方法,算是一次整理吧,如有纰漏,请不吝赐教.1. Stream 的distinct()方法 distinct()是Java8中 Stream 提供的方法 ...

  5. 玩转Java8中的 Stream 之从零认识 Stream

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:litesky www.jianshu.com/p/11c9 ...

  6. Java8 中通过 Stream 对列表进行去重的几种方法

    点击关注公众号,实用技术文章及时了解 来源:juejin.cn/post/6844903842132262926 在这里我来分享几种列表去重的方法,算是一次整理吧,如有纰漏,请不吝赐教. 1. Str ...

  7. java8中的Stream流式操作总结,List转Map或List转LinkedHashMap使用Collectors.groupingBy用法

    前言背景描述: 开发使用本来是直接使用数据库的依据SQL进行group By获取到数据表的分组的一个字段的字符串,可是后来字符串越来越多越长,导致的最后的后面长度超多1024个汉字就会被截取,所以需要 ...

  8. Java8中的Stream流

    定义 什么是Stream流,Java doc中是这样写的 A sequence of elements supporting sequential and parallel aggregate ope ...

  9. java8中的流(Stream)

    流式编程爱 撸码就是快,流式编程好 代码传家宝 Stream API 概念: Stream 流处理,首先要澄清的是 java8 中的 Stream 与 I/O 流 InputStream 和 Outp ...

最新文章

  1. [JS] 事件冒泡,阻止事件冒泡,事件的三个阶段(捕获,目标,冒泡)
  2. DateTime时间格式转换为Unix时间戳格式
  3. php 复选框默认选中的值,PHP复选框默认值是什么 - php
  4. 详解:UML类图符号、各种关系说明以及举例
  5. AlamofireJsonToObjects+EVReflection:一步解决JSON解析
  6. python excel读取出错_python读取excel数据出错
  7. 键值的 key 和 value 允许为null吗
  8. Java实现AVL平衡树
  9. 车牌识别之车牌定位(方案总结)
  10. SQL Server中的text类型字段要如何查询?
  11. python读取坐标文本文件_使用python读取txt坐标文件生成挖空矿山_探矿批量
  12. 图解如何安装Oracle 10g的
  13. 缓冲大小 设置_【设计】小知识点:各种水箱的选型设计(二)缓冲水箱
  14. Java创建多线程的方法总结
  15. JAVAEE智慧树第二次作业
  16. BScroll warn 】EventEmitter has used unknown event type: “pullingUp“解决方法:看bs文档
  17. 人的命,三分天注定,七分靠打拼,有梦就会红,爱拼才会赢
  18. office2016显示已经激活,但每次打开都跳出激活页面
  19. dedecms教程:龙书浩最新DedeCmsV5.7建站仿站VIP视频教程免费下载
  20. http协议如何获取请求参数

热门文章

  1. Java并发编程笔记—基础知识—实用案例
  2. SQL Server 2008存储结构之GAM、SGAM
  3. mongodb对数组元素及内嵌文档进行增删改查操作(转)
  4. 学术牛人教你如何阅读外国文献
  5. bzoj4195 noi2015 day1 t1
  6. 安装Visual Studio 2005 SP1时遇到1718错误
  7. 反流氓软件运动为何变了味
  8. 360网络自动化运维
  9. SpringCloud 微服务网关Gateway 动态路由配置
  10. 自编fun函数求 N*N矩阵四周元素的平均值