/* * [Accumulate.java] * * Summary: accumulate values to a set of named buckets. * * Copyright: (c) 2004-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.0 2004-07-16 * 1.1 2006-03-06 * 1.2 2008-01-01 add pad, icons * 1.3 2009-03-12 add ANT built script */ package com.mindprod.accumulate; import java.util.Arrays; import java.util.HashMap; import static java.lang.System.*; /** * accumulate values to a set of named buckets. *

* Might be used in a timesheet program to accumulate hours by billing categories. * Demonstrates use of HashMap. * * @author Roedy Green, Canadian Mind Products * @version 1.3 2009-03-12 add ANT built script * @since 2004-07-16 */ public final class Accumulate { /** * true if you want the debugging harness code included. */ private static final boolean DEBUGGING = false; private static final int FIRST_COPYRIGHT_YEAR = 2004; /** * undisplayed copyright notice * * @noinspection UnusedDeclaration */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2004-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; /** * when this version released. * * @noinspection UnusedDeclaration */ private static final String RELEASE_DATE = "2009-03-12"; /** * current version * * @noinspection UnusedDeclaration */ private static final String VERSION_STRING = "1.3"; /** * underlying HashMap where we store the accumulations by category */ private final HashMap hashMap; /** * @param size approximate number of categories you will be accumulating */ private Accumulate( int size ) { if ( size <= 0 ) { size = 16; } hashMap = new HashMap<>( ( int ) ( size / .75f ), 0.75f ); } /** * Accumulate value to the category * * @param category the category, case-sensitive to accumulate to * @param value the amount to add to the category accumulation. */ void accumulate( String category, long value ) { final Accum o = hashMap.get( category ); if ( o == null ) { Accum a = new Accum(); a.accumulate( value ); hashMap.put( category, a ); } else { o.accumulate( value ); } } /** * get list of all categories used so far * * @return array of category names, in sorted, case-sensitive order. */ String[] categories() { // get the current categories final int size = hashMap.size(); final String[] result = hashMap.keySet().toArray( new String[ size ] ); Arrays.sort( result ); return result; } /** * get the amount accumulated so far to the given category * * @param category the category desired, case-sensitive. Different capitalisations are considered different * categories. * * @return long the amount accumulated to that category. */ long total( String category ) { final Accum o = hashMap.get( category ); if ( o == null ) { return 0; } else { return o.total(); } } /** * test harness * * @param args not used */ public static void main( String[] args ) { if ( DEBUGGING ) { Accumulate buckets = new Accumulate( 20 ); buckets.accumulate( "ugli fruit", 3 ); buckets.accumulate( "peaches", 10 ); buckets.accumulate( "strawberries", 15 ); buckets.accumulate( "peaches", 14 ); String[] categories = buckets.categories(); // prints totals sorted in alphabetical order: // peaches:24 // strawberries:15 // ugli fruit:3 for ( final String category : categories ) { out.println( category + ":" + buckets.total( category ) ); } } } // end main /** * empty all accumulations */ public void clear() { hashMap.clear(); } /** * object to store in HashMap to store the accumulation for a category */ private static final class Accum { /** * total accumulated so far for this category */ private long total; /** * constructor */ Accum() { this.total = 0; } /** * accumulate value onto total * * @param value to add */ void accumulate( long value ) { total += value; } /** * get value accumulated so far * * @return total accumulated so far. */ long total() { return total; } } } // end Accumulate