JAVA8 Stream新特性的玩法

Stream lambda

Stream 流
将集合转换为 流 ,元素序列
通过声明方式,对集合中的每个元素进行一系列并行或串行的流水线操作。

数据源 流 中间操作 终端操作

List 集合转换为 Stream 类型的流

过滤 排序 类型转换
终端操作,可以把 Stream 转换回集合类型 或者 打印 计数 求和 求平均 计算最大值最小值 等

List newList = list.stream().map(Person::getName).sorted().limit(10).collect(Collectors.toList());

List list = Arrays.asList(“x”,“a”,“d”,“c”);
Stream stream = list.stream().sorted().limit(3);
List newList1 = stream.collect(Collectors.toList());
// java.lang.IllegalStateException: stream has already been operated upon or closed
// List newList2 = stream.collect(Collectors.toList());

流只能迭代一次

stream()
parallelStream()

filter(T -> boolean)
保留 boolean 为 true 的元素

保留年龄为 20 的 person
list = list.stream().filter(person -> person.getAge() == 20).collect(toList());

distinct() 去除重复元素
通过 equals 方法 判断两个元素是否相等

sorted()
sorted((T, T) -> int)

如果流中的元素实现了 Comparable 接口,可以直接调用 sorted() 排序

根据年龄大小来比较:
list = list.stream().sorted((p1, p2) -> p1.getAge() - p2.getAge()).collect(toList());

list = list.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(toList());

limit(long n) 返回前 n 个元素
skip(long n) 跳 前 n 个元素

map(T -> R)
将流中的每一个元素 T 映射为 R(类似类型转换)

List newlist = list.stream().map(Person::getName).collect(toList());

flatMap(T -> Stream)
将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流

List list = new ArrayList<>();
list.add(“are you ok”);
list.add(“i am fine”);

list = list.stream().map(s -> s.split(" ")).flatMap(Arrays::stream).collect(toList());

anyMatch(T -> boolean)
boolean b = list.stream().anyMatch(person -> person.getAge() == 20);

allMatch(T -> boolean)
noneMatch(T -> boolean)

Optional findAny()
Optional findFirst()

reduce((T, T) -> T) 和 reduce(T, (T, T) -> T)

用于组合流中的元素,如求和,求积,求最大值等

求和

计算年龄总和:
int sum = list.stream().map(Person::getAge).reduce(0, (a, b) -> a + b);
int sum = list.stream().map(Person::getAge).reduce(0, Integer::sum);
第一个参数为初始值

可以不提供初始值 ,返回 Optional
Optional sum = list.stream().map(Person::getAge).reduce(Integer::sum);

long count()

collect()
collect(toList()) collect(toSet())

forEach
list.stream().forEach(System.out::println);

数值流
IntStream, DoubleStream, LongStream
使用原始类型 int,double,long 避免 Box unbox

流转换为数值流
mapToInt(T -> int) : return IntStream
mapToDouble(T -> double) : return DoubleStream
mapToLong(T -> long) : return LongStream

IntStream intStream = list.stream().mapToInt(Person::getAge);

数值流转换为流
Stream stream = intStream.boxed();

数值流方法
sum()
max()
min()
average()

数值范围
range 和 rangeClosed

闭区间 半开半闭区间

1 到 10 求和
IntStream intStream = IntStream.rangeClosed(1, 10);
int sum = intStream.sum();

Optional 类 解决空指针问题

isPresent() 值存在时返回 true
get() 获取当前值,值不存抛异常
orElse(T) 值存在时返回该值,否则返回 T 值

创建流

Stream stream = Stream.of(“hello”, “Java8”);
Stream.empty()

根据数组创建流

Arrays.stream(T[])
Arrays.stream(int[])
Arrays.stream(double[])
Arrays.stream(long[])

// 只取索引第 1 到第 2 位 , 切片 [1,3)
int[] a = {1, 2, 3, 4};
Arrays.stream(a, 1, 3).forEach(System.out::println);

文件生成流
Stream stream = Files.lines(Paths.get(“data.txt”));

函数生成流
首元素为 0,之后依次加 2
Stream.iterate(0, n -> n + 2)
Stream.generate(Math :: random)
元素全为 1
Stream.generate(() -> 1)

collect 收集数据

toList
toSet
toCollection
toMap

List newlist = list.stream.collect(toList());

// Map Key 重复,报错
Map<Integer, Person> map = list.stream().collect(toMap(Person::getAge, p -> p));

汇总

long count = list.stream().collect(counting());
long count = list.stream().count();

summingInt ,summingLong ,summingDouble

int sum = list.stream().collect(summingInt(Person::getAge));

int sum = list.stream().mapToInt(Person::getAge).sum();

int sum = list.stream().map(Person::getAge).reduce(Interger::sum).get();

函数式编程通常提供多种方式来完成同一种操作

averagingInt,averagingLong,averagingDouble
Double average = list.stream().collect(averagingInt(Person::getAge));
OptionalDouble average = list.stream().mapToInt(Person::getAge).average();

注意返回类型不同!!!

summarizingInt,summarizingLong,summarizingDouble

IntSummaryStatistics stat = list.stream().collect(summarizingInt(Person::getAge));

取最值

Optional optional = list.stream().collect(maxBy(comparing(Person::getAge)));
Optional optional = list.stream().max(comparing(Person::getAge));

joining 连接字符串

String s = list.stream().map(Person::getName).collect(joining());

String s = list.stream().map(Person::getName).collect(joining(","));

groupingBy 分组

Map<Integer, List> map = list.stream().collect(groupingBy(Person::getAge));

按照年龄 age 分组,年龄相同的归为一组

多级分组

Map<Integer, Map<T, List>> map = list.stream().collect(groupingBy(Person::getAge, groupingBy(…)));

按组聚合
Map<Integer, Integer> map = list.stream().collect(groupingBy(Person::getAge, summingInt(Person::getAge)));

partitioningBy 分区
分区按照 true 和 false 来分

根据年龄是否小于等于20来分区
Map<Boolean, List> map = list.stream().collect(partitioningBy(p -> p.getAge() <= 20));

list.parallelStream() 并行流

流的可分解性

ArrayList 和 LinkedList, 前者在分解方面占优

性能

Stream 的性能可能会低于传统的循环或者迭代器,甚至会低很多。

创建流的开销 流只能迭代一次 重复创建流 box unbox

函数式编程 主要是为了提高编码开发效率 及 增强代码可读性

Java performance tutorial – How fast are the Java 8 streams?
https://jaxenter.com/java-performance-tutorial-how-fast-are-the-java-8-streams-118830.html
转载于:http://codefun007.xyz/view/article_detail.htm?id=543

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值