@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)的引入使得集合的处理更加高效。流操作允许在一次遍历中对集合进行多个操作,这样可以减少遍历的次数,提高性能。