1 package junit.samples.money;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6
7
8
9
10
11
12
13
14
15
16
17 public class MoneyBag implements IMoney {
18 private List<Money> fMonies = new ArrayList<Money>(5);
19
20 public static IMoney create(IMoney m1, IMoney m2) {
21 MoneyBag result = new MoneyBag();
22 m1.appendTo(result);
23 m2.appendTo(result);
24 return result.simplify();
25 }
26
27 public IMoney add(IMoney m) {
28 return m.addMoneyBag(this);
29 }
30
31 public IMoney addMoney(Money m) {
32 return MoneyBag.create(m, this);
33 }
34
35 public IMoney addMoneyBag(MoneyBag s) {
36 return MoneyBag.create(s, this);
37 }
38
39 void appendBag(MoneyBag aBag) {
40 for (Money each : aBag.fMonies) {
41 appendMoney(each);
42 }
43 }
44
45 void appendMoney(Money aMoney) {
46 if (aMoney.isZero()) return;
47 IMoney old = findMoney(aMoney.currency());
48 if (old == null) {
49 fMonies.add(aMoney);
50 return;
51 }
52 fMonies.remove(old);
53 Money sum = (Money) old.add(aMoney);
54 if (sum.isZero()) {
55 return;
56 }
57 fMonies.add(sum);
58 }
59
60 @Override
61 public boolean equals(Object anObject) {
62 if (isZero()) {
63 if (anObject instanceof IMoney) {
64 return ((IMoney) anObject).isZero();
65 }
66 }
67
68 if (anObject instanceof MoneyBag) {
69 MoneyBag aMoneyBag = (MoneyBag) anObject;
70 if (aMoneyBag.fMonies.size() != fMonies.size()) {
71 return false;
72 }
73
74 for (Money each : fMonies) {
75 if (!aMoneyBag.contains(each)) {
76 return false;
77 }
78 }
79 return true;
80 }
81 return false;
82 }
83
84 private Money findMoney(String currency) {
85 for (Money each : fMonies) {
86 if (each.currency().equals(currency)) {
87 return each;
88 }
89 }
90 return null;
91 }
92
93 private boolean contains(Money m) {
94 Money found = findMoney(m.currency());
95 if (found == null) return false;
96 return found.amount() == m.amount();
97 }
98
99 @Override
100 public int hashCode() {
101 int hash = 0;
102 for (Money each : fMonies) {
103 hash ^= each.hashCode();
104 }
105 return hash;
106 }
107
108 public boolean isZero() {
109 return fMonies.size() == 0;
110 }
111
112 public IMoney multiply(int factor) {
113 MoneyBag result = new MoneyBag();
114 if (factor != 0) {
115 for (Money each : fMonies) {
116 result.appendMoney((Money) each.multiply(factor));
117 }
118 }
119 return result;
120 }
121
122 public IMoney negate() {
123 MoneyBag result = new MoneyBag();
124 for (Money each : fMonies) {
125 result.appendMoney((Money) each.negate());
126 }
127 return result;
128 }
129
130 private IMoney simplify() {
131 if (fMonies.size() == 1) {
132 return fMonies.iterator().next();
133 }
134 return this;
135 }
136
137 public IMoney subtract(IMoney m) {
138 return add(m.negate());
139 }
140
141 @Override
142 public String toString() {
143 StringBuilder sb = new StringBuilder();
144 sb.append("{");
145 for (Money each : fMonies) {
146 sb.append(each);
147 }
148 sb.append("}");
149 return sb.toString();
150 }
151
152 public void appendTo(MoneyBag m) {
153 m.appendBag(this);
154 }
155 }