1 /* 2 * Copyright 2009-2013 Stephen Colebourne 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.joda.money; 17 18 import java.io.InvalidObjectException; 19 import java.io.ObjectInputStream; 20 import java.io.Serializable; 21 import java.math.BigDecimal; 22 import java.math.RoundingMode; 23 import java.util.Arrays; 24 import java.util.Iterator; 25 26 import org.joda.convert.FromString; 27 import org.joda.convert.ToString; 28 29 /** 30 * An amount of money with the standard decimal places defined by the currency. 31 * <p> 32 * This class represents a quantity of money, stored as a {@code BigDecimal} amount 33 * in a single {@link CurrencyUnit currency}. 34 * <p> 35 * Every currency has a certain standard number of decimal places. 36 * This is typically 2 (Euro, British Pound, US Dollar) but might be 37 * 0 (Japanese Yen), 1 (Vietnamese Dong) or 3 (Bahrain Dinar). 38 * The {@code Money} class is fixed to this number of decimal places. 39 * <p> 40 * For example, US dollars has a standard number of decimal places of 2. 41 * The major units are dollars. The minor units are cents, 100 to the dollar. 42 * This class does not allow calculations on fractions of a cent. 43 * <p> 44 * This class is immutable and thread-safe. 45 */ 46 public final class Money implements BigMoneyProvider, Comparable<BigMoneyProvider>, Serializable { 47 48 /** 49 * The serialisation version. 50 */ 51 private static final long serialVersionUID = 1L; 52 53 /** 54 * The money, not null. 55 */ 56 private final BigMoney money; 57 58 //----------------------------------------------------------------------- 59 /** 60 * Obtains an instance of {@code Money} from a {@code BigDecimal}. 61 * <p> 62 * This allows you to create an instance with a specific currency and amount. 63 * No rounding is performed on the amount, so it must have a scale compatible 64 * with the currency. 65 * 66 * @param currency the currency, not null 67 * @param amount the amount of money, not null 68 * @return the new instance, never null 69 * @throws ArithmeticException if the scale exceeds the currency scale 70 */ 71 public static Money of(CurrencyUnit currency, BigDecimal amount) { 72 MoneyUtils.checkNotNull(currency, "Currency must not be null"); 73 if (amount.scale() > currency.getDecimalPlaces()) { 74 throw new ArithmeticException("Scale of amount " + amount + " is greater than the scale of the currency " + currency); 75 } 76 return Money.of(currency, amount, RoundingMode.UNNECESSARY); 77 } 78 79 /** 80 * Obtains an instance of {@code Money} from a {@code BigDecimal}, rounding as necessary. 81 * <p> 82 * This allows you to create an instance with a specific currency and amount. 83 * If the amount has a scale in excess of the scale of the currency then the excess 84 * fractional digits are rounded using the rounding mode. 85 * 86 * @param currency the currency, not null 87 * @param amount the amount of money, not null 88 * @param roundingMode the rounding mode to use, not null 89 * @return the new instance, never null 90 * @throws ArithmeticException if the rounding fails 91 */ 92 public static Money of(CurrencyUnit currency, BigDecimal amount, RoundingMode roundingMode) { 93 MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null"); 94 MoneyUtils.checkNotNull(amount, "Amount must not be null"); 95 MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null"); 96 amount = amount.setScale(currency.getDecimalPlaces(), roundingMode); 97 return new Money(BigMoney.of(currency, amount)); 98 } 99 100 //----------------------------------------------------------------------- 101 /** 102 * Obtains an instance of {@code Money} from a {@code double} using a 103 * well-defined conversion. 104 * <p> 105 * This allows you to create an instance with a specific currency and amount. 106 * No rounding is performed on the amount, so it must have a scale compatible 107 * with the currency. 108 * <p> 109 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 110 * the most expected answer for most programming scenarios. 111 * Any {@code double} literal in code will be converted to 112 * exactly the same BigDecimal with the same scale. 113 * For example, the literal '1.45d' will be converted to '1.45'. 114 * 115 * @param currency the currency, not null 116 * @param amount the amount of money, not null 117 * @return the new instance, never null 118 * @throws ArithmeticException if the scale exceeds the currency scale 119 */ 120 public static Money of(CurrencyUnit currency, double amount) { 121 return Money.of(currency, BigDecimal.valueOf(amount)); 122 } 123 124 /** 125 * Obtains an instance of {@code Money} from a {@code double} using a 126 * well-defined conversion, rounding as necessary. 127 * <p> 128 * This allows you to create an instance with a specific currency and amount. 129 * If the amount has a scale in excess of the scale of the currency then the excess 130 * fractional digits are rounded using the rounding mode. 131 * <p> 132 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 133 * the most expected answer for most programming scenarios. 134 * Any {@code double} literal in code will be converted to 135 * exactly the same BigDecimal with the same scale. 136 * For example, the literal '1.45d' will be converted to '1.45'. 137 * 138 * @param currency the currency, not null 139 * @param amount the amount of money, not null 140 * @param roundingMode the rounding mode to use, not null 141 * @return the new instance, never null 142 * @throws ArithmeticException if the rounding fails 143 */ 144 public static Money of(CurrencyUnit currency, double amount, RoundingMode roundingMode) { 145 return Money.of(currency, BigDecimal.valueOf(amount), roundingMode); 146 } 147 148 //----------------------------------------------------------------------- 149 /** 150 * Obtains an instance of {@code Money} from an amount in major units. 151 * <p> 152 * This allows you to create an instance with a specific currency and amount. 153 * The amount is a whole number only. Thus you can initialise the value 154 * 'USD 20', but not the value 'USD 20.32'. 155 * For example, {@code ofMajor(USD, 25)} creates the instance {@code USD 25.00}. 156 * 157 * @param currency the currency, not null 158 * @param amountMajor the amount of money in the major division of the currency 159 * @return the new instance, never null 160 */ 161 public static Money ofMajor(CurrencyUnit currency, long amountMajor) { 162 return Money.of(currency, BigDecimal.valueOf(amountMajor), RoundingMode.UNNECESSARY); 163 } 164 165 /** 166 * Obtains an instance of {@code Money} from an amount in minor units. 167 * <p> 168 * This allows you to create an instance with a specific currency and amount 169 * expressed in terms of the minor unit. 170 * For example, if constructing US Dollars, the input to this method represents cents. 171 * Note that when a currency has zero decimal places, the major and minor units are the same. 172 * For example, {@code ofMajor(USD, 2595)} creates the instance {@code USD 25.95}. 173 * 174 * @param currency the currency, not null 175 * @param amountMinor the amount of money in the minor division of the currency 176 * @return the new instance, never null 177 */ 178 public static Money ofMinor(CurrencyUnit currency, long amountMinor) { 179 return new Money(BigMoney.ofMinor(currency, amountMinor)); 180 } 181 182 //----------------------------------------------------------------------- 183 /** 184 * Obtains an instance of {@code Money} representing zero. 185 * <p> 186 * For example, {@code zero(USD)} creates the instance {@code USD 0.00}. 187 * 188 * @param currency the currency, not null 189 * @return the instance representing zero, never null 190 */ 191 public static Money zero(CurrencyUnit currency) { 192 MoneyUtils.checkNotNull(currency, "Currency must not be null"); 193 BigDecimal bd = BigDecimal.valueOf(0, currency.getDecimalPlaces()); 194 return new Money(BigMoney.of(currency, bd)); 195 } 196 197 //----------------------------------------------------------------------- 198 /** 199 * Obtains an instance of {@code Money} from a provider. 200 * <p> 201 * This allows you to create an instance from any class that implements the 202 * provider, such as {@code BigMoney}. 203 * No rounding is performed on the amount, so it must have a scale compatible 204 * with the currency. 205 * 206 * @param moneyProvider the money to convert, not null 207 * @return the new instance, never null 208 * @throws ArithmeticException if the scale exceeds the currency scale 209 */ 210 public static Money of(BigMoneyProvider moneyProvider) { 211 return Money.of(moneyProvider, RoundingMode.UNNECESSARY); 212 } 213 214 /** 215 * Obtains an instance of {@code Money} from a provider, rounding as necessary. 216 * <p> 217 * This allows you to create an instance from any class that implements the 218 * provider, such as {@code BigMoney}. 219 * The rounding mode is used to adjust the scale to the scale of the currency. 220 * 221 * @param moneyProvider the money to convert, not null 222 * @param roundingMode the rounding mode to use, not null 223 * @return the new instance, never null 224 * @throws ArithmeticException if the rounding fails 225 */ 226 public static Money of(BigMoneyProvider moneyProvider, RoundingMode roundingMode) { 227 MoneyUtils.checkNotNull(moneyProvider, "BigMoneyProvider must not be null"); 228 MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null"); 229 return new Money(BigMoney.of(moneyProvider).withCurrencyScale(roundingMode)); 230 } 231 232 //----------------------------------------------------------------------- 233 /** 234 * Obtains an instance of {@code Money} as the total value of an array. 235 * <p> 236 * The array must contain at least one monetary value. 237 * Subsequent amounts are added as though using {@link #plus(Money)}. 238 * All amounts must be in the same currency. 239 * 240 * @param monies the monetary values to total, not empty, no null elements, not null 241 * @return the total, never null 242 * @throws IllegalArgumentException if the array is empty 243 * @throws CurrencyMismatchException if the currencies differ 244 */ 245 public static Money total(Money... monies) { 246 MoneyUtils.checkNotNull(monies, "Money array must not be null"); 247 if (monies.length == 0) { 248 throw new IllegalArgumentException("Money array must not be empty"); 249 } 250 Money total = monies[0]; 251 MoneyUtils.checkNotNull(total, "Money arary must not contain null entries"); 252 for (int i = 1; i < monies.length; i++) { 253 total = total.plus(monies[i]); 254 } 255 return total; 256 } 257 258 /** 259 * Obtains an instance of {@code Money} as the total value of a collection. 260 * <p> 261 * The iterable must provide at least one monetary value. 262 * Subsequent amounts are added as though using {@link #plus(Money)}. 263 * All amounts must be in the same currency. 264 * 265 * @param monies the monetary values to total, not empty, no null elements, not null 266 * @return the total, never null 267 * @throws IllegalArgumentException if the iterable is empty 268 * @throws CurrencyMismatchException if the currencies differ 269 */ 270 public static Money total(Iterable<Money> monies) { 271 MoneyUtils.checkNotNull(monies, "Money iterator must not be null"); 272 Iterator<Money> it = monies.iterator(); 273 if (it.hasNext() == false) { 274 throw new IllegalArgumentException("Money iterator must not be empty"); 275 } 276 Money total = it.next(); 277 MoneyUtils.checkNotNull(total, "Money iterator must not contain null entries"); 278 while (it.hasNext()) { 279 total = total.plus(it.next()); 280 } 281 return total; 282 } 283 284 /** 285 * Obtains an instance of {@code Money} as the total value of 286 * a possibly empty array. 287 * <p> 288 * The amounts are added as though using {@link #plus(Money)} starting 289 * from zero in the specified currency. 290 * All amounts must be in the same currency. 291 * 292 * @param currency the currency to total in, not null 293 * @param monies the monetary values to total, no null elements, not null 294 * @return the total, never null 295 * @throws CurrencyMismatchException if the currencies differ 296 */ 297 public static Money total(CurrencyUnit currency, Money... monies) { 298 return Money.zero(currency).plus(Arrays.asList(monies)); 299 } 300 301 /** 302 * Obtains an instance of {@code Money} as the total value of 303 * a possibly empty collection. 304 * <p> 305 * The amounts are added as though using {@link #plus(Money)} starting 306 * from zero in the specified currency. 307 * All amounts must be in the same currency. 308 * 309 * @param currency the currency to total in, not null 310 * @param monies the monetary values to total, no null elements, not null 311 * @return the total, never null 312 * @throws CurrencyMismatchException if the currencies differ 313 */ 314 public static Money total(CurrencyUnit currency, Iterable<Money> monies) { 315 return Money.zero(currency).plus(monies); 316 } 317 318 //----------------------------------------------------------------------- 319 /** 320 * Parses an instance of {@code Money} from a string. 321 * <p> 322 * The string format is '<currencyCode> <amount>'. 323 * The currency code must be a valid three letter currency. 324 * The amount must match the regular expression {@code [+-]?[0-9]*[.]?[0-9]*}. 325 * This matches the output from {@link #toString()}. 326 * <p> 327 * For example, {@code of("USD 25")} creates the instance {@code USD 25.00} 328 * while {@code of("USD 25.95")} creates the instance {@code USD 25.95}. 329 * 330 * @param moneyStr the money string to parse, not null 331 * @return the parsed instance, never null 332 * @throws IllegalArgumentException if the string is malformed 333 * @throws ArithmeticException if the amount is too large 334 */ 335 @FromString 336 public static Money parse(String moneyStr) { 337 return Money.of(BigMoney.parse(moneyStr)); 338 } 339 340 //----------------------------------------------------------------------- 341 /** 342 * Ensures that a {@code Money} is not {@code null}. 343 * <p> 344 * If the input money is not {@code null}, then it is returned, providing 345 * that the currency matches the specified currency. 346 * If the input money is {@code null}, then zero money in the currency is returned. 347 * 348 * @param money the monetary value to check, may be null 349 * @param currency the currency to use, not null 350 * @return the input money or zero in the specified currency, never null 351 * @throws CurrencyMismatchException if the input money is non-null and the currencies differ 352 */ 353 public static Money nonNull(Money money, CurrencyUnit currency) { 354 if (money == null) { 355 return zero(currency); 356 } 357 if (money.getCurrencyUnit().equals(currency) == false) { 358 MoneyUtils.checkNotNull(currency, "Currency must not be null"); 359 throw new CurrencyMismatchException(money.getCurrencyUnit(), currency); 360 } 361 return money; 362 } 363 364 //----------------------------------------------------------------------- 365 /** 366 * Constructor, creating a new monetary instance. 367 * 368 * @param money the underlying money, not null 369 */ 370 Money(BigMoney money) { 371 assert money != null : "Joda-Money bug: BigMoney must not be null"; 372 assert money.isCurrencyScale() : "Joda-Money bug: Only currency scale is valid for Money"; 373 this.money = money; 374 } 375 376 /** 377 * Block malicious data streams. 378 * 379 * @param ois the input stream, not null 380 * @throws InvalidObjectException 381 */ 382 private void readObject(ObjectInputStream ois) throws InvalidObjectException { 383 throw new InvalidObjectException("Serialization delegate required"); 384 } 385 386 /** 387 * Uses a serialization delegate. 388 * 389 * @return the replacing object, never null 390 */ 391 private Object writeReplace() { 392 return new Ser(Ser.MONEY, this); 393 } 394 395 //----------------------------------------------------------------------- 396 /** 397 * Returns a new {@code Money}, returning {@code this} if possible. 398 * <p> 399 * This instance is immutable and unaffected by this method. 400 * 401 * @param newInstance the new money to use, not null 402 * @return the new instance, never null 403 */ 404 private Money with(BigMoney newInstance) { 405 if (money.equals(newInstance)) { 406 return this; 407 } 408 return new Money(newInstance); 409 } 410 411 //----------------------------------------------------------------------- 412 /** 413 * Gets the currency. 414 * 415 * @return the currency, never null 416 */ 417 public CurrencyUnit getCurrencyUnit() { 418 return money.getCurrencyUnit(); 419 } 420 421 //----------------------------------------------------------------------- 422 /** 423 * Returns a copy of this monetary value with the specified currency. 424 * <p> 425 * The returned instance will have the specified currency and the amount 426 * from this instance. If the scale differs between the currencies such 427 * that rounding would be required, then an exception is thrown. 428 * <p> 429 * This instance is immutable and unaffected by this method. 430 * 431 * @param currency the currency to use, not null 432 * @return the new instance with the input currency set, never null 433 * @throws ArithmeticException if the scale of the new currency is less than 434 * the scale of this currency 435 */ 436 public Money withCurrencyUnit(CurrencyUnit currency) { 437 return withCurrencyUnit(currency, RoundingMode.UNNECESSARY); 438 } 439 440 /** 441 * Returns a copy of this monetary value with the specified currency. 442 * <p> 443 * The returned instance will have the specified currency and the amount 444 * from this instance. If the number of decimal places differs between the 445 * currencies, then the amount may be rounded. 446 * <p> 447 * This instance is immutable and unaffected by this method. 448 * 449 * @param currency the currency to use, not null 450 * @param roundingMode the rounding mode to use to bring the decimal places back in line, not null 451 * @return the new instance with the input currency set, never null 452 * @throws ArithmeticException if the rounding fails 453 */ 454 public Money withCurrencyUnit(CurrencyUnit currency, RoundingMode roundingMode) { 455 return with(money.withCurrencyUnit(currency).withCurrencyScale(roundingMode)); 456 } 457 458 //----------------------------------------------------------------------- 459 /** 460 * Gets the scale of the {@code BigDecimal} amount. 461 * <p> 462 * The scale has the same meaning as in {@link BigDecimal}. 463 * Positive values represent the number of decimal places in use. 464 * For example, a scale of 2 means that the money will have two decimal places 465 * such as 'USD 43.25'. 466 * <p> 467 * For {@code Money}, the scale is fixed and always matches that of the currency. 468 * 469 * @return the scale in use, typically 2 but could be 0, 1 and 3 470 */ 471 public int getScale() { 472 return money.getScale(); 473 } 474 475 //----------------------------------------------------------------------- 476 /** 477 * Gets the amount. 478 * <p> 479 * This returns the value of the money as a {@code BigDecimal}. 480 * The scale will be the scale of this money. 481 * 482 * @return the amount, never null 483 */ 484 public BigDecimal getAmount() { 485 return money.getAmount(); 486 } 487 488 /** 489 * Gets the amount in major units as a {@code BigDecimal} with scale 0. 490 * <p> 491 * This returns the monetary amount in terms of the major units of the currency, 492 * truncating the amount if necessary. 493 * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1. 494 * <p> 495 * This is returned as a {@code BigDecimal} rather than a {@code BigInteger}. 496 * This is to allow further calculations to be performed on the result. 497 * Should you need a {@code BigInteger}, simply call {@link BigDecimal#toBigInteger()}. 498 * 499 * @return the major units part of the amount, never null 500 */ 501 public BigDecimal getAmountMajor() { 502 return money.getAmountMajor(); 503 } 504 505 /** 506 * Gets the amount in major units as a {@code long}. 507 * <p> 508 * This returns the monetary amount in terms of the major units of the currency, 509 * truncating the amount if necessary. 510 * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1. 511 * 512 * @return the major units part of the amount 513 * @throws ArithmeticException if the amount is too large for a {@code long} 514 */ 515 public long getAmountMajorLong() { 516 return money.getAmountMajorLong(); 517 } 518 519 /** 520 * Gets the amount in major units as an {@code int}. 521 * <p> 522 * This returns the monetary amount in terms of the major units of the currency, 523 * truncating the amount if necessary. 524 * For example, 'EUR 2.35' will return 2, and 'BHD -1.345' will return -1. 525 * 526 * @return the major units part of the amount 527 * @throws ArithmeticException if the amount is too large for an {@code int} 528 */ 529 public int getAmountMajorInt() { 530 return money.getAmountMajorInt(); 531 } 532 533 /** 534 * Gets the amount in minor units as a {@code BigDecimal} with scale 0. 535 * <p> 536 * This returns the monetary amount in terms of the minor units of the currency, 537 * truncating the amount if necessary. 538 * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345. 539 * <p> 540 * This is returned as a {@code BigDecimal} rather than a {@code BigInteger}. 541 * This is to allow further calculations to be performed on the result. 542 * Should you need a {@code BigInteger}, simply call {@link BigDecimal#toBigInteger()}. 543 * 544 * @return the minor units part of the amount, never null 545 */ 546 public BigDecimal getAmountMinor() { 547 return money.getAmountMinor(); 548 } 549 550 /** 551 * Gets the amount in minor units as a {@code long}. 552 * <p> 553 * This returns the monetary amount in terms of the minor units of the currency, 554 * truncating the amount if necessary. 555 * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345. 556 * 557 * @return the minor units part of the amount 558 * @throws ArithmeticException if the amount is too large for a {@code long} 559 */ 560 public long getAmountMinorLong() { 561 return money.getAmountMinorLong(); 562 } 563 564 /** 565 * Gets the amount in minor units as an {@code int}. 566 * <p> 567 * This returns the monetary amount in terms of the minor units of the currency, 568 * truncating the amount if necessary. 569 * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345. 570 * 571 * @return the minor units part of the amount 572 * @throws ArithmeticException if the amount is too large for an {@code int} 573 */ 574 public int getAmountMinorInt() { 575 return money.getAmountMinorInt(); 576 } 577 578 /** 579 * Gets the minor part of the amount. 580 * <p> 581 * This return the minor unit part of the monetary amount. 582 * This is defined as the amount in minor units excluding major units. 583 * <p> 584 * For example, EUR has a scale of 2, so the minor part is always between 0 and 99 585 * for positive amounts, and 0 and -99 for negative amounts. 586 * Thus 'EUR 2.35' will return 35, and 'EUR -1.34' will return -34. 587 * 588 * @return the minor part of the amount, negative if the amount is negative 589 */ 590 public int getMinorPart() { 591 return money.getMinorPart(); 592 } 593 594 //----------------------------------------------------------------------- 595 /** 596 * Checks if the amount is zero. 597 * 598 * @return true if the amount is zero 599 */ 600 public boolean isZero() { 601 return money.isZero(); 602 } 603 604 /** 605 * Checks if the amount is greater than zero. 606 * 607 * @return true if the amount is greater than zero 608 */ 609 public boolean isPositive() { 610 return money.isPositive(); 611 } 612 613 /** 614 * Checks if the amount is zero or greater. 615 * 616 * @return true if the amount is zero or greater 617 */ 618 public boolean isPositiveOrZero() { 619 return money.isPositiveOrZero(); 620 } 621 622 /** 623 * Checks if the amount is less than zero. 624 * 625 * @return true if the amount is less than zero 626 */ 627 public boolean isNegative() { 628 return money.isNegative(); 629 } 630 631 /** 632 * Checks if the amount is zero or less. 633 * 634 * @return true if the amount is zero or less 635 */ 636 public boolean isNegativeOrZero() { 637 return money.isNegativeOrZero(); 638 } 639 640 //----------------------------------------------------------------------- 641 /** 642 * Returns a copy of this monetary value with the specified amount. 643 * <p> 644 * The returned instance will have this currency and the new amount. 645 * No rounding is performed on the amount to be added, so it must have a 646 * scale compatible with the currency. 647 * <p> 648 * This instance is immutable and unaffected by this method. 649 * 650 * @param amount the monetary amount to set in the returned instance, not null 651 * @return the new instance with the input amount set, never null 652 * @throws ArithmeticException if the scale of the amount is too large 653 */ 654 public Money withAmount(BigDecimal amount) { 655 return withAmount(amount, RoundingMode.UNNECESSARY); 656 } 657 658 /** 659 * Returns a copy of this monetary value with the specified amount. 660 * <p> 661 * The returned instance will have this currency and the new amount. 662 * If the scale of the {@code BigDecimal} needs to be adjusted, then 663 * it will be rounded using the specified mode. 664 * <p> 665 * This instance is immutable and unaffected by this method. 666 * 667 * @param amount the monetary amount to set in the returned instance, not null 668 * @param roundingMode the rounding mode to adjust the scale, not null 669 * @return the new instance with the input amount set, never null 670 */ 671 public Money withAmount(BigDecimal amount, RoundingMode roundingMode) { 672 return with(money.withAmount(amount).withCurrencyScale(roundingMode)); 673 } 674 675 /** 676 * Returns a copy of this monetary value with the specified amount using a well-defined 677 * conversion from a {@code double}. 678 * <p> 679 * The returned instance will have this currency and the new amount. 680 * No rounding is performed on the amount to be added, so it must have a 681 * scale compatible with the currency. 682 * <p> 683 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 684 * the most expected answer for most programming scenarios. 685 * Any {@code double} literal in code will be converted to 686 * exactly the same BigDecimal with the same scale. 687 * For example, the literal '1.45d' will be converted to '1.45'. 688 * <p> 689 * This instance is immutable and unaffected by this method. 690 * 691 * @param amount the monetary amount to set in the returned instance, not null 692 * @return the new instance with the input amount set, never null 693 * @throws ArithmeticException if the scale of the amount is too large 694 */ 695 public Money withAmount(double amount) { 696 return withAmount(amount, RoundingMode.UNNECESSARY); 697 } 698 699 /** 700 * Returns a copy of this monetary value with the specified amount using a well-defined 701 * conversion from a {@code double}. 702 * <p> 703 * The returned instance will have this currency and the new amount. 704 * If the scale of the {@code BigDecimal} needs to be adjusted, then 705 * it will be rounded using the specified mode. 706 * <p> 707 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 708 * the most expected answer for most programming scenarios. 709 * Any {@code double} literal in code will be converted to 710 * exactly the same BigDecimal with the same scale. 711 * For example, the literal '1.45d' will be converted to '1.45'. 712 * <p> 713 * This instance is immutable and unaffected by this method. 714 * 715 * @param amount the monetary amount to set in the returned instance, not null 716 * @param roundingMode the rounding mode to adjust the scale, not null 717 * @return the new instance with the input amount set, never null 718 */ 719 public Money withAmount(double amount, RoundingMode roundingMode) { 720 return with(money.withAmount(amount).withCurrencyScale(roundingMode)); 721 } 722 723 //----------------------------------------------------------------------- 724 /** 725 * Returns a copy of this monetary value with a collection of monetary amounts added. 726 * <p> 727 * This adds the specified amounts to this monetary amount, returning a new object. 728 * The amounts must be in the same currency. 729 * <p> 730 * This instance is immutable and unaffected by this method. 731 * 732 * @param moniesToAdd the monetary values to add, no null elements, not null 733 * @return the new instance with the input amounts added, never null 734 * @throws CurrencyMismatchException if the currencies differ 735 */ 736 public Money plus(Iterable<Money> moniesToAdd) { 737 return with(money.plus(moniesToAdd)); 738 } 739 740 //----------------------------------------------------------------------- 741 /** 742 * Returns a copy of this monetary value with the amount added. 743 * <p> 744 * This adds the specified amount to this monetary amount, returning a new object. 745 * The amount added must be in the same currency. 746 * <p> 747 * The addition has no rounding issues and is always accurate. 748 * For example,'USD 25.95' plus 'USD 3.02' will 'USD 28.97'. 749 * <p> 750 * This instance is immutable and unaffected by this method. 751 * 752 * @param moneyToAdd the monetary value to add, not null 753 * @return the new instance with the input amount added, never null 754 * @throws CurrencyMismatchException if the currencies differ 755 */ 756 public Money plus(Money moneyToAdd) { 757 return with(money.plus(moneyToAdd)); 758 } 759 760 /** 761 * Returns a copy of this monetary value with the amount added. 762 * <p> 763 * This adds the specified amount to this monetary amount, returning a new object. 764 * No rounding is performed on the amount to be added, so it must have a 765 * scale compatible with the currency. 766 * <p> 767 * This instance is immutable and unaffected by this method. 768 * 769 * @param amountToAdd the monetary value to add, not null 770 * @return the new instance with the input amount added, never null 771 * @throws ArithmeticException if the scale of the amount is too large 772 */ 773 public Money plus(BigDecimal amountToAdd) { 774 return plus(amountToAdd, RoundingMode.UNNECESSARY); 775 } 776 777 /** 778 * Returns a copy of this monetary value with the amount added. 779 * <p> 780 * This adds the specified amount to this monetary amount, returning a new object. 781 * If the amount to add exceeds the scale of the currency, then the 782 * rounding mode will be used to adjust the result. 783 * <p> 784 * This instance is immutable and unaffected by this method. 785 * 786 * @param amountToAdd the monetary value to add, not null 787 * @param roundingMode the rounding mode to use, not null 788 * @return the new instance with the input amount added, never null 789 */ 790 public Money plus(BigDecimal amountToAdd, RoundingMode roundingMode) { 791 return with(money.plusRetainScale(amountToAdd, roundingMode)); 792 } 793 794 /** 795 * Returns a copy of this monetary value with the amount added. 796 * <p> 797 * This adds the specified amount to this monetary amount, returning a new object. 798 * No rounding is performed on the amount to be added, so it must have a 799 * scale compatible with the currency. 800 * <p> 801 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 802 * the most expected answer for most programming scenarios. 803 * Any {@code double} literal in code will be converted to 804 * exactly the same BigDecimal with the same scale. 805 * For example, the literal '1.45d' will be converted to '1.45'. 806 * <p> 807 * This instance is immutable and unaffected by this method. 808 * 809 * @param amountToAdd the monetary value to add, not null 810 * @return the new instance with the input amount added, never null 811 * @throws ArithmeticException if the scale of the amount is too large 812 */ 813 public Money plus(double amountToAdd) { 814 return plus(amountToAdd, RoundingMode.UNNECESSARY); 815 } 816 817 /** 818 * Returns a copy of this monetary value with the amount added. 819 * <p> 820 * This adds the specified amount to this monetary amount, returning a new object. 821 * If the amount to add exceeds the scale of the currency, then the 822 * rounding mode will be used to adjust the result. 823 * <p> 824 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 825 * the most expected answer for most programming scenarios. 826 * Any {@code double} literal in code will be converted to 827 * exactly the same BigDecimal with the same scale. 828 * For example, the literal '1.45d' will be converted to '1.45'. 829 * <p> 830 * This instance is immutable and unaffected by this method. 831 * 832 * @param amountToAdd the monetary value to add, not null 833 * @param roundingMode the rounding mode to use, not null 834 * @return the new instance with the input amount added, never null 835 */ 836 public Money plus(double amountToAdd, RoundingMode roundingMode) { 837 return with(money.plusRetainScale(amountToAdd, roundingMode)); 838 } 839 840 /** 841 * Returns a copy of this monetary value with the amount in major units added. 842 * <p> 843 * This adds an amount in major units, leaving the minor units untouched. 844 * For example, USD 23.45 plus 138 gives USD 161.45. 845 * <p> 846 * This instance is immutable and unaffected by this method. 847 * 848 * @param amountToAdd the monetary value to add, not null 849 * @return the new instance with the input amount added, never null 850 */ 851 public Money plusMajor(long amountToAdd) { 852 return with(money.plusMajor(amountToAdd)); 853 } 854 855 /** 856 * Returns a copy of this monetary value with the amount in minor units added. 857 * <p> 858 * This adds an amount in minor units. 859 * For example, USD 23.45 plus 138 gives USD 24.83. 860 * <p> 861 * This instance is immutable and unaffected by this method. 862 * 863 * @param amountToAdd the monetary value to add, not null 864 * @return the new instance with the input amount added, never null 865 */ 866 public Money plusMinor(long amountToAdd) { 867 return with(money.plusMinor(amountToAdd)); 868 } 869 870 //----------------------------------------------------------------------- 871 /** 872 * Returns a copy of this monetary value with a collection of monetary amounts subtracted. 873 * <p> 874 * This subtracts the specified amounts from this monetary amount, returning a new object. 875 * The amounts must be in the same currency. 876 * <p> 877 * This instance is immutable and unaffected by this method. 878 * 879 * @param moniesToSubtract the monetary values to subtract, no null elements, not null 880 * @return the new instance with the input amounts subtracted, never null 881 * @throws CurrencyMismatchException if the currencies differ 882 */ 883 public Money minus(Iterable<Money> moniesToSubtract) { 884 return with(money.minus(moniesToSubtract)); 885 } 886 887 //----------------------------------------------------------------------- 888 /** 889 * Returns a copy of this monetary value with the amount subtracted. 890 * <p> 891 * This subtracts the specified amount from this monetary amount, returning a new object. 892 * The amount subtracted must be in the same currency. 893 * <p> 894 * The subtraction has no rounding issues and is always accurate. 895 * For example,'USD 25.95' minus 'USD 3.02' will 'USD 22.93'. 896 * <p> 897 * This instance is immutable and unaffected by this method. 898 * 899 * @param moneyToSubtract the monetary value to subtract, not null 900 * @return the new instance with the input amount subtracted, never null 901 * @throws CurrencyMismatchException if the currencies differ 902 */ 903 public Money minus(Money moneyToSubtract) { 904 return with(money.minus(moneyToSubtract)); 905 } 906 907 /** 908 * Returns a copy of this monetary value with the amount subtracted. 909 * <p> 910 * This subtracts the specified amount from this monetary amount, returning a new object. 911 * No rounding is performed on the amount to be subtracted, so it must have a 912 * scale compatible with the currency. 913 * <p> 914 * This instance is immutable and unaffected by this method. 915 * 916 * @param amountToSubtract the monetary value to subtract, not null 917 * @return the new instance with the input amount subtracted, never null 918 * @throws ArithmeticException if the scale of the amount is too large 919 */ 920 public Money minus(BigDecimal amountToSubtract) { 921 return minus(amountToSubtract, RoundingMode.UNNECESSARY); 922 } 923 924 /** 925 * Returns a copy of this monetary value with the amount subtracted. 926 * <p> 927 * This subtracts the specified amount from this monetary amount, returning a new object. 928 * If the amount to subtract exceeds the scale of the currency, then the 929 * rounding mode will be used to adjust the result. 930 * <p> 931 * This instance is immutable and unaffected by this method. 932 * 933 * @param amountToSubtract the monetary value to subtract, not null 934 * @param roundingMode the rounding mode to use, not null 935 * @return the new instance with the input amount subtracted, never null 936 */ 937 public Money minus(BigDecimal amountToSubtract, RoundingMode roundingMode) { 938 return with(money.minusRetainScale(amountToSubtract, roundingMode)); 939 } 940 941 /** 942 * Returns a copy of this monetary value with the amount subtracted. 943 * <p> 944 * This subtracts the specified amount from this monetary amount, returning a new object. 945 * No rounding is performed on the amount to be subtracted, so it must have a 946 * scale compatible with the currency. 947 * <p> 948 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 949 * the most expected answer for most programming scenarios. 950 * Any {@code double} literal in code will be converted to 951 * exactly the same BigDecimal with the same scale. 952 * For example, the literal '1.45d' will be converted to '1.45'. 953 * <p> 954 * This instance is immutable and unaffected by this method. 955 * 956 * @param amountToSubtract the monetary value to subtract, not null 957 * @return the new instance with the input amount subtracted, never null 958 * @throws ArithmeticException if the scale of the amount is too large 959 */ 960 public Money minus(double amountToSubtract) { 961 return minus(amountToSubtract, RoundingMode.UNNECESSARY); 962 } 963 964 /** 965 * Returns a copy of this monetary value with the amount subtracted. 966 * <p> 967 * This subtracts the specified amount from this monetary amount, returning a new object. 968 * If the amount to subtract exceeds the scale of the currency, then the 969 * rounding mode will be used to adjust the result. 970 * <p> 971 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 972 * the most expected answer for most programming scenarios. 973 * Any {@code double} literal in code will be converted to 974 * exactly the same BigDecimal with the same scale. 975 * For example, the literal '1.45d' will be converted to '1.45'. 976 * <p> 977 * This instance is immutable and unaffected by this method. 978 * 979 * @param amountToSubtract the monetary value to subtract, not null 980 * @param roundingMode the rounding mode to use, not null 981 * @return the new instance with the input amount subtracted, never null 982 */ 983 public Money minus(double amountToSubtract, RoundingMode roundingMode) { 984 return with(money.minusRetainScale(amountToSubtract, roundingMode)); 985 } 986 987 /** 988 * Returns a copy of this monetary value with the amount in major units subtracted. 989 * <p> 990 * This subtracts an amount in major units, leaving the minor units untouched. 991 * For example, USD 23.45 minus 138 gives USD -114.55. 992 * <p> 993 * This instance is immutable and unaffected by this method. 994 * 995 * @param amountToSubtract the monetary value to subtract, not null 996 * @return the new instance with the input amount subtracted, never null 997 */ 998 public Money minusMajor(long amountToSubtract) { 999 return with(money.minusMajor(amountToSubtract)); 1000 } 1001 1002 /** 1003 * Returns a copy of this monetary value with the amount in minor units subtracted. 1004 * <p> 1005 * This subtracts an amount in minor units. 1006 * For example, USD 23.45 minus 138 gives USD 22.07. 1007 * <p> 1008 * This instance is immutable and unaffected by this method. 1009 * 1010 * @param amountToSubtract the monetary value to subtract, not null 1011 * @return the new instance with the input amount subtracted, never null 1012 */ 1013 public Money minusMinor(long amountToSubtract) { 1014 return with(money.minusMinor(amountToSubtract)); 1015 } 1016 1017 //----------------------------------------------------------------------- 1018 /** 1019 * Returns a copy of this monetary value multiplied by the specified value. 1020 * <p> 1021 * This takes this amount and multiplies it by the specified value, rounding 1022 * the result is rounded as specified. 1023 * <p> 1024 * This instance is immutable and unaffected by this method. 1025 * 1026 * @param valueToMultiplyBy the scalar value to multiply by, not null 1027 * @param roundingMode the rounding mode to use to bring the decimal places back in line, not null 1028 * @return the new multiplied instance, never null 1029 * @throws ArithmeticException if the rounding fails 1030 */ 1031 public Money multipliedBy(BigDecimal valueToMultiplyBy, RoundingMode roundingMode) { 1032 return with(money.multiplyRetainScale(valueToMultiplyBy, roundingMode)); 1033 } 1034 1035 /** 1036 * Returns a copy of this monetary value multiplied by the specified value. 1037 * <p> 1038 * This takes this amount and multiplies it by the specified value, rounding 1039 * the result is rounded as specified. 1040 * <p> 1041 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 1042 * the most expected answer for most programming scenarios. 1043 * Any {@code double} literal in code will be converted to 1044 * exactly the same BigDecimal with the same scale. 1045 * For example, the literal '1.45d' will be converted to '1.45'. 1046 * <p> 1047 * This instance is immutable and unaffected by this method. 1048 * 1049 * @param valueToMultiplyBy the scalar value to multiply by, not null 1050 * @param roundingMode the rounding mode to use to bring the decimal places back in line, not null 1051 * @return the new multiplied instance, never null 1052 * @throws ArithmeticException if the rounding fails 1053 */ 1054 public Money multipliedBy(double valueToMultiplyBy, RoundingMode roundingMode) { 1055 return with(money.multiplyRetainScale(valueToMultiplyBy, roundingMode)); 1056 } 1057 1058 /** 1059 * Returns a copy of this monetary value multiplied by the specified value. 1060 * <p> 1061 * This takes this amount and multiplies it by the specified value. 1062 * <p> 1063 * This instance is immutable and unaffected by this method. 1064 * 1065 * @param valueToMultiplyBy the scalar value to multiply by, not null 1066 * @return the new multiplied instance, never null 1067 */ 1068 public Money multipliedBy(long valueToMultiplyBy) { 1069 return with(money.multipliedBy(valueToMultiplyBy)); 1070 } 1071 1072 //----------------------------------------------------------------------- 1073 /** 1074 * Returns a copy of this monetary value divided by the specified value. 1075 * <p> 1076 * This takes this amount and divides it by the specified value, rounding 1077 * the result is rounded as specified. 1078 * <p> 1079 * This instance is immutable and unaffected by this method. 1080 * 1081 * @param valueToDivideBy the scalar value to divide by, not null 1082 * @param roundingMode the rounding mode to use, not null 1083 * @return the new divided instance, never null 1084 * @throws ArithmeticException if dividing by zero 1085 * @throws ArithmeticException if the rounding fails 1086 */ 1087 public Money dividedBy(BigDecimal valueToDivideBy, RoundingMode roundingMode) { 1088 return with(money.dividedBy(valueToDivideBy, roundingMode)); 1089 } 1090 1091 /** 1092 * Returns a copy of this monetary value divided by the specified value. 1093 * <p> 1094 * This takes this amount and divides it by the specified value, rounding 1095 * the result is rounded as specified. 1096 * <p> 1097 * The amount is converted via {@link BigDecimal#valueOf(double)} which yields 1098 * the most expected answer for most programming scenarios. 1099 * Any {@code double} literal in code will be converted to 1100 * exactly the same BigDecimal with the same scale. 1101 * For example, the literal '1.45d' will be converted to '1.45'. 1102 * <p> 1103 * This instance is immutable and unaffected by this method. 1104 * 1105 * @param valueToDivideBy the scalar value to divide by, not null 1106 * @param roundingMode the rounding mode to use, not null 1107 * @return the new divided instance, never null 1108 * @throws ArithmeticException if dividing by zero 1109 * @throws ArithmeticException if the rounding fails 1110 */ 1111 public Money dividedBy(double valueToDivideBy, RoundingMode roundingMode) { 1112 return with(money.dividedBy(valueToDivideBy, roundingMode)); 1113 } 1114 1115 /** 1116 * Returns a copy of this monetary value divided by the specified value. 1117 * <p> 1118 * This takes this amount and divides it by the specified value, rounding 1119 * the result is rounded as specified. 1120 * <p> 1121 * This instance is immutable and unaffected by this method. 1122 * 1123 * @param valueToDivideBy the scalar value to divide by, not null 1124 * @param roundingMode the rounding mode to use, not null 1125 * @return the new divided instance, never null 1126 * @throws ArithmeticException if dividing by zero 1127 * @throws ArithmeticException if the rounding fails 1128 */ 1129 public Money dividedBy(long valueToDivideBy, RoundingMode roundingMode) { 1130 return with(money.dividedBy(valueToDivideBy, roundingMode)); 1131 } 1132 1133 //----------------------------------------------------------------------- 1134 /** 1135 * Returns a copy of this monetary value with the amount negated. 1136 * <p> 1137 * This instance is immutable and unaffected by this method. 1138 * 1139 * @return the new instance with the amount negated, never null 1140 */ 1141 public Money negated() { 1142 return with(money.negated()); 1143 } 1144 1145 /** 1146 * Returns a copy of this monetary value with a positive amount. 1147 * <p> 1148 * This instance is immutable and unaffected by this method. 1149 * 1150 * @return the new instance with the amount converted to be positive, never null 1151 */ 1152 public Money abs() { 1153 return (isNegative() ? negated() : this); 1154 } 1155 1156 //----------------------------------------------------------------------- 1157 /** 1158 * Returns a copy of this monetary value rounded to the specified scale without 1159 * changing the current scale. 1160 * <p> 1161 * Scale has the same meaning as in {@link BigDecimal}. 1162 * A scale of 2 means round to 2 decimal places. 1163 * <ul> 1164 * <li>Rounding 'EUR 45.23' to a scale of -1 returns 40.00 or 50.00 depending on the rounding mode. 1165 * <li>Rounding 'EUR 45.23' to a scale of 0 returns 45.00 or 46.00 depending on the rounding mode. 1166 * <li>Rounding 'EUR 45.23' to a scale of 1 returns 45.20 or 45.30 depending on the rounding mode. 1167 * <li>Rounding 'EUR 45.23' to a scale of 2 has no effect (it already has that scale). 1168 * <li>Rounding 'EUR 45.23' to a scale of 3 has no effect (the scale is not increased). 1169 * </ul> 1170 * <p> 1171 * This instance is immutable and unaffected by this method. 1172 * 1173 * @param scale the new scale 1174 * @param roundingMode the rounding mode to use, not null 1175 * @return the new instance with the amount converted to be positive, never null 1176 * @throws ArithmeticException if the rounding fails 1177 */ 1178 public Money rounded(int scale, RoundingMode roundingMode) { 1179 return with(money.rounded(scale, roundingMode)); 1180 } 1181 1182 //----------------------------------------------------------------------- 1183 /** 1184 * Returns a copy of this monetary value converted into another currency 1185 * using the specified conversion rate, with a rounding mode used to adjust 1186 * the decimal places in the result. 1187 * <p> 1188 * This instance is immutable and unaffected by this method. 1189 * 1190 * @param currency the new currency, not null 1191 * @param conversionMultipler the conversion factor between the currencies, not null 1192 * @param roundingMode the rounding mode to use to bring the decimal places back in line, not null 1193 * @return the new multiplied instance, never null 1194 * @throws IllegalArgumentException if the currency is the same as this currency 1195 * @throws IllegalArgumentException if the conversion multiplier is negative 1196 * @throws ArithmeticException if the rounding fails 1197 */ 1198 public Money convertedTo(CurrencyUnit currency, BigDecimal conversionMultipler, RoundingMode roundingMode) { 1199 return with(money.convertedTo(currency, conversionMultipler).withCurrencyScale(roundingMode)); 1200 } 1201 1202 //----------------------------------------------------------------------- 1203 /** 1204 * Implements the {@code BigMoneyProvider} interface, returning a 1205 * {@code BigMoney} instance with the same currency, amount and scale. 1206 * 1207 * @return the money instance, never null 1208 */ 1209 public BigMoney toBigMoney() { 1210 return money; 1211 } 1212 1213 //----------------------------------------------------------------------- 1214 /** 1215 * Checks if this instance and the specified instance have the same currency. 1216 * 1217 * @param other the money to check, not null 1218 * @return true if they have the same currency 1219 */ 1220 public boolean isSameCurrency(BigMoneyProvider other) { 1221 return money.isSameCurrency(other); 1222 } 1223 1224 //----------------------------------------------------------------------- 1225 /** 1226 * Compares this monetary value to another. 1227 * <p> 1228 * This allows {@code Money} to be compared to any {@code BigMoneyProvider}. 1229 * Scale is ignored in the comparison. 1230 * The compared values must be in the same currency. 1231 * 1232 * @param other the other monetary value, not null 1233 * @return -1 if this is less than , 0 if equal, 1 if greater than 1234 * @throws CurrencyMismatchException if the currencies differ 1235 */ 1236 public int compareTo(BigMoneyProvider other) { 1237 return money.compareTo(other); 1238 } 1239 1240 /** 1241 * Checks if this monetary value is equal to another. 1242 * <p> 1243 * This allows {@code Money} to be compared to any {@code BigMoneyProvider}. 1244 * Scale is ignored, so 'USD 30.00' and 'USD 30' are equal. 1245 * The compared values must be in the same currency. 1246 * 1247 * @param other the other monetary value, not null 1248 * @return true is this is greater than the specified monetary value 1249 * @throws CurrencyMismatchException if the currencies differ 1250 * @see #equals(Object) 1251 */ 1252 public boolean isEqual(BigMoneyProvider other) { 1253 return money.isEqual(other); 1254 } 1255 1256 /** 1257 * Checks if this monetary value is greater than another. 1258 * <p> 1259 * This allows {@code Money} to be compared to any {@code BigMoneyProvider}. 1260 * Scale is ignored in the comparison. 1261 * The compared values must be in the same currency. 1262 * 1263 * @param other the other monetary value, not null 1264 * @return true is this is greater than the specified monetary value 1265 * @throws CurrencyMismatchException if the currencies differ 1266 */ 1267 public boolean isGreaterThan(BigMoneyProvider other) { 1268 return money.isGreaterThan(other); 1269 } 1270 1271 /** 1272 * Checks if this monetary value is less than another. 1273 * <p> 1274 * This allows {@code Money} to be compared to any {@code BigMoneyProvider}. 1275 * Scale is ignored in the comparison. 1276 * The compared values must be in the same currency. 1277 * 1278 * @param other the other monetary value, not null 1279 * @return true is this is less than the specified monetary value 1280 * @throws CurrencyMismatchException if the currencies differ 1281 */ 1282 public boolean isLessThan(BigMoneyProvider other) { 1283 return money.isLessThan(other); 1284 } 1285 1286 //----------------------------------------------------------------------- 1287 /** 1288 * Checks if this monetary value equals another. 1289 * <p> 1290 * The comparison takes into account the scale. 1291 * The compared values must be in the same currency. 1292 * 1293 * @param other the other object to compare to, not null 1294 * @return true if this instance equals the other instance 1295 */ 1296 @Override 1297 public boolean equals(Object other) { 1298 if (this == other) { 1299 return true; 1300 } 1301 if (other instanceof Money) { 1302 Money otherMoney = (Money) other; 1303 return money.equals(otherMoney.money); 1304 } 1305 return false; 1306 } 1307 1308 /** 1309 * Returns a hash code for this monetary value. 1310 * 1311 * @return a suitable hash code 1312 */ 1313 @Override 1314 public int hashCode() { 1315 return money.hashCode() + 3; 1316 } 1317 1318 //----------------------------------------------------------------------- 1319 /** 1320 * Gets the monetary value as a string. 1321 * <p> 1322 * The format is the 3 letter ISO currency code, followed by a space, 1323 * followed by the amount as per {@link BigDecimal#toPlainString()}. 1324 * 1325 * @return the string representation of this monetary value, never null 1326 */ 1327 @Override 1328 @ToString 1329 public String toString() { 1330 return money.toString(); 1331 } 1332 1333 }