Stream流
数据源
数据处理
数据结果
filter 过滤
limit 取前几
sorted 排序
max、min、count
map 对集合中的元素进行特定的操作
reduce 将所有的元素按照传入的逻辑进行处理,并且会把结果合并成一个值进行返回
collection 基于目标集合生成新的数组
public class Test {
public static void main(String[] args) {
List<User> list = Arrays.asList(
new User("小明", 20, 3000),
new User("小红", 20, 2000),
new User("小亮", 22, 5000)
);
// stream 流
Predicate<User> predicate1 = user -> user.getAge() < 21;
Predicate<User> predicate2 = user -> user.getAge() < 2000;
List<User> collect = list.stream()
.filter(predicate1.or(predicate2))
.collect(Collectors.toList());
System.out.println(collect);
// filter 过滤
List<String> testList = Arrays.asList("Hello", "World", "Java");
testList.stream()
.filter(str -> str.length() >= 5)
.forEach(str -> System.out.println(str));
// limit
testList.stream()
.limit(2)
.forEach(str -> System.out.println(str));
// sorted 排序
List<Integer> integerList = Arrays.asList(1, 6, 5, 4, 2, 3);
integerList.stream()
.sorted()//正序
.sorted(Comparator.reverseOrder())//反序
.forEach(num -> System.out.println(num));
// max、min、count
System.out.println("最大的数:" + integerList.stream().max(Integer::compareTo).get());
System.out.println("最小的数:" + integerList.stream().min(Integer::compareTo).get());
System.out.println("集合长度:" + integerList.stream().count());
// map 对集合中的元素进行特定的操作
integerList.stream()
.map(num -> num + 10)
.forEach(num -> System.out.println(num));
// reduce 将所有的元素按照传入的逻辑进行处理,并且会把结果合并成一个值进行返回
System.out.println("集合中的元素求和为:" + integerList.stream().reduce((sum, num) -> sum + num).get());
// collection 基于目标集合生成新的数组
List<Integer> collectList = integerList.stream()
.filter(num -> num % 2 == 0)
.collect(Collectors.toList());
System.out.println("偶数集合:" + collectList);
}
}
使用Stream流对集合进行分页
// 通过流处理进行分页
List<String> subList = denyList.stream()
.skip((pageNo-1)*pageSize) // 跳过(第pageNo页-1)*每页多少条 例如:第一页就是跳过0条,第二页跳过1*每页的条数...
.limit(pageSize)// 取pageSize条数据
.collect(Collectors.toList());// 将过滤的数据输出成集合
对集合中实体中某个字段进行去重
// 使用
List<TopicReplyRecord> filterDistinctList = notUserNameCommentsList.stream()
.filter(distinctByKey(TopicReplyRecord::getReply_record_id))
.collect(Collectors.toList());
private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
Stream流性能分析
1、性能分析
在少数据量的处理场景中(size <= 1000)
stream 的处理效率是不如传统的 iterator 外部迭代器处理速度快的,但是实际上这些处理任务本身运行时间都低于毫秒,这点效率的差距对普通业务几乎没有影响,反而 stream 可以使得代码更加简洁;
在大量数据(size > 10000)
stream 的处理效率会高于 iterator,特别是使用了并行流,在 cpu 恰好将线程分配到多个核心的条件下(当然 parallel stream 底层使用的是 JVM 的 ForkJoinPool,这东西分配线程本身就很玄学),可以达到一个很高的运行效率,然而实际普通业务一般不会有需要迭代高于 10000 次的计算;
Parallel Stream (并行流)
Parallel Stream 受引 CPU 环境影响很大,当没分配到多个 cpu 核心时,加上引用 forkJoinPool 的开销,运行效率可能还不如普通的 Stream;
2、使用建议
简单的迭代逻辑,可以直接使用 iterator,对于有多步处理的迭代逻辑,可以使用 stream,损失一点几乎没有的效率,换来代码的高可读性是值得的;
单核 cpu 环境,不推荐使用 parallel stream,在多核 cpu 且有大数据量的条件下,推荐使用 paralle stream;
stream 中含有装箱类型,在进行中间操作之前,最好转成对应的数值流,减少由于频繁的拆箱、装箱造成的性能损失。
转载:https://blog.csdn.net/hlzdbk/article/details/128507827