/*
* [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