引子
for (Msg msg : msgSet) {
list.remove(msg);
}
众所周知,ArrayList删除是比较耗时的,原因就是remove会遍历对比对象,再删除。而非通过hashcode查找元素。
当list的Size非常大的时候,这个循环将会让程序耗时很久。
如果采用空间换时间的策略的话,速度就会大大提升。或者将list放入set集合中,在set集合删除,这样速度也会提升。
除此之外,也可以采用并行流来操作,充分利用CPU多核的优势。
list.parallelStream().forEachOrder(msg ->{
list.remove(msg);
});
当然,能避免调用list.remove就要尽量避免,此处只是以此来介绍并行流。
流
Stream
并不直接存储数据,通常是由集合或数组转化而来。
list.stream();
IntStream.range(1,10);
当我们对流进行filter
,sort
,distinct
操作时,都会得到一个新的stream
,这些聚合操作被称之为中间操作。
流的创建
// 使用 Stream.of 创建流
Stream<Integer> intStream = Stream.of(1,3,2,2, 3, 4, 5);
intStream.filter(integer -> {return integer > 1;}).distinct().sorted().forEachOrdered(System.out::print);
// 使用 builder 创建流
Stream<Object> buildStream = Stream.builder().add(1).add(2).add(3).build();
buildStream.forEach(System.out::print);
// 使用generate创建无限流。
Stream<Integer> generateStream = Stream.generate(new Random()::nextInt);
generateStream.limit(100L).sorted().forEach(System.out::println);
// 使用 seed 创建无限流
Stream<Integer> iterateStream = Stream.iterate(2, num -> num << 1);
iterateStream.limit(20L).forEach(System.out::println);
// 使用 concat 合并流
Stream<Integer> concatStream = Stream.concat(Stream.of(1,2,3), Stream.of(4,3,5,6,7));
concatStream.forEach(System.out::println);
// list 生成流
ArrayList<Integer> list = new ArrayList<>();
list.stream().forEach(System.out::println);
流的中间方法
-
filter
:用于过滤。参数是Predicate
接口,实现test
方法即可。// 两者是等同的 list.stream().filter(i->i%2==0); list.stream().filter(new Predicate<Integer>() { @Override public boolean test(Integer integer) { return integer%2==0; } });
-
sorted
: 排序。如果类实现了Comparable
接口,那么可以直接调用空参的sort
方法。如果没有则会报错,需要传入Comparator
。 -
distinct
:去重。 -
map
:元素转化。map
的方法参数为Function
函数接口,Function
中的接口方法R apply(T t)
的目的是将流中的元素转换为R类型的元素。Stream<Integer> intStream = Stream.of(1,3, 2 , 2 , 3, 4, 5); Stream<String> stringStream = intStream.map(t -> String.valueOf(t * 2));
flatMap
与map
非常相似,不同的是map
是将流中的元素转成R类型的元素,返回流。而flatMap
是将流中的数据计算后的得到的流再次合并成一个流。 -
skip
:跳过前n个 -
limit
: 取前n个
流的最终方法
-
sum
:求和 -
count
:计数 -
max
:最大值 -
min
:最小值 -
allMatch
:全部匹配,参数是Predicate
-
anyMatch
:任一匹配 -
noneMatch
:没有匹配 -
collect
:将Stream
流中的数据收集到目标容器中collect
有三个参数:-
Supplier
:容纳数据的对象 -
ObjIntConsumer
:Supplier
如何处理数据 -
BiConsumer
:并行流的情况下,多个Supplier
如何合并
// 并行流 collect IntStream intStream = IntStream.rangeClosed(1, 10).parallel(); ArrayList<Integer> collect = intStream.collect(ArrayList::new, (list, i) -> list.add(i), (l1, l2) -> {}); System.out.println(collect.toString()); // [1] // IntStream intStream = IntStream.rangeClosed(1, 10).parallel(); ArrayList<Integer> collect = intStream.collect(ArrayList::new, (list, i) -> list.add(i), (l1, l2) -> l1.addAll(l2)); System.out.println(collect.toString());//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-
-
reduce
:将Stream
中的数据归纳为一个对象