Download presentation
Presentation is loading. Please wait.
1
Implementing Bags with Arrays
Chapter 2
2
Today Array instance variables Core methods of a container
partly filled arrays Core methods of a container Securing your container Methods for removing from the bag Other Bag methods Array Resizing
3
Sample ADT: the Bag A finite collection of objects in no particular order, possibly with duplicates compare a list: in some particular order compare a set: no duplicates allowed Lists, sets and bags are all containers object to group other objects similar actions
4
<<interface>> Bag<T>
Bag UML Diagram T is a “generic” type each bag will specify its own “base” type <<interface>> Bag<T> +getCurrentSize(): integer +isEmpty(): boolean +add(newEntry: T): boolean +remove(anEntry: T) : boolean +remove(): T +clear(): void +contains(anEnty: T): boolean +getFrequencyOf(enEntry: T): integer +toArray(): T[]
5
BagInterface public interface BagInterface<T> { public int getCurrentSize (); public boolean isEmpty (); public boolean add (T newEntry); public boolean remove (T anEntry); public T remove (); public void clear (); public boolean contains (T anEntry); public int getFrequency (T anEntry); public T[] toArray (); }
6
Bag Implementation/Interface
Want to allow multiple ways to implement an array, a linked list, a kind of structure that hasn’t even been invented yet! Each implementation is its own class ArrayBag, LinkedBag, QuantumBag, … For the ADT, we create an interface BagInterface
7
ArrayBag Implementation
Uses an array to hold the contents public class ArrayBag<T> implements BagInterface<T> { private T[] contents; private int numInBag; Need to specify a size for the array let client choose; provide a default value public ArrayBag(int capacity) { … } public ArrayBag() { this(DEFAULT_CAPACITY); }
8
Core Methods Need to implement every interface method
but start with most important methods and test as you go along Core methods: minimal methods for testing need to be able to add items to the Bag need to see what's in the Bag add and toArray We’ll also need a constructor….
9
Constructor Start with the basics make the array
keep track of how many items are in the bag public ArrayBag(int capacity) { contents = new T[capacity]; numInBag = 0; } problem right away…. generic array creation error
10
Generic Array Creation
Base type T not allowed for an array generics in Java work by erasure Java checks to see you use T consistently… …then replaces T with Object when compiling every different kind of Bag uses the same code at run time, Java doesn’t know what T was Java won’t know what kind of array to create! Just assure Java what you’re doing is OK because it is OK – it’s just that Java can’t tell
11
Constructor Make an array of Objects
assure Java it’s OK to treat it as an array of T because it’s only got nulls in it anyway public ArrayBag(int capacity) { contents = (T[])new Object[capacity]; numInBag = 0; } get a warning message: unchecked or unsafe when we clean and build in NetBeans when we compile from command line
12
Optional: Suppress the Warning
Get warning message: unchecked or unsafe but we know what we’re doing is OK so tell Java not to worry about it but can only do that for declarations, so…. public ArrayBag(int capacity) { @SuppressWarnings("unchecked") T[] temp = (T[])new Object[capacity]; contents = temp; numInBag = 0; }
13
Adding to the Array Consider putting pencils into pencil loops
pencils placed arbitrarily?
14
Using the Array Consider putting pencils into pencil loops
pencils placed arbitrarily? chance of collisions
15
Using the Array Consider putting pencils into pencil loops
fill in from one end (front) place for new pencil == # of pencils before it
16
Using the Array Consider putting pencils into pencil loops
fill in from one end (front) array is full when #pencils == size of array
17
add Method Remember we can’t put nulls in the Bag @Override
public boolean add(T item) { if (numInBag == contents.length || item == null) { return false; } else { contents[numInBag] = item; ++numInBag; return true; }
18
toArray Method (done wrong)
So we can see what’s in there and if it’s in the correct position public T[] toArray() { return contents; } OK? NO! why not OK?
19
Reference Types Arrays are reference types
return contents return a pointer to the array now the client has access to your array what will the client do with your array? possibly something stupid or malicious (Almost) never return an array return a copy instead
20
toArray Method (fixed)
Import java.util.Arrays copyOf(array, number of elements to copy) public T[] toArray() { return Arrays.copyOf(contents, numInBag); } client can only mess about with the copy Bonus! returned array has no empty spaces in it
21
Thinking about Security
New things that can go wrong pass array back to client – security problem solve by passing a copy What else might go wrong? things not considered when doing ADT client asks for array to be a given size what if it’s negative? what if it’s too big for the computer? letting those pass may cause security problems
22
Programming Securely Fail-safe programming:
check for anticipated errors Safe and secure programming: check all arguments and input values eliminate side effects make no assumptions about client/user actions Ensure Bag is unusable if constructor fails create boolean variable for whether it finished
23
Safer Constructor private boolean initialized = false; private static final int MAX_CAPACITY = 10000; public ArrayBag(int capacity) { if (0 < capacity && capacity <= MAX_CAPACITY) T[] temp = (T[])new Object[capacity]; contents = temp; numInBag = 0; initialized = true; } else { throw new IllegalArgumentException("Invalid capacity: " + capacity); }
24
Preventing Use of Invalid Bags
What if some other thing goes wrong? can’t be sure we’ve checked everything Make operations check whether initialized (only methods that access the array) public boolean add(T newItem) { if (initialized) { /* code to add new item here */ } else { throw new SecurityException("ArrayBag not initialized"); }
25
Better Yet Several methods need to check initialization
create a method to check initialization private void checkInitialization() { if (!initialized) { throw new SecurityException("ArrayBag not initialized"); } call that method as required public boolean add(T newItem) { checkInitialization(); /* code to add new item here */
26
Testing the ArrayBag We’re ready to test our class Write a test class
constructor(s), add and toArray complete test those methods before we do more Write a test class create ArrayBag with each constructor test whether add puts items in correct positions try to overflow the array check add’s return value try to get and use an uninitialized ArrayBag
27
On toArray’s Return Type
It seems like this should work: BagInterface<Integer> myBag = new ArrayBag<>(); Integer[] arr = myBag.toArray(); but it doesn’t! program crashes with ClassCastException can’t cast Object[] to Integer[] type erasure is the problem again myBag isn’t a Bag of Integers at run time it’s a Bag of Objects
28
On toArray’s Return Type
Telling Java to cast to Integer[] doesn’t help still get the class cast exception Just have to use an Object[] variable Object[] arr = myBag.toArray(); if necessary, you can cast the elements int sumFirstTow = (Integer)arr[0] + (Integer)arr[1]; But we still declare return type to be T[] because that’s what the ADT says!
29
Remove Methods Two methods: remove() and remove(T)
remove() removes any element return the element removed; null if Bag was empty remove(T) removes the given element return true if removed; false if not Several possible ways to do those things some ways are better than others
30
remove() Remove a pencil at random
pick a number in range [0, numInBag) leaves a hole in the array
31
What Does “Don’t Care” Mean?
Does it mean to remove one at random? NO! removing one at random would be OK, but you don’t have to remove one at random Whichever one is most convenient for you! don’t want to have to fill in a hole… …so remove the last one in the array
32
remove() Remove last pencil in array the one in position numInBag – 1
no hole in the array
33
remove() Check initialization / empty Bag public T remove() {
if (numInBag == 0) { return null; } else { T result = contents[numInBag – 1]; --numInBag; return result; }
34
remove(T) Find the pencil and remove it
the blue pencil is in position 2 it leaves a hole in the array – can’t avoid that!
35
remove(T) Slide the rest of the pencils down?
here we have four pencils to move quite a bit of work
36
Don’t Care, Again Order of pencils is not important
they’re not in any particular order don’t need to keep them in any particular order OK to get them “mixed up”
37
remove(T) Move the last pencil into the open space
only one pencil to move much better
38
Removing a Particular Item
public boolean remove(T anItem) { checkInitialization(); int posn = findItem(anItem); if (posn < 0) { return false; } else { contents[posn] = contents[numInBag – 1]; --numInBag; return true; }
39
Finding the Item Look thru array until find an equals item
return its position in the array (or -1 if none) private int findItem(T anItem) { for (int posn = 0; posn < numInBag; ++posn) { if (contents[posn].equals(anItem)) { return posn; } return -1;
40
Possible Problem What happens if client asks to remove null? Options
ADT says to return false (not removed) but make sure program doesn’t crash! Options check for null argument if (numInBag == 0 || anItem == null) make sure we never ask anItem a question if (contents[posn].equals(anItem)) we know contents[posn] isn’t null
41
Nulling Array Entries Good idea to null out unused array entries
allows them to be garbage collected reclaim space for objects no longer in use our code above didn’t do that it should have done that after deleting/moving item from last position contents[numInBag – 1] = null; add code to both remove() and remove(T) maybe we should make a private method
42
Private Remove Method Remove from a particular location
it’s private, so we have control over position remove() and remove(T) responsible to get it right private T remove(int posn) { T result = contents[posn]; contents[posn] = contents[numInBag – 1]; contents[numInBag – 1] = null; --numInBag; return result; }
43
Revised remove() public T remove() { checkInitialization(); if (numInBag == 0) { return null; } else { T result = remove(numInBag – 1); return result; }
44
Revised remove(T) public boolean remove(T anItem) { checkInitialization(); int posn = findItem(anItem); if (posn < 0) { return false; } else { remove(posn); return true; }
45
Testing Remove Methods
Test your code to make sure it works remove things you know are in the Bag remove things you know aren’t in the Bag remove from the bag till it’s empty checking the return value and then remove some more
46
Other BagInterface Methods
One-liners: public int getCurrentSize() { return numInBag; } public boolean isEmpty() { // this is more efficient than the default provided return numInBag == 0; don't really need to check initialization not using any reference type
47
clear() Method Default method OK here, but… public void clear() {
// slightly faster than the default for (int i = 0; i < numInBag; ++i) { contents[i] = null; } numInBag = 0;
48
contains(T) Method If it’s in there, it has a position >= 0
public boolean contains(T anItem) { checkInitialization(); return findItem(anItem) >= 0; } need to check initialization because….
49
getFrequency(T) Method
Go thru and count make sure null argument doesn’t cause crash public int getFrequency(T anItem) { checkInitialization(); int count = 0; for (int i = 0; i < numInBag; ++i) { if (contents[i].equals(anItem)) { ++count; } return count;
50
Test the Other Methods empty/size before/after adding items
getFrequency with 0, 1, many instances empty/size/contains before/after clearing
51
Extra Methods? ArrayBag might have some extra methods
isFull is a possibility getCapacity is another Don’t make remove(int)/findItem(T) public! they refer to positions in the array client has no access to the array client has no need to know about positions dangerous to give them access to such details
52
ArrayBag Limitations Size fixed when Bag is created
Bag might get full Fine for some applications if client knows maximum size ahead of time But might want a Bag that grows forever or until run out of memory ResizingArrayBag
53
Resizing the Array Make the array bigger to hold more items
how much bigger? if just one space we will need to resize a lot! so double the size of the array but remember that we have an upper limit for size newSize = min(2 * oldSize, MAX_CAPACITY); if newSize is same as oldSize, resizing failed add will need to return false
54
Resizing Our Array Use Arrays.copyOf to make the copy
private boolean resize() { int oldSize = contents.length; int newSize = Math.min(MAX_CAPACITY, 2 * oldSize); if (newSize > oldSize) { contents = Arrays.copyOf(contents, newSize); return true; // resized successsfully } else { return false; // failed to resize }
55
Resizing add(T) If array is full AND we can’t resize it, then return false public boolean add(T newEntry) { checkInitialization(); if (numInBag == contents.length && !resize()) { return false; } contents[numInBag] = newEntry; ++numInBag; return true;
56
“Short Circuit” Evaluation
Recall that && means BOTH parts are true SO, if first is false… i.e. numInBag == contents.length is false i.e. numInBag != contents.length i.e. there’s still space in the bag … then don’t need to check second i.e. resize doesn’t need to be called! Java knows resize doesn’t need to be called, and so doesn’t call it! if there’s room in the Bag, it doesn’t get resized
57
Exercises True or false? 5 > 10 && 51 * 3 < 14 *12
"yes".startsWith("m") && Math.sin(2) > 0.5 1 == 2 && 3 * * 7 + Math.sqrt(18) > 41.2 5 < 1 && Math.ulp(17.4) > Math.scalb(1.1, 6) 10 < 20 || Math.random() < 0.5
58
Questions
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.