怎么在Java8中使用Collectors实现一个求和功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
自定义工具类
public class MyCollectors { private MyCollectors() { }// public static <T> Collector<T, ?, BigDecimal> summingBigDecimal(Function<? super T, BigDecimal> mapper) {} // BigDecimal 类型的集合求和 public static <T> Collector<T, ?, BigDecimal> summingBigDecimal(ToBigDecimalFunction<? super T> mapper) { return new CollectorImpl<>( () -> new BigDecimal[] { BigDecimal.ZERO }, (a, t) -> a[0] = a[0].add(mapper.applyAsInt(t)), (a, b) -> { a[0] = a[0].add(b[0]); return a; }, a -> a[0], Collections.emptySet() ); } static class CollectorImpl<T, A, R> implements Collector<T, A, R> { // 创建一个计算用的容器 private final Supplier<A> supplier; // 计算逻辑 private final BiConsumer<A, T> accumulator; // 合并逻辑 private final BinaryOperator<A> combiner; // 返回最终计算值 private final Function<A, R> finisher; // 空Set private final Set<Characteristics> characteristics; CollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Function<A, R> finisher, Set<Characteristics> characteristics) { this.supplier = supplier; this.accumulator = accumulator; this.combiner = combiner; this.finisher = finisher; this.characteristics = characteristics; } CollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Set<Characteristics> characteristics) { this(supplier, accumulator, combiner, castingIdentity(), characteristics); } @Override public BiConsumer<A, T> accumulator() { return accumulator; } @Override public Supplier<A> supplier() { return supplier; } @Override public BinaryOperator<A> combiner() { return combiner; } @Override public Function<A, R> finisher() { return finisher; } @Override public Set<Characteristics> characteristics() { return characteristics; } } @SuppressWarnings("unchecked") private static <I, R> Function<I, R> castingIdentity() { return i -> (R) i; }}
自定义函数式接口
@FunctionalInterfacepublic interface ToBigDecimalFunction<T> { BigDecimal applyAsInt(T value);}
测试入口
public class AnswerApp { public static void main(String[] args) { List<BigDecimal> list = Lists.newArrayList(); for (int i = 0; i < 24; i++) { list.add(BigDecimal.valueOf(i + 10.2121543)); } // 方式1 BigDecimal sum = list.stream().collect(MyCollectors.summingBigDecimal(e -> e)); System.out.println(sum.doubleValue()); // 方式2 Optional<BigDecimal> reduce = list.stream().reduce(BigDecimal::add); System.out.println(reduce.orElse(BigDecimal.valueOf(0))); } }// OUTPUT: 521.0917032
补充:Collectors扩展接口 实现BigDecimal的相加
第一步
创建ToBigDecimalFunction接口
import java.math.BigDecimal;@FunctionalInterfacepublic interface ToBigDecimalFunction<T> { BigDecimal applyAsBigDecimal(T value);}
第二步
创建工具类 实现接口
import java.math.BigDecimal;import java.util.Collections;import java.util.Set;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;public class CollectorsUtil { static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet(); private CollectorsUtil() { } @SuppressWarnings("unchecked") private static <I, R> Function<I, R> castingIdentity() { return i -> (R) i; } static class CollectorImpl<T, A, R> implements Collector<T, A, R> { private final Supplier<A> supplier; private final BiConsumer<A, T> accumulator; private final BinaryOperator<A> combiner; private final Function<A, R> finisher; private final Set<Characteristics> characteristics; CollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Function<A, R> finisher, Set<Characteristics> characteristics) { this.supplier = supplier; this.accumulator = accumulator; this.combiner = combiner; this.finisher = finisher; this.characteristics = characteristics; } CollectorImpl(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Set<Characteristics> characteristics) { this(supplier, accumulator, combiner, castingIdentity(), characteristics); } @Override public BiConsumer<A, T> accumulator() { return accumulator; } @Override public Supplier<A> supplier() { return supplier; } @Override public BinaryOperator<A> combiner() { return combiner; } @Override public Function<A, R> finisher() { return finisher; } @Override public Set<Characteristics> characteristics() { return characteristics; } } public static <T> Collector<T, ?, BigDecimal> summingBigDecimal(ToBigDecimalFunction<? super T> mapper) { return new CollectorImpl<>(() -> new BigDecimal[1], (a, t) -> { if (a[0] == null) { a[0] = BigDecimal.ZERO; } a[0] = a[0].add(mapper.applyAsBigDecimal(t)); }, (a, b) -> { a[0] = a[0].add(b[0]); return a; }, a -> a[0], CH_NOID); }}
使用测试
import com.example.javademo.JavaDemoApplicationTests;import com.example.javademo.pojo.Student;import com.example.javademo.utils.DataUtils;import org.junit.Test;import java.math.BigDecimal;import java.util.stream.Collectors;public class TestBigDecimal extends JavaDemoApplicationTests { @Test public void testGroupByAfterBigdecimal(){ System.out.println(DataUtils.getData().stream().collect(Collectors.groupingBy(Student::getSchool,CollectorsUtil.summingBigDecimal(Student::getMoney)))); //归约造作 BigDecimal reduce = DataUtils.getData().stream().map(Student::getMoney).reduce(BigDecimal.ZERO, BigDecimal::add); System.out.println(reduce); int sum = DataUtils.getData().stream().mapToInt(Student::getAge).sum(); System.out.println(sum); }}
看完上述内容,你们掌握怎么在Java8中使用Collectors实现一个求和功能的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!