MathAggregatorFunctions { @Beta public static <T extends Number> Function<Collection<? extends Number>, T> computingSum( Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, Class<T> type) { return computingSum(defaultValueForUnreportedSensors, valueToReportIfNoSensors, TypeToken.of(type)); } private  MathAggregatorFunctions(); @Beta static Function<Collection<? extends Number>, T> computingSum(
            Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, Class<T> type); @Beta static Function<Collection<? extends Number>, T> computingSum(
            Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken); @Beta static Function<Collection<? extends Number>, T> computingAverage(
            Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, Class<T> type); @Beta static Function<Collection<? extends Number>, T> computingAverage(
            Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken); @Beta static Function<Collection<? extends Number>, T> computingMin(
            Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, Class<T> type); @Beta static Function<Collection<? extends Number>, T> computingMin(
            Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken); @Beta static Function<Collection<? extends Number>, T> computingMax(
            Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, Class<T> type); @Beta static Function<Collection<? extends Number>, T> computingMax(
            Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken);  }
@Test public void testCastInputValuesToNumbers() throws Exception { Function<Collection<? extends Number>, Integer> func = MathAggregatorFunctions.computingSum(null, null, Integer.class); @SuppressWarnings({ "rawtypes", "unchecked" }) List<Number> input = (List<Number>) (List) MutableList.<Object>of("1", null, "4"); assertEquals(func.apply(input), (Integer)5); }
@Test @SuppressWarnings({ "rawtypes", "unchecked" }) public void testTryCastInputValuesWhenNotNumbers() throws Exception { Function<Collection<? extends Number>, Integer> func = MathAggregatorFunctions.computingSum(null, null, Integer.class); try (final LogWatcher watcher = new LogWatcher( ImmutableList.of(LoggerFactory.getLogger(MathAggregatorFunctions.class).getName()), ch.qos.logback.classic.Level.WARN, containsMessage("Input to numeric aggregator is not a number"))) { List<Number> inputWithNonNumber = (List<Number>) (List) MutableList.<Object>of(1, null, "not a number", "4", true); for (int i = 0; i < 2; i++) { assertEquals(func.apply(inputWithNonNumber), (Integer)5); } assertEquals(watcher.getEvents().size(), 1, "events="+watcher.getEvents()); watcher.clearEvents(); assertEquals(func.apply(ImmutableList.of(1, 4)), (Integer)5); assertTrue(watcher.getEvents().isEmpty(), "events="+watcher.getEvents()); for (int i = 0; i < 2; i++) { assertEquals(func.apply(inputWithNonNumber), (Integer)5); } assertEquals(watcher.getEvents().size(), 1, "events="+watcher.getEvents()); } }
@Test public void testSum() throws Exception { Function<Collection<? extends Number>, Integer> func = MathAggregatorFunctions.computingSum(null, null, Integer.class); assertEquals(func.apply(MutableList.<Number>of(1, 2, 4)), (Integer)7); assertEquals(func.apply(MutableList.<Number>of(1, null, 4)), (Integer)5); }