BasicCounters implements Serializable { @SuppressWarnings("unchecked") public synchronized T findCounter(Enum<?> counterKey) throws IllegalAccessException, InstantiationException { T counter = cache.get(counterKey); if (counter == null) { counter = counterType.newInstance(); cache.put(counterKey, counter); } return counter; } @SuppressWarnings("unused") private  BasicCounters();  BasicCounters(@Nonnull Class<T> counterType); @SuppressWarnings("unchecked") synchronized T findCounter(Enum<?> counterKey); synchronized T getCounter(Enum<?> counterKey); synchronized void setCounter(Enum<?> counterKey, T value); synchronized ImmutableMap<Enum<?>, T> getCopy();  }
@Test public void testBasicCountersAggregator() throws InstantiationException, IllegalAccessException { List<Object> physicalCounters = Lists.newArrayList(); for (int i = 0; i < 5; i++) { BasicCounters<MutableDouble> doubleBasicCounters = new BasicCounters<MutableDouble>(MutableDouble.class); MutableDouble counterA = doubleBasicCounters.findCounter(CounterKeys.A); counterA.increment(); physicalCounters.add(doubleBasicCounters); } BasicCounters.DoubleAggregator<MutableDouble> aggregator = new BasicCounters.DoubleAggregator<MutableDouble>(); @SuppressWarnings("unchecked") Map<String, NumberAggregate.DoubleAggregate> aggregateMap = (Map<String, NumberAggregate.DoubleAggregate>)aggregator.aggregate(physicalCounters); Assert.assertNotNull("null", aggregateMap.get(CounterKeys.A.name())); NumberAggregate.DoubleAggregate aggregate = aggregateMap.get(CounterKeys.A.name()); Assert.assertEquals(aggregate.getSum().doubleValue(), 5.0, 0); Assert.assertEquals(aggregate.getMin().doubleValue(), 1.0, 0); Assert.assertEquals(aggregate.getMax().doubleValue(), 1.0, 0); Assert.assertEquals(aggregate.getAvg().doubleValue(), 1.0, 0); }