Java8 对List中的各个字段进行数据汇总

@Slf4j
@SpringBootTest
public class DemoTest {

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class TestPojo {
        private BigDecimal money1;
        private BigDecimal money2;
        private BigDecimal money3;
        private BigDecimal money4;
        private BigDecimal money5;

        public List<TestPojo> getList() {
            List<TestPojo> list = new ArrayList<>();
            for (int i = 0; i < 5000000; i++) {
                BigDecimal b = BigDecimal.valueOf(Math.random() * 100);
                list.add(new TestPojo(b, b, b, b, b));
            }
            return list;
        }
    }
   
    @Test
    public static void test() {
        List<TestPojo> list = new TestPojo().getList();

        StopWatch stopWatch = new StopWatch("任务名称");
        // 方式一
        stopWatch.start();
        List<BigDecimal> sumList2 = Arrays.asList(
                list.stream().map(TestPojo::getMoney1).reduce(BigDecimal.ZERO, BigDecimal::add),
                list.stream().map(TestPojo::getMoney2).reduce(BigDecimal.ZERO, BigDecimal::add),
                list.stream().map(TestPojo::getMoney3).reduce(BigDecimal.ZERO, BigDecimal::add),
                list.stream().map(TestPojo::getMoney4).reduce(BigDecimal.ZERO, BigDecimal::add),
                list.stream().map(TestPojo::getMoney5).reduce(BigDecimal.ZERO, BigDecimal::add)
        );
        stopWatch.stop();
        System.out.println(stopWatch.getLastTaskTimeMillis());

        // 方式二
        stopWatch.start();
        AtomicReference<BigDecimal> money1Sum = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> money2Sum = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> money3Sum = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> money4Sum = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> money5Sum = new AtomicReference<>(BigDecimal.ZERO);
        list.stream().forEach(f -> {
            money1Sum.set(money1Sum.get().add(f.getMoney1()));
            money2Sum.set(money2Sum.get().add(f.getMoney2()));
            money3Sum.set(money3Sum.get().add(f.getMoney3()));
            money4Sum.set(money4Sum.get().add(f.getMoney4()));
            money5Sum.set(money5Sum.get().add(f.getMoney5()));
        });
        List<BigDecimal> sumList1 = Arrays.asList(money1Sum.get(), money2Sum.get(), money3Sum.get(), money4Sum.get(), money5Sum.get());

        stopWatch.stop();
        System.out.println(stopWatch.getLastTaskTimeMillis());
    }

}

如上代码,通过两种方式汇总数据,第一种再一个循环里面对多个字段分别汇总,第二个针对每个字段单独循环汇总数据,测试过100万到500万数据,为什么两种方式的耗时相差不大?

两种方式的耗时相差不大的原因是因为在Java 8中,流式操作(Stream API)的引入使得集合的处理更加高效。流操作允许在一次遍历中对集合进行多个操作,这样可以减少遍历的次数,提高性能。