1717
1818import com .arpnetworking .commons .builder .OvalBuilder ;
1919import com .arpnetworking .logback .annotations .Loggable ;
20- import com .google .common .base .Function ;
2120import com .google .common .base .MoreObjects ;
22- import com .google .common .collect .Lists ;
2321import edu .umd .cs .findbugs .annotations .SuppressFBWarnings ;
2422import net .sf .oval .constraint .NotNull ;
2523
2624import java .io .Serializable ;
27- import java .util .Collection ;
28- import java .util .List ;
2925import java .util .Objects ;
3026import java .util .Optional ;
31- import javax .annotation .Nullable ;
3227
3328/**
3429 * Represents a sample.
@@ -61,7 +56,7 @@ public Quantity add(final Quantity otherQuantity) {
6156 this ,
6257 otherQuantity ));
6358 }
64- if (_unit .equals (otherQuantity ._unit )) {
59+ if (Objects .equals (_unit , otherQuantity ._unit )) {
6560 return new Quantity (_value + otherQuantity ._value , _unit );
6661 }
6762 final Unit smallerUnit = _unit .get ().getSmallerUnit (otherQuantity .getUnit ().get ());
@@ -86,7 +81,7 @@ public Quantity subtract(final Quantity otherQuantity) {
8681 this ,
8782 otherQuantity ));
8883 }
89- if (_unit .equals (otherQuantity ._unit )) {
84+ if (Objects .equals (_unit , otherQuantity ._unit )) {
9085 return new Quantity (_value - otherQuantity ._value , _unit );
9186 }
9287 final Unit smallerUnit = _unit .get ().getSmallerUnit (otherQuantity .getUnit ().get ());
@@ -122,73 +117,23 @@ public Quantity multiply(final Quantity otherQuantity) {
122117 public Quantity divide (final Quantity otherQuantity ) {
123118 // TODO(vkoskela): Support division by quantity with unit [2F].
124119 if (otherQuantity ._unit .isPresent ()) {
125- throw new UnsupportedOperationException ("Compount units not supported yet" );
120+ throw new UnsupportedOperationException ("Compound units not supported yet" );
126121 }
127- if (_unit .equals (otherQuantity ._unit )) {
122+ if (Objects .equals (_unit , otherQuantity ._unit )) {
128123 return new Quantity (_value / otherQuantity ._value , Optional .empty ());
129124 }
130125 return new Quantity (
131126 _value / otherQuantity ._value ,
132127 _unit );
133128 }
134129
135- /**
136- * Convert this <code>Quantity</code> to one in the specified unit. This
137- * <code>Quantity</code> must also have a <code>Unit</code> and it must
138- * be in the same domain as the provided unit.
139- *
140- * @param unit <code>Unit</code> to convert to.
141- * @return <code>Quantity</code> in specified unit.
142- */
143- public Quantity convertTo (final Unit unit ) {
144- if (!_unit .isPresent ()) {
145- throw new IllegalStateException (String .format (
146- "Cannot convert a quantity without a unit; this=%s" ,
147- this ));
148- }
149- if (_unit .get ().equals (unit )) {
150- return this ;
151- }
152- return new Quantity (
153- unit .convert (_value , _unit .get ()),
154- Optional .of (unit ));
155- }
156-
157- /**
158- * Convert this <code>Quantity</code> to one in the specified optional unit.
159- * Either this <code>Quantity</code> also has a <code>Unit</code> in the
160- * same domain as the provided unit or both units are absent.
161- *
162- * @param unit <code>Optional</code> <code>Unit</code> to convert to.
163- * @return <code>Quantity</code> in specified unit.
164- */
165- public Quantity convertTo (final Optional <Unit > unit ) {
166- if (_unit .isPresent () != unit .isPresent ()) {
167- throw new IllegalStateException (String .format (
168- "Units must both be present or absent; quantity=%s unit=%s" ,
169- this ,
170- unit ));
171- }
172- if (_unit .equals (unit )) {
173- return this ;
174- }
175- return new Quantity (
176- unit .get ().convert (_value , _unit .get ()),
177- unit );
178- }
179-
180130 @ Override
181131 public int compareTo (final Quantity other ) {
182132 if (other ._unit .equals (_unit )) {
183133 return Double .compare (_value , other ._value );
184- } else if (other ._unit .isPresent () && _unit .isPresent ()) {
185- final Unit smallerUnit = _unit .get ().getSmallerUnit (other ._unit .get ());
186- final double convertedValue = smallerUnit .convert (_value , _unit .get ());
187- final double otherConvertedValue = smallerUnit .convert (other ._value , other ._unit .get ());
188- return Double .compare (convertedValue , otherConvertedValue );
189134 }
190135 throw new IllegalArgumentException (String .format (
191- "Cannot compare a quantity with a unit to a quantity without a unit ; this=%s, other=%s" ,
136+ "Cannot compare mismatched units ; this=%s, other=%s" ,
192137 this ,
193138 other ));
194139 }
@@ -222,37 +167,6 @@ public String toString() {
222167 .toString ();
223168 }
224169
225- /**
226- * Ensures all <code>Quantity</code> instances have the same (including no)
227- * <code>Unit</code>.
228- *
229- * @param quantities <code>Quantity</code> instances to convert.
230- * @return <code>List</code> of <code>Quantity</code> instances with the
231- * same <code>Unit</code> (or no <code>Unit</code>).
232- */
233- public static List <Quantity > unify (final Collection <Quantity > quantities ) {
234- // This is a 2-pass operation:
235- // First pass is to grab the smallest unit in the samples
236- // Second pass is to convert everything to that unit
237- Optional <Unit > smallestUnit = Optional .empty ();
238- for (final Quantity quantity : quantities ) {
239- if (!smallestUnit .isPresent ()) {
240- smallestUnit = quantity .getUnit ();
241- } else if (quantity .getUnit ().isPresent ()
242- && !smallestUnit .get ().getSmallerUnit (quantity .getUnit ().get ()).equals (smallestUnit .get ())) {
243- smallestUnit = quantity .getUnit ();
244- }
245- }
246-
247- final List <Quantity > convertedSamples = Lists .newArrayListWithExpectedSize (quantities .size ());
248- final Function <Quantity , Quantity > converter = SampleConverter .to (smallestUnit );
249- for (final Quantity quantity : quantities ) {
250- convertedSamples .add (converter .apply (quantity ));
251- }
252-
253- return convertedSamples ;
254- }
255-
256170 private Quantity (final Builder builder ) {
257171 this (builder ._value , Optional .ofNullable (builder ._unit ));
258172 }
@@ -268,37 +182,6 @@ private Quantity(final double value, final Optional<Unit> unit) {
268182
269183 private static final long serialVersionUID = -6339526234042605516L ;
270184
271- private static final class SampleConverter implements Function <Quantity , Quantity > {
272-
273- public static Function <Quantity , Quantity > to (final Optional <Unit > unit ) {
274- if (unit .isPresent ()) {
275- return new SampleConverter (unit .get ());
276- }
277- return (q ) -> q ;
278- }
279-
280- @ Override
281- @ Nullable
282- public Quantity apply (@ Nullable final Quantity quantity ) {
283- if (quantity == null ) {
284- return null ;
285- }
286- if (!quantity .getUnit ().isPresent ()) {
287- throw new IllegalArgumentException (String .format ("Cannot convert a quantity without unit; sample=%s" , quantity ));
288- }
289- return new Quantity .Builder ()
290- .setValue (_unit .convert (quantity .getValue (), quantity .getUnit ().get ()))
291- .setUnit (_unit )
292- .build ();
293- }
294-
295- private SampleConverter (final Unit convertTo ) {
296- _unit = convertTo ;
297- }
298-
299- private final Unit _unit ;
300- }
301-
302185 /**
303186 * <code>Builder</code> implementation for <code>Quantity</code>.
304187 */
@@ -311,6 +194,17 @@ public Builder() {
311194 super ((java .util .function .Function <Builder , Quantity >) Quantity ::new );
312195 }
313196
197+ /**
198+ * Public constructor.
199+ *
200+ * @param quantity the <code>Quantity</code> to initialize from
201+ */
202+ public Builder (final Quantity quantity ) {
203+ super ((java .util .function .Function <Builder , Quantity >) Quantity ::new );
204+ _value = quantity ._value ;
205+ _unit = quantity ._unit .orElse (null );
206+ }
207+
314208 /**
315209 * Set the value. Required. Cannot be null.
316210 *
@@ -335,12 +229,21 @@ public Builder setUnit(final Unit value) {
335229
336230 @ Override
337231 public Quantity build () {
338- if (_value == null ) {
339- throw new IllegalStateException ("value cannot be null" );
340- }
232+ normalize ();
341233 return new Quantity (this );
342234 }
343235
236+ private Builder normalize () {
237+ if (_value != null && _unit != null ) {
238+ final Unit defaultUnit = _unit .getType ().getDefaultUnit ();
239+ if (!Objects .equals (_unit , defaultUnit )) {
240+ _value = defaultUnit .convert (_value , _unit );
241+ _unit = defaultUnit ;
242+ }
243+ }
244+ return this ;
245+ }
246+
344247 @ NotNull
345248 private Double _value ;
346249 private Unit _unit ;
0 commit comments