package com.qbb.threadpool; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; /** * @author QiuQiu&LL (个人博客:https://www.cnblogs.com/qbbit) * @version 1.0 * @date 2022-07-23 20:19 * @Description: */ public class Java8NewFeatureStream { public static void main(String[] args) { // 创建Stream方式一 : 通过集合 List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6); // 获取串行流 Stream<Integer> stream = list.stream(); // 获取一个并行流 Stream<Integer> parallelStream = list.parallelStream(); // 创建Stream方式二 : 通过数组 String[] arr = new String[]{"a", "b", "c"}; Stream<String> arrStream = Arrays.stream(arr); // 创建Stream方式三 : 通过Stream.of() Stream<String> streamOf = Stream.of("x", "y", "z"); // 创建Stream方式四 : 通过Stream.iterate(),创建无限流 Stream<Integer> integerStream = Stream.iterate(0, q -> q + 1).limit(5); integerStream.forEach(System.out::println); //生成10个随机数 Stream<Double> stream1 = Stream.generate(Math::random).limit(10); stream1.forEach(System.out::println); } }
fifter(Predicate<? super T> predicate)
: 过滤,保留满足条件分元素public static void main(String[] args) { // 创建流 List<Integer> asList = Arrays.asList(1, 2, 3, 4, 5, 6); asList.stream() .filter(q -> q % 2 ==0) // filter:过滤,保留符合条件的元素 .forEach(System.out::println); // forEach:内部迭代,终止操作输出每一个元素 }
distinct ()
: 去除重复的元素// 测试类 class User { private String name; private int age; public User() { } public User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", 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; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return age == user.age && Objects.equals(name, user.name); } @Override public int hashCode() { return Objects.hash(name, age); } } public static void main(String[] args) { // 创建流 List<Integer> asList = Arrays.asList(1, 2, 3, 4, 5, 6, 2, 5); asList.stream().distinct().forEach(System.out::println); List<User> userList = new ArrayList<>(); // 测试一下对象类型 for (int i = 0; i < 5; i++) { User user = new User("qiuqiu"+i,18+i); userList.add(user); } User qiuqiu3 = new User("qiuqiu3", 21); userList.add(qiuqiu3); userList.stream().distinct().forEach(System.out::println); }
limit(long maxSize)
: 获取指定maxSize个元素public static void main(String[] args) { // 创建流 List<Integer> asList = Arrays.asList(1, 2, 3, 4, 5, 6, 2, 5); asList.stream().limit(3).forEach(System.out::println); }
skip(long n)
: 跳过前n个元素public static void main(String[] args) { // 创建流 List<Integer> asList = Arrays.asList(1, 2, 3, 4, 5, 6, 2, 5); long count = asList.stream() .skip(3) // 跳过前三个元素 // .findFirst() // 获取跳过操作后的第一个元素 // .findAny() // 获取跳过操作后的任意一个元素 .count(); // 获取剩余元素个数 // System.out.println("result = " + result); System.out.println("count = " + count); }
sorted()/sorted(Comparator<? super T> comparator)
: 排序public static void main(String[] args) { // 创建流 List<Integer> asList = Arrays.asList(4, 5, 6, 2, 1, 2, 3, 5); // 默认排序 asList.stream().sorted().forEach(System.out::println); System.out.println("======================================================="); // 指定比较器排序 // asList.stream().sorted((o1,o2) -> o1.compareTo(o2)).forEach(System.out::println); asList.stream().sorted(Integer::compareTo).forEach(System.out::println); }
map
:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。public static void main(String[] args) { // 创建流 List<Integer> asList = Arrays.asList(4, 5, 6, 2, 1, 2, 3, 5); // map asList.stream().map(q -> { String str; if(q%2 == 0){ str = q+"qiu"; }else { str = q + "ll"; } return str; }).forEach(System.out::println); }
mapToInt(ToIntFunction<? super T> mapper)
mapToDouble(ToDoubleFunction<? super T> mapper)
mapToLong(ToLongFunction<? super T> mapper)
flatMapToInt(Function<? super T, ? extends IntStream> mapper)
flatMapToLong(Function<? super T, ? extends LongStream> mapper)
flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper)
flatMap
:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。public static void main(String[] args) { // 创建流 String[] arr = new String[]{"a,b,c","x,y,z"}; // flatMap Arrays.stream(arr).flatMap(q -> { String[] split = q.split(","); // 把一个流拆分多个流然后又合并为一个流 Stream<String> stream = Arrays.stream(split); return stream; }).forEach(System.out::println); }
peek
:如同于map,能得到流中的每一个元素。但map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值。public static void main(String[] args) { // 创建流 User zs = new User("zs", 18); User ls = new User("ls", 28); List<User> userList = Arrays.asList(zs, ls); userList.stream() .peek(q -> q.setAge(22)) .forEach(System.out::println); }
当然还有其他的一些操作,这里就不一一演示了
allMatch
:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
noneMatch
:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
anyMatch
:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
findFirst
:返回流中第一个元素
findAny
:返回流中的任意元素
count
:返回流中元素的总个数
max
:返回流中元素最大值
min
:返回流中元素最小值
public static void main(String[] args) { // 创建流 List<Integer> asList = Arrays.asList(4, 5, 6, 2, 1, 2, 3, 5); boolean allMatch = asList.stream().allMatch(q -> q > 0); System.out.println("allMatch = " + allMatch); boolean noneMatch = asList.stream().noneMatch(q -> q < 0); System.out.println("noneMatch = " + noneMatch); boolean anyMatch = asList.stream().anyMatch(q -> q % 2 == 0); System.out.println("anyMatch = " + anyMatch); Integer findFirst = asList.stream().findFirst().get(); System.out.println("findFirst = " + findFirst); Integer findAny = asList.stream().findAny().get(); System.out.println("findAny = " + findAny); // long count = asList.stream().count(); long count = asList.size(); System.out.println("count = " + count); Integer max = asList.stream().max(Comparator.comparingInt(o -> o)).get(); System.out.println("max = " + max); Integer min = asList.stream().min(Integer::compareTo).get(); System.out.println("min = " + min); }
Optional<T> reduce(BinaryOperator<T> accumulator)
:第一次执行时,accumulator函数的第一个参数为流中的第一个元素,第二个参数为流中元素的第二个元素;第二次执行时,第一个参数为第一次函数执行的结果,第二个参数为流中的第三个元素;依次类推。
T reduce(T identity, BinaryOperator<T> accumulator)
:流程跟上面一样,只是第一次执行时,accumulator函数的第一个参数为identity,而第二个参数为流中的第一个元素。
<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner)
:在串行流(stream)中,该方法跟第二个方法一样,即第三个参数combiner不会起作用。在并行流(parallelStream)中,我们知道流被fork join出多个线程进行执行,此时每个线程的执行流程就跟第二个方法reduce(identity,accumulator)一样,而第三个参数combiner函数,则是将每个线程的执行结果当成一个新的流,然后使用第一个方法reduce(accumulator)流程进行规约。
public static void main(String[] args) { // 创建流 List<Integer> asList = Arrays.asList(1, 2, 3, 4, 5); Integer one = asList.stream().reduce(Integer::sum).get(); System.out.println("one = " + one); Integer two = asList.stream().reduce(100, Integer::sum); System.out.println("two = " + two); Integer three = asList.parallelStream().reduce(100, Integer::sum, (x, y) -> x * y); System.out.println("three = " + three); }
collect
:接收一个Collector实例,将流转化为其他形式,常用的List、Set、Map、Collection。
toCollection toList() toSet() toMap
: 将输入元素累积到一个集合中public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); list.replaceAll(q -> q > 5 ? q + 10 : q); System.out.println("list = " + list); list.sort((o1, o2) -> o1 - o2); // 转Collection Collection<Integer> collection = list.parallelStream().collect(Collectors.toCollection(HashSet::new)); // 转List List<Integer> integerList = list.parallelStream().collect(Collectors.toList()); // 转Set Set<Integer> set = list.parallelStream().collect(Collectors.toSet()); // 转Map Map<Integer, Integer> map = list.parallelStream().collect(Collectors.toMap(item -> item, integer -> integer)); }
joining
: 连接字符串// joining List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f", "g"); String result = list.parallelStream().collect(Collectors.joining(",", "[", "]")); System.out.println("result = " + result);
mapping/flatMapping
: 它将Function应用于输入元素,然后将它们累积到给定的CollectorSet<String> setStr = Stream.of("a", "a", "b") .collect(Collectors.mapping(String::toUpperCase, Collectors.toSet())); System.out.println(setStr); // [A, B] Set<String> setStr1 = Stream.of("a", "a", "b") .collect(Collectors.flatMapping(s -> Stream.of(s.toUpperCase()), Collectors.toSet())); System.out.println(setStr1); // [A, B]
collectingAndThen
: 返回一个收集器,该收集器将输入元素累积到给定的收集器中,然后执行其他完成功能List<String> strList2 = Lists.newArrayList("1", "2", "10", "100", "20", "999"); List<String> unmodifiableList = strList2.parallelStream() .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)); System.out.println(unmodifiableList); // [1, 2, 10, 100, 20, 999]
counting
: 计数Long evenCount = Stream.of(1, 2, 3, 4, 5).filter(x -> x % 2 == 0).collect(Collectors.counting()); System.out.println(evenCount); // 2
minBy
: 根据给定的比较器返回最小元素Optional<Integer> min = Stream.of(1, 2, 3, 4, 5).collect(Collectors.minBy((x, y) -> x - y)); System.out.println(min); // Optional[1]
maxBy
: 它根据给定的比较器返回最大元素Optional<Integer> max = Stream.of(1, 2, 3, 4, 5).collect(Collectors.maxBy((x, y) -> x - y)); System.out.println(max); // Optional[5]
summingInt/summingLong/summingDouble
: 求总和List<String> strList3 = Arrays.asList("1", "2", "3", "4", "5"); Integer sum = strList3.parallelStream().collect(Collectors.summingInt(Integer::parseInt)); System.out.println(sum); // 15 Long sumL = Stream.of("12", "23").collect(Collectors.summingLong(Long::parseLong)); System.out.println(sumL); // 35 Double sumD = Stream.of("1e2", "2e3").collect(Collectors.summingDouble(Double::parseDouble)); System.out.println(sumD); // 2100.0
averagingInt/averagingLong/averagingDouble
: 求平均值List<String> strList4 = Arrays.asList("1", "2", "3", "4", "5"); Double average = strList4.parallelStream().collect(Collectors.averagingInt(Integer::parseInt)); System.out.println(average); // 3.0 Double averageL = Stream.of("12", "23").collect(Collectors.averagingLong(Long::parseLong)); System.out.println(averageL); // 17.5 Double averageD = Stream.of("1e2", "2e3").collect(Collectors.averagingDouble(Double::parseDouble)); System.out.println(averageD); // 1050.0
groupingBy
: 分组Map<Integer, List<Integer>> mapGroupBy = Stream.of(1, 2, 3, 4, 5, 4, 3).collect(Collectors.groupingBy(x -> x * 10)); System.out.println(mapGroupBy); // {50=[5], 20=[2], 40=[4, 4], 10=[1], 30=[3, 3]}
groupingByConcurrent
: 分组,是并发和无序的Map<Integer, List<Integer>> mapGroupBy = Stream.of(1, 2, 3, 4, 5, 4, 3).collect(Collectors.groupingByConcurrent(x -> x * 10)); System.out.println(mapGroupBy); // {50=[5], 20=[2], 40=[4, 4], 10=[1], 30=[3, 3]}
partitioningBy
: 返回一个Collector,它根据Predicate对输入元素进行分区,并将它们组织成Map <Boolean,List >Map<Boolean, List<Integer>> mapPartitionBy = Stream.of(1, 2, 3, 4, 5, 4, 3).collect(Collectors.partitioningBy(x -> x % 2 == 0)); System.out.println(mapPartitionBy); // {false=[1, 3, 5, 3], true=[2, 4, 4]}
BinaryOperator
: 返回一个收集器,它在指定的BinaryOperator下执行其输入元素的减少。这主要用于多级缩减,例如使用groupingBy()和partitioningBy()方法指定下游收集器Map<Boolean, Optional<Integer>> reducing = Stream.of(1, 2, 3, 4, 5, 4, 3).collect(Collectors.partitioningBy( x -> x % 2 == 0, Collectors.reducing(BinaryOperator.maxBy(Comparator.comparing(Integer::intValue))))); System.out.println(reducing); // {false=Optional[5], true=Optional[4]}
summarizingInt
: 返回统计数据:min, max, average, count, sumIntSummaryStatistics summarizingInt = Stream.of("12", "23", "35") .collect(Collectors.summarizingInt(Integer::parseInt)); System.out.println(summarizingInt); //IntSummaryStatistics{count=3, sum=70, min=12, average=23.333333, max=35}