-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResizableArrayBag.java
More file actions
391 lines (325 loc) · 11 KB
/
ResizableArrayBag.java
File metadata and controls
391 lines (325 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
import java.util.Arrays;
/**
A class that implements a bag of objects by using an array.
The bag is never full.
@author Frank M. Carrano, Timothy M. Henry
@version 5.0
*/
public final class ResizableArrayBag<T> implements BagInterface<T>
{
private T[] bag; // Cannot be final due to doubling
private int numberOfEntries;
private boolean integrityOK = false;
private static final int DEFAULT_CAPACITY = 25; // Initial capacity of bag
private static final int MAX_CAPACITY = 10000;
/** Creates an empty bag whose initial capacity is 25. */
public ResizableArrayBag()
{
this(DEFAULT_CAPACITY);
} // end default constructor
/** Creates an empty bag having a given initial capacity.
@param initialCapacity The integer capacity desired. */
public ResizableArrayBag(int initialCapacity)
{
checkCapacity(initialCapacity);
// The cast is safe because the new array contains null entries
@SuppressWarnings("unchecked")
T[] tempBag = (T[])new Object[initialCapacity]; // Unchecked cast
bag = tempBag;
numberOfEntries = 0;
integrityOK = true;
} // end constructor
/** Creates a bag containing given entries.
@param contents An array of objects. */
public ResizableArrayBag(T[] contents)
{
checkCapacity(contents.length);
bag = Arrays.copyOf(contents, contents.length);
numberOfEntries = contents.length;
integrityOK = true;
} // end constructor
/** Adds a new entry to this bag.
@param newEntry The object to be added as a new entry.
@return True. */
public boolean add(T newEntry)
{
checkintegrity();
if (isArrayFull())
{
doubleCapacity();
} // end if
bag[numberOfEntries] = newEntry;
numberOfEntries++;
return true;
} // end add
/** Retrieves all entries that are in this bag.
@return A newly allocated array of all the entries in this bag. */
public T[] toArray()
{
checkintegrity();
// The cast is safe because the new array contains null entries.
@SuppressWarnings("unchecked")
T[] result = (T[])new Object[numberOfEntries]; // Unchecked cast
for (int index = 0; index < numberOfEntries; index++)
{
result[index] = bag[index];
} // end for
return result;
} // end toArray
/** Sees whether this bag is empty.
@return True if this bag is empty, or false if not. */
public boolean isEmpty()
{
return numberOfEntries == 0;
} // end isEmpty
/** Gets the current number of entries in this bag.
@return The integer number of entries currently in this bag. */
public int getCurrentSize()
{
return numberOfEntries;
} // end getCurrentSize
/** Counts the number of times a given entry appears in this bag.
@param anEntry The entry to be counted.
@return The number of times anEntry appears in this ba. */
public int getFrequencyOf(T anEntry)
{
checkintegrity();
int counter = 0;
for (int index = 0; index < numberOfEntries; index++)
{
if (anEntry.equals(bag[index]))
{
counter++;
} // end if
} // end for
return counter;
} // end getFrequencyOf
/** Tests whether this bag contains a given entry.
@param anEntry The entry to locate.
@return True if this bag contains anEntry, or false otherwise. */
public boolean contains(T anEntry)
{
checkintegrity();
return getIndexOf(anEntry) > -1; // or >= 0
} // end contains
/** Removes all entries from this bag. */
public void clear()
{
while (!isEmpty())
remove();
} // end clear
/** Removes one unspecified entry from this bag, if possible.
@return Either the removed entry, if the removal
was successful, or null. */
public T remove()
{
checkintegrity();
T result = removeEntry(numberOfEntries - 1);
return result;
} // end remove
/** Removes one occurrence of a given entry from this bag.
@param anEntry The entry to be removed.
@return True if the removal was successful, or false if not. */
public boolean remove(T anEntry)
{
checkintegrity();
int index = getIndexOf(anEntry);
T result = removeEntry(index);
return anEntry.equals(result);
} // end remove
/**
* @param anEntry
* @return int
*/
// Locates a given entry within the array bag.
// Returns the index of the entry, if located,
// or -1 otherwise.
// Precondition: checkintegrity has been called.
private int getIndexOf(T anEntry)
{
int where = -1;
boolean found = false;
int index = 0;
while (!found && (index < numberOfEntries))
{
if (anEntry.equals(bag[index]))
{
found = true;
where = index;
} // end if
index++;
} // end while
// Assertion: If where > -1, anEntry is in the array bag, and it
// equals bag[where]; otherwise, anEntry is not in the array.
return where;
} // end getIndexOf
/**
* @param givenIndex
* @return T
*/
// Removes and returns the entry at a given index within the array.
// If no such entry exists, returns null.
// Precondition: 0 <= givenIndex < numberOfEntries.
// Precondition: checkintegrity has been called.
private T removeEntry(int givenIndex)
{
T result = null;
if (!isEmpty() && (givenIndex >= 0))
{
result = bag[givenIndex]; // Entry to remove
int lastIndex = numberOfEntries - 1;
bag[givenIndex] = bag[lastIndex]; // Replace entry to remove with last entry
bag[lastIndex] = null; // Remove reference to last entry
numberOfEntries--;
} // end if
return result;
} // end removeEntry
/**
* @return boolean
*/
// Returns true if the array bag is full, or false if not.
private boolean isArrayFull()
{
return numberOfEntries >= bag.length;
} // end isArrayFull
// Doubles the size of the array bag.
// Precondition: checkInitialization has been called.
private void doubleCapacity()
{
int newLength = 2 * bag.length;
checkCapacity(newLength);
bag = Arrays.copyOf(bag, newLength);
} // end doubleCapacity
/**
* @param capacity
*/
// Throws an exception if the client requests a capacity that is too large.
private void checkCapacity(int capacity)
{
if (capacity > MAX_CAPACITY)
throw new IllegalStateException("Attempt to create a bag whose capacity exceeds " +
"allowed maximum of " + MAX_CAPACITY);
} // end checkCapacity
// Throws an exception if receiving object is not initialized.
private void checkintegrity()
{
if (!integrityOK)
throw new SecurityException ("ArrayBag object is corrupt.");
} // end checkintegrity
/** Combines the contents of two bags into another bag.
@param bag2 Second bag.
@return combined, combined bag of contents from both bags. */
public BagInterface<T> union(BagInterface<T> bag2){
checkintegrity();
BagInterface<T> combined = new ResizableArrayBag<T>();
T[] firstbag = this.toArray();
T[] secondbag = bag2.toArray();
for (int i = 0; i < numberOfEntries; i++){
combined.add(firstbag[i]);
} // end for
for (int i = 0; i < bag2.getCurrentSize(); i++){
combined.add(secondbag[i]);
} // end for
return combined;
} // end union
/** Combines only like contents of two bags into another bag.
@param bag2 Second bag.
@return combined, combined bag of like contents. */
public BagInterface<T> intersection(BagInterface<T> bag2){
checkintegrity();
BagInterface<T> compare = new ResizableArrayBag<T>();
BagInterface<T> combined = new ResizableArrayBag<T>();
T[] firstbag = this.toArray();
T[] secondbag = bag2.toArray();
for(int i = 0; i < numberOfEntries; i++){
compare.add(firstbag[i]);
} // end for
for(int i = 0; i < bag2.getCurrentSize(); i++){
if(compare.contains(secondbag[i])){
combined.add(secondbag[i]);
} // end if
} // end for
return combined;
} // end intersection
/*
Trying to come up with different ways to iterate difference:
public BagInterface<T> difference2(BagInterface<T> bag2){
BagInterface<T> diff = new ResizableArrayBag<T>();
T[] firstbag = this.toArray();
//T[] secondbag = bag2.toArray();
for (int i = 0; i < numberOfEntries; i++){
if (this.getFrequencyOf(firstbag[i]) > bag2.getFrequencyOf(firstbag[i])){
for(int j = 0; j < (this.getFrequencyOf(firstbag[i]) - bag2.getFrequencyOf(firstbag[i])); j++){
diff.add(firstbag[i]);
}
}
}
return diff;
}
*/
/** Creates a collection of entries that would be left in one collection, after removing
* those that also occur in the second.
@param bag2 Second bag.
@return compare, new collection of entries after second bag contents are removed from first bag. */
public BagInterface<T> difference(BagInterface<T> bag2){
checkintegrity();
BagInterface<T> compare = new ResizableArrayBag<T>();
T[] firstbag = this.toArray();
T[] secondbag = bag2.toArray();
for(int i = 0; i < numberOfEntries; i++){
compare.add(firstbag[i]);
} // end for
for(int i = 0; i < bag2.getCurrentSize(); i++){
if(compare.contains(secondbag[i])){
compare.remove(secondbag[i]);
} // end if
} // end for
return compare;
} // end difference
} // end ResizableArrayBag
/*
Testing isEmpty with an empty bag:
isEmpty finds the bag empty: OK.
Adding to the bag more strings than its initial capacity.
Adding to the bag: A D B A C A D
The bag contains 7 string(s), as follows:
A D B A C A D
Testing isEmpty with a bag that is not empty:
isEmpty finds the bag not empty: OK.
Testing the method getFrequencyOf:
In this bag, the count of A is 3
In this bag, the count of B is 1
In this bag, the count of C is 1
In this bag, the count of D is 2
In this bag, the count of Z is 0
Testing the method contains:
Does this bag contain A? true
Does this bag contain B? true
Does this bag contain C? true
Does this bag contain D? true
Does this bag contain Z? false
Removing a string from the bag:
remove() returns D
The bag contains 6 string(s), as follows:
A D B A C A
Removing "B" from the bag:
remove("B") returns true
The bag contains 5 string(s), as follows:
A D A A C
Removing "A" from the bag:
remove("A") returns true
The bag contains 4 string(s), as follows:
C D A A
Removing "C" from the bag:
remove("C") returns true
The bag contains 3 string(s), as follows:
A D A
Removing "Z" from the bag:
remove("Z") returns false
The bag contains 3 string(s), as follows:
A D A
Clearing the bag:
Testing isEmpty with an empty bag:
isEmpty finds the bag empty: OK.
The bag contains 0 string(s), as follows:
*/