CSCI 151 Lab 4: Extensible arrays and dictionaries
Overview
This lab will:
- Give you even more experience working with arrays;
- Teach you about
Objectmethods liketoStringandequals; and - Give you experience working at multiple levels of abstraction.
We will start by improving our GenericExtensibleArray class, and then use our improved arrays to create a better (though not more efficient) Dictionary implementation.
Materials
Setup
Download GenericExtensibleArray.java, GenericAssociation.java, and GenericDictionary.java.
Create a new project in Eclipse called
Lab04(or something similar; really it does not matter what you call it).Now copy
GenericExtensibleArray.java,GenericAssociation.java, andGenericDictionary.javainto your new Eclipse project, either by dragging and dropping them into thesrcpackage, or by right-clicking onsrcand choosing “Import… From File System”. Alternatively, if you simply move them into the appopriate folder on your file system, go back into Eclipse and hit F5 to refresh the project view, and the new files should show up.From now on we will make pretty much everything generic, so there is no need for the classes to actually have the word
Genericin their names. To avoid a bunch of tedious find-and-replace, use Eclipse to change the name of each class to get rid of the wordGeneric: click on the name of the class and chooseRefactor > Renamefrom the menu, or hitAlt + Shift + R.
Part 1: extending ExtensibleArray
Your first assignment is to add more useful methods to ExtensibleArray. Similar methods already exist in ArrayList, and it is important for you to explore how these methods are implemented. In particular, you should add each of the following methods:
public String toString(): TheObjectclass has atoStringmethod which is intended to produce some sort of string representation of an object, and which is called automatically whenever an object gets converted to a string (for example, by printing it withSystem.out.println). The default implementation oftoStringsimply prints out the memory address of an object—not very useful! Typically, we will override the inheritedtoStringso that it returns a more useful string.In particular, you should add a
toStringmethod which returns string representations of the elements of the array (using their owntoStringmethod!) separated by spaces. For example, the following code:ExtensibleArray<Integer> arr = new ExtensibleArray<>(); arr.append(1); arr.append(3); arr.append(7); System.out.printn(arr);should produce the output
1 3 7Be sure to put an
@Overrideannotation on the line before thetoStringmethod, to indicate that we are overriding an inherited method.public int indexOf(E elt): returns the index of the first occurrence of elementeltin theExtensibleArray. If no element of theExtensibleArrayis equal toelt, it should return -1 instead. (Remember to use.equalsto test for equality, not==!)public E find(E elt): finds the first element which isequaltoeltand returns it (ornullif the element is not found). This may seem pointless (why return an element when we already know what it is?), but the purpose will become clearer in the next few sections.Hint: your implementation of
findshould only be one or two lines long, if you make use ofindexOf.public E removeElementAt(int index): delete the element atindex, and return the element that was deleted. “Delete” means to shift all the following elements over by one position. For example, this code:System.out.println(v); v.removeElementAt(3); System.out.println(v);might produce this output:
1 3 17 25 0 9 8 1 3 17 0 9 8public void remove(E elt): delete the first occurrence of an element which isequaltoelt. For example, this code:System.out.println(v); v.remove(3); System.out.println(v);might produce this output:
1 3 17 25 0 3 8 1 17 25 0 3 8Hint: again, this method should only be a few lines long. Think about how to reuse functionality you have already implemented.
public void add(int index, E elt): inserts the new elementeltso that it is now atindex, by shifting later elements over one spot to make room. For example, this code:System.out.println(v); v.add(4, 6984); System.out.println(v);might produce this output:
1 3 17 25 0 3 8 1 3 17 25 6984 0 3 8Notice that
getorremoveElementAtrequire an index0 <= i < length, butaddrequires an index0 <= i <= length. That is,lengthis a valid index foradd, which corresponds to inserting an element at the very end of theExtensibleArray.Note also that it is allowed to have two methods named
add, as long as Java can tell them apart by their arguments. Typically, methods with the same name will perform variants of the same task. In this case,addwith a single argument of typeEadds to the end, whereasaddwithintandEarguments inserts in the middle.public boolean equals(Object other): determine whether this vector is equal to another one (by comparing all the elements). Be sure to put an@Overrideannotation before it. The one annoying thing about this method is that it has to take anObjectinstead of aExtensibleArray<E>. To implement it, you should simply castotherto the typeExtensibleArray<E>. If anyone callsequalswith something other than aExtensibleArray, it will crash—but that’s OK since no one should ever do that. In fact, one could argue that it is better to have the program crash than for it to silently returnfalse, because callingequalson objects of two different types almost certainly signals a bug.
Part 2: Equality for Associations
In order to effectively look up an Association in a Dictionary, we will want to be able to compare two Associations, so we will also implement equals for them. However, we are going to do something a bit strange and just compare their keys, not their values. If we were just implementing a generic class for pairs, this would be the wrong thing to do. However, Associations are not just generic pairs: we are going to use them to store key-value associations, to implement things like dictionaries. In a key-value association, we always look things up by key, so it makes sense to only compare Associations by key.
- Add a method
public boolean equals(Object other)to theAssociationclass as well. As withExtensibleArray, you should just assume thatotheris anAssociationand cast it appropriately.
Part 3: A better dictionary
Finally, we will use the improved ExtensibleArray and Association classes to simplify the implementation of Dictionary.
First, modify the
putmethod so that it does not use any loops. It is possible to implement it in a concise, elegant way making use of some of the things you developed in parts 1 and 2. If you are unsure how to do this, then go back and think about parts 1 and 2 again.Now rewrite the
getmethod ofDictionaryto make use of our new tools. The new implementation ofgetshould also not have any loops. (Hint: try making anew Association(key, null).)
What to Hand In
You should turn in
ExtensibleArray.javaAssociation.javaDictionary.java
Grading
- To get a D, complete three of the methods in Part 1.
- To get a C, complete Part 1.
- To get a B, complete Part 2.
- To get an A, complete Part 3.