实现自己的收集器以获得更好的性能

博客主要围绕Java8展开,实现将数字按质数与非质数分区,创建了一个收集器并测试其性能,还将自己实现的收集器与partitioningBy工厂方法创建的收集器进行性能比较,多次运行结果显示,自己实现的收集器性能提升约35% - 40%。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将数字按质数与非质数分区

package streams;

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.IntStream;

public class PrimeNumber {

    public static boolean isPrime1(int num) {
        int sqrtNum = (int) Math.sqrt(num);
        return IntStream.rangeClosed(2, sqrtNum)
                .noneMatch(i -> num % i == 0);
    }

    public static boolean isPrime2(List<Integer> primes, int num) {
        int sqrtNum = (int) Math.sqrt(num);
        return takeWhile(primes, i -> i <= sqrtNum)
                .stream()
                .noneMatch(i -> num % i == 0);
    }

    public static <A> List<A> takeWhile(List<A> list, Predicate<A> p) {
        int i = 0;
        for (A l : list) {
            if (!p.test(l)) {
                return list.subList(0, i);
            }
            i++;
        }
        return list;
    }
}

实现一个收集器并测试性能

package streams;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.IntStream;

import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH;
import static java.util.stream.Collectors.partitioningBy;

/**
 * 第一步,定义Collector类的签名
 */
public class MyCollector implements Collector<Integer, Map<Boolean, List<Integer>>,
        Map<Boolean, List<Integer>>> {

    /**
     * 第二步,实现规约过程
     *
     * @return
     */
    @Override
    public Supplier<Map<Boolean, List<Integer>>> supplier() {
        return () -> new HashMap<Boolean, List<Integer>>() {{
            put(true, new ArrayList<>());
            put(false, new ArrayList<>());
        }};
    }

    @Override
    public BiConsumer<Map<Boolean, List<Integer>>, Integer> accumulator() {
        return (Map<Boolean, List<Integer>> acc, Integer num) -> {
            acc.get(PrimeNumber.isPrime2(acc.get(true), num))
                    .add(num);
        };
    }

    /**
     * 第三步,让并行器并行工作(如果可能)
     *
     * @return
     */

    @Override
    public BinaryOperator<Map<Boolean, List<Integer>>> combiner() {
        return (Map<Boolean, List<Integer>> map1,
                Map<Boolean, List<Integer>> map2) -> {
            map1.get(true).addAll(map2.get(true));
            map1.get(false).addAll(map2.get(false));
            return map1;
        };
    }

    /**
     * 第四步,finisher方法和收集器的characteristics方法
     *
     * @return
     */
    @Override
    public Function<Map<Boolean, List<Integer>>,
            Map<Boolean, List<Integer>>> finisher() {
        return Function.identity();
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH));
    }




    public static Map<Boolean, List<Integer>> partitionPrimes(int n) {
        return IntStream.rangeClosed(2, n).boxed()
                .collect(partitioningBy(i -> PrimeNumber.isPrime1(i)));
    }

    public static Map<Boolean, List<Integer>> partitionPrimesWithCustomCollector(int n) {
        return IntStream.rangeClosed(2, n).boxed().collect(new MyCollector());
    }

    public static long testPerf (Function<Integer,Map<Boolean, List<Integer>>> adder, int n) {
        long fast = Long.MAX_VALUE;
        for (int i = 0; i < 10; i++) {
            long start = System.nanoTime();
            adder.apply(n);
            long spendTime = (System.nanoTime() - start) / 1_000_000;

            if (spendTime < fast)
                fast = spendTime;
        }
        return fast;
    }

    public static void main(String[] args) {

        System.out.println("Collector spend " +
                testPerf(MyCollector::partitionPrimes, 1000_000) + " msecs ");

        System.out.println("MyCollector spend " +
                testPerf(MyCollector::partitionPrimesWithCustomCollector, 1000_000) + " msecs ");
        
    }
}

比较自己实现的收集器与partitioningBy工厂方法创建的收集器的性能
在我的电脑
在这里插入图片描述
多次运行结果如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试的次数不多,提升的性能大概在35%~40%之间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值