001package org.javamoney.moneta.function; 002 003import java.util.Objects; 004 005import javax.money.CurrencyUnit; 006import javax.money.MonetaryAmount; 007 008import org.javamoney.moneta.FastMoney; 009 010/** 011 * A state object for collecting statistics such as count, min, max, sum, and 012 * average. 013 * @author otaviojava 014 * @author Anatole Tresch 015 */ 016public class MonetarySummaryStatistics { 017 018 private final MonetaryAmount empty; 019 020 private long count; 021 022 private MonetaryAmount min; 023 024 private MonetaryAmount max; 025 026 private MonetaryAmount sum; 027 028 private MonetaryAmount average; 029 030 /** 031 * Creates a new instance, targeting the given {@link javax.money.CurrencyUnit}. 032 * @param currencyUnit the target currency, not null. 033 */ 034 MonetarySummaryStatistics(CurrencyUnit currencyUnit) { 035 empty = FastMoney.of(0, Objects.requireNonNull(currencyUnit)); 036 setSameMonetary(empty); 037 } 038 039 /** 040 * Records another value into the summary information. 041 * 042 * @param amount 043 * the input amount value to be addeed, not null. 044 */ 045 public void accept(MonetaryAmount amount) { 046 047 if (!empty.getCurrency().equals( 048 Objects.requireNonNull(amount).getCurrency())) { 049 return; 050 } 051 if (isEmpty()) { 052 setSameMonetary(amount); 053 count++; 054 } else { 055 doSummary(amount); 056 } 057 } 058 059 /** 060 * Combines the state of another {@code MonetarySummaryStatistics} into this 061 * one. 062 * @param summaryStatistics 063 * another {@code MonetarySummaryStatistics}, not null. 064 */ 065 public MonetarySummaryStatistics combine(MonetarySummaryStatistics summaryStatistics) { 066 Objects.requireNonNull(summaryStatistics); 067 068 if (!equals(summaryStatistics)) { 069 return this; 070 } 071 min = MonetaryFunctions.min(min, summaryStatistics.min); 072 max = MonetaryFunctions.max(max, summaryStatistics.max); 073 sum = sum.add(summaryStatistics.sum); 074 count += summaryStatistics.count; 075 average = sum.divide(count); 076 return this; 077 } 078 079 private void doSummary(MonetaryAmount moneraty) { 080 min = MonetaryFunctions.min(min, moneraty); 081 max = MonetaryFunctions.max(max, moneraty); 082 sum = sum.add(moneraty); 083 average = sum.divide(++count); 084 } 085 086 private boolean isEmpty() { 087 return count == 0; 088 } 089 090 private void setSameMonetary(MonetaryAmount monetary) { 091 min = monetary; 092 max = monetary; 093 sum = monetary; 094 average = monetary; 095 } 096 097 /** 098 * Get the number of items added to this summary instance. 099 * @return the number of summarized items, >= 0. 100 */ 101 public long getCount() { 102 return count; 103 } 104 105 /** 106 * Get the minimal amount found within this summary. 107 * @return the minimal amount, or null if no amount was added to this summary instance. 108 */ 109 public MonetaryAmount getMin() { 110 return min; 111 } 112 113 /** 114 * Get the maximal amount found within this summary. 115 * @return the minimal amount, or null if no amount was added to this summary instance. 116 */ 117 public MonetaryAmount getMax() { 118 return max; 119 } 120 121 /** 122 * Get the sum of all amounts within this summary. 123 * @return the total amount, or null if no amount was added to this summary instance. 124 */ 125 public MonetaryAmount getSum() { 126 return sum; 127 } 128 129 /** 130 * Get the mean average of all amounts added. 131 * @return the mean average amount, or null if no amount was added to this summary instance. 132 */ 133 public MonetaryAmount getAverage() { 134 return average; 135 } 136 137 /** 138 * will equals when the currency utils were equals 139 */ 140 @Override 141 public boolean equals(Object obj) { 142 if (MonetarySummaryStatistics.class.isInstance(obj)) { 143 MonetarySummaryStatistics other = MonetarySummaryStatistics.class.cast(obj); 144 return Objects.equals(empty.getCurrency(), 145 other.empty.getCurrency()); 146 } 147 return false; 148 } 149 @Override 150 public int hashCode() { 151 return empty.getCurrency().hashCode(); 152 } 153 154 @Override 155 public String toString() { 156 StringBuilder sb = new StringBuilder(); 157 sb.append("[currency: ").append(empty.getCurrency()).append(","); 158 sb.append("count:").append(count).append(","); 159 sb.append("min:").append(min).append(","); 160 sb.append("max:").append(max).append(","); 161 sb.append("sum:").append(sum).append(","); 162 sb.append("average:").append(average).append("]"); 163 return sb.toString(); 164 } 165 166}