first commit
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
#BlueJ class context
|
||||
comment0.params=
|
||||
comment0.target=AddressBook()
|
||||
comment0.text=\n\ Perform\ any\ initialization\ for\ the\ address\ book.\n
|
||||
comment1.params=key
|
||||
comment1.target=ContactDetails\ getDetails(java.lang.String)
|
||||
comment1.text=\n\ Look\ up\ a\ name\ or\ phone\ number\ and\ return\ the\n\ corresponding\ contact\ details.\n\ @param\ key\ The\ name\ or\ number\ to\ be\ looked\ up.\n\ @return\ The\ details\ corresponding\ to\ the\ key.\n
|
||||
comment2.params=key
|
||||
comment2.target=boolean\ keyInUse(java.lang.String)
|
||||
comment2.text=\n\ Return\ whether\ or\ not\ the\ current\ key\ is\ in\ use.\n\ @param\ key\ The\ name\ or\ number\ to\ be\ looked\ up.\n\ @return\ true\ if\ the\ key\ is\ in\ use,\ false\ otherwise.\n
|
||||
comment3.params=details
|
||||
comment3.target=void\ addDetails(ContactDetails)
|
||||
comment3.text=\n\ Add\ a\ new\ set\ of\ details\ to\ the\ notebook.\n\ @param\ details\ The\ details\ to\ associate\ with\ the\ person.\n
|
||||
comment4.params=oldKey\ details
|
||||
comment4.target=void\ changeDetails(java.lang.String,\ ContactDetails)
|
||||
comment4.text=\n\ Change\ the\ details\ previously\ stored\ under\ the\ given\ key.\n\ @param\ oldKey\ One\ of\ the\ keys\ used\ to\ store\ the\ details.\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ This\ should\ be\ a\ key\ that\ is\ currently\ in\ use.\n\ @param\ details\ The\ replacement\ details.\ Must\ not\ be\ null.\n\ @throws\ IllegalArgumentException\ If\ either\ argument\ is\ null.\n
|
||||
comment5.params=keyPrefix
|
||||
comment5.target=ContactDetails[]\ search(java.lang.String)
|
||||
comment5.text=\n\ Search\ for\ all\ details\ stored\ under\ a\ key\ that\ starts\ with\n\ the\ given\ prefix.\n\ @param\ keyPrefix\ The\ key\ prefix\ to\ search\ on.\ This\ may\ be\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ of\ zero\ length,\ but\ must\ not\ be\ null.\n\ @return\ An\ array\ of\ those\ details\ that\ have\ been\ found.\n
|
||||
comment6.params=
|
||||
comment6.target=int\ getNumberOfEntries()
|
||||
comment6.text=\n\ @return\ The\ number\ of\ entries\ currently\ in\ the\n\ \ \ \ \ \ \ \ \ address\ book.\n
|
||||
comment7.params=key
|
||||
comment7.target=void\ removeDetails(java.lang.String)
|
||||
comment7.text=\n\ Remove\ the\ entry\ with\ the\ given\ key\ from\ the\ address\ book.\n\ The\ key\ should\ be\ one\ that\ is\ currently\ in\ use.\n\ @param\ key\ One\ of\ the\ keys\ of\ the\ entry\ to\ be\ removed.\n\ @throws\ IllegalArgumentException\ If\ the\ key\ is\ null.\n
|
||||
comment8.params=
|
||||
comment8.target=java.lang.String\ listDetails()
|
||||
comment8.text=\n\ @return\ All\ the\ contact\ details,\ sorted\ according\n\ to\ the\ sort\ order\ of\ the\ ContactDetails\ class.\n
|
||||
comment9.params=
|
||||
comment9.target=boolean\ consistentSize()
|
||||
comment9.text=\n\ Check\ that\ the\ numberOfEntries\ field\ is\ consistent\ with\n\ the\ number\ of\ entries\ actually\ stored\ in\ the\ address\ book.\n\ @return\ true\ if\ the\ field\ is\ consistent,\ false\ otherwise.\n
|
||||
numComments=10
|
@@ -0,0 +1,187 @@
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* A class to maintain an arbitrary number of contact details.
|
||||
* Details are indexed by both name and phone number.
|
||||
* This version uses assert statements to check internal
|
||||
* consistency.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class AddressBook
|
||||
{
|
||||
// Storage for an arbitrary number of details.
|
||||
private TreeMap<String, ContactDetails> book;
|
||||
private int numberOfEntries;
|
||||
|
||||
/**
|
||||
* Perform any initialization for the address book.
|
||||
*/
|
||||
public AddressBook()
|
||||
{
|
||||
book = new TreeMap<>();
|
||||
numberOfEntries = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up a name or phone number and return the
|
||||
* corresponding contact details.
|
||||
* @param key The name or number to be looked up.
|
||||
* @return The details corresponding to the key.
|
||||
*/
|
||||
public ContactDetails getDetails(String key)
|
||||
{
|
||||
return book.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the current key is in use.
|
||||
* @param key The name or number to be looked up.
|
||||
* @return true if the key is in use, false otherwise.
|
||||
*/
|
||||
public boolean keyInUse(String key)
|
||||
{
|
||||
return book.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new set of details to the address book.
|
||||
* @param details The details to associate with the person.
|
||||
*/
|
||||
public void addDetails(ContactDetails details)
|
||||
{
|
||||
if(details == null) {
|
||||
throw new IllegalArgumentException("Null details passed to addDetails.");
|
||||
}
|
||||
book.put(details.getName(), details);
|
||||
book.put(details.getPhone(), details);
|
||||
numberOfEntries++;
|
||||
assert consistentSize() : "Inconsistent book size in addDetails";
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the details previously stored under the given key.
|
||||
* @param oldKey One of the keys used to store the details.
|
||||
This should be a key that is currently in use.
|
||||
* @param details The replacement details. Must not be null.
|
||||
* @throws IllegalArgumentException If either argument is null.
|
||||
*/
|
||||
public void changeDetails(String oldKey,
|
||||
ContactDetails details)
|
||||
{
|
||||
if(details == null) {
|
||||
throw new IllegalArgumentException("Null details passed to changeDetails.");
|
||||
}
|
||||
if(oldKey == null){
|
||||
throw new IllegalArgumentException("Null key passed to changeDetails.");
|
||||
}
|
||||
if(keyInUse(oldKey)){
|
||||
removeDetails(oldKey);
|
||||
addDetails(details);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for all details stored under a key that starts with
|
||||
* the given prefix.
|
||||
* @param keyPrefix The key prefix to search on. This may be
|
||||
* of zero length, but must not be null.
|
||||
* @return An array of those details that have been found.
|
||||
*/
|
||||
public ContactDetails[] search(String keyPrefix)
|
||||
{
|
||||
// Build a list of the matches.
|
||||
List<ContactDetails> matches = new LinkedList<>();
|
||||
if(keyPrefix != null) {
|
||||
// Find keys that are equal-to or greater-than the prefix.
|
||||
SortedMap<String, ContactDetails> tail = book.tailMap(keyPrefix);
|
||||
Iterator<String> it = tail.keySet().iterator();
|
||||
// Stop when we find a mismatch.
|
||||
boolean endOfSearch = false;
|
||||
while(!endOfSearch && it.hasNext()) {
|
||||
String key = it.next();
|
||||
if(key.startsWith(keyPrefix)) {
|
||||
matches.add(book.get(key));
|
||||
}
|
||||
else {
|
||||
endOfSearch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ContactDetails[] results = new ContactDetails[matches.size()];
|
||||
matches.toArray(results);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of entries currently in the
|
||||
* address book.
|
||||
* @return The number of entries.
|
||||
*/
|
||||
public int getNumberOfEntries()
|
||||
{
|
||||
return numberOfEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the entry with the given key from the address book.
|
||||
* The key should be one that is currently in use.
|
||||
* @param key One of the keys of the entry to be removed.
|
||||
* @throws IllegalArgumentException If the key is null.
|
||||
*/
|
||||
public void removeDetails(String key)
|
||||
{
|
||||
if(key == null){
|
||||
throw new IllegalArgumentException("Null key passed to removeDetails.");
|
||||
}
|
||||
if(keyInUse(key)) {
|
||||
ContactDetails details = book.get(key);
|
||||
book.remove(details.getName());
|
||||
book.remove(details.getPhone());
|
||||
numberOfEntries--;
|
||||
}
|
||||
assert !keyInUse(key);
|
||||
assert consistentSize() : "Inconsistent book size in removeDetails";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the contact details, sorted according
|
||||
* to the sort order of the ContactDetails class.
|
||||
* @return A sorted list of the details.
|
||||
*/
|
||||
public String listDetails()
|
||||
{
|
||||
// Because each entry is stored under two keys, it is
|
||||
// necessary to build a set of the ContactDetails. This
|
||||
// eliminates duplicates.
|
||||
StringBuilder allEntries = new StringBuilder();
|
||||
Set<ContactDetails> sortedDetails = new TreeSet<>(book.values());
|
||||
for(ContactDetails details : sortedDetails) {
|
||||
allEntries.append(details).append("\n\n");
|
||||
}
|
||||
return allEntries.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the numberOfEntries field is consistent with
|
||||
* the number of entries actually stored in the address book.
|
||||
* @return true if the field is consistent, false otherwise.
|
||||
*/
|
||||
private boolean consistentSize()
|
||||
{
|
||||
Collection<ContactDetails> allEntries = book.values();
|
||||
// Eliminate duplicates as we are using multiple keys.
|
||||
Set<ContactDetails> uniqueEntries = new HashSet<>(allEntries);
|
||||
int actualCount = uniqueEntries.size();
|
||||
return numberOfEntries == actualCount;
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
#BlueJ class context
|
||||
comment0.params=
|
||||
comment0.target=AddressBookDemo()
|
||||
comment0.text=\n\ Setup\ some\ sample\ data.\n
|
||||
comment1.params=
|
||||
comment1.target=void\ setup()
|
||||
comment1.text=\n\ Setup\ a\ new\ AddressBook\ with\ sample\ data.\n
|
||||
comment2.params=
|
||||
comment2.target=void\ testAddition()
|
||||
comment2.text=\n\ A\ simple\ test\ of\ addDetails\ to\ see\ if\ an\ assertion\ fails.\n
|
||||
comment3.params=
|
||||
comment3.target=void\ testRemoval()
|
||||
comment3.text=\n\ A\ simple\ test\ of\ removeDetails\ to\ see\ if\ an\ assertion\ fails.\n
|
||||
comment4.params=
|
||||
comment4.target=void\ testChange()
|
||||
comment4.text=\n\ A\ simple\ test\ of\ changeDetails\ to\ see\ if\ an\ assertion\ fails.\n
|
||||
comment5.params=
|
||||
comment5.target=void\ testForAdditionError()
|
||||
comment5.text=\n\ Add\ for\ a\ second\ time\ an\ entry\ with\ duplicate\ name\n\ and\ phone\ details.\n\ This\ should\ trigger\ an\ AssertionError.\n
|
||||
comment6.params=
|
||||
comment6.target=AddressBook\ getBook()
|
||||
comment6.text=\n\ @return\ The\ sample\ address\ book.\n
|
||||
comment7.params=
|
||||
comment7.target=ContactDetails\ getExistingContact()
|
||||
comment7.text=\n\ @return\ The\ details\ of\ a\ contact\ who\ is\ originally\ in\n\ \ \ \ \ \ \ \ \ the\ address\ book.\n
|
||||
comment8.params=
|
||||
comment8.target=ContactDetails\ getFurtherContact()
|
||||
comment8.text=\n\ @return\ The\ details\ of\ a\ further\ contact,\ not\ originally\n\ \ \ \ \ \ \ \ \ in\ the\ address\ book.\n
|
||||
comment9.params=
|
||||
comment9.target=ContactDetails\ createRevisedDetails()
|
||||
comment9.text=\n\ Create\ a\ contact\ based\ on\ an\ existing\ contact.\n
|
||||
numComments=10
|
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* A demo class for AddressBook.
|
||||
* Some basic test methods are included. The purpose of these
|
||||
* is to see whether assertion errors are triggered for some
|
||||
* of the basic operations on an address book.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class AddressBookDemo
|
||||
{
|
||||
// Sample contact details.
|
||||
private ContactDetails[] sampleDetails;
|
||||
// An address book containing sample data.
|
||||
private AddressBook book;
|
||||
// A copy of one of the contact's details.
|
||||
private ContactDetails existingContact;
|
||||
// An additional contact.
|
||||
private ContactDetails furtherContact;
|
||||
|
||||
/**
|
||||
* Setup some sample data.
|
||||
*/
|
||||
public AddressBookDemo()
|
||||
{
|
||||
// A sample of contact details to be stored in the book.
|
||||
sampleDetails = new ContactDetails[] {
|
||||
new ContactDetails("david", "08459 100000", "address 1"),
|
||||
new ContactDetails("michael", "08459 200000", "address 2"),
|
||||
new ContactDetails("john", "08459 300000", "address 3"),
|
||||
new ContactDetails("helen", "08459 400000", "address 4"),
|
||||
new ContactDetails("emma", "08459 500000", "address 5"),
|
||||
new ContactDetails("kate", "08459 600000", "address 6"),
|
||||
new ContactDetails("chris", "08459 700000", "address 7"),
|
||||
new ContactDetails("ruth", "08459 800000", "address 8"),
|
||||
};
|
||||
book = new AddressBook();
|
||||
// Take a copy of the details of one of the contacts.
|
||||
ContactDetails first = sampleDetails[0];
|
||||
existingContact = new ContactDetails(first.getName(), first.getPhone(),
|
||||
first.getAddress());
|
||||
// Create a further contact who is not yet in the address book.
|
||||
furtherContact = new ContactDetails("ian", "08459 900000", "address 9");
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a new AddressBook with sample data.
|
||||
*/
|
||||
public void setup()
|
||||
{
|
||||
book = new AddressBook();
|
||||
for(ContactDetails details : sampleDetails) {
|
||||
book.addDetails(details);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple test of addDetails to see if an assertion fails.
|
||||
*/
|
||||
public void testAddition()
|
||||
{
|
||||
setup();
|
||||
book.addDetails(furtherContact);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple test of removeDetails to see if an assertion fails.
|
||||
*/
|
||||
public void testRemoval()
|
||||
{
|
||||
setup();
|
||||
book.removeDetails(existingContact.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple test of changeDetails to see if an assertion fails.
|
||||
*/
|
||||
public void testChange()
|
||||
{
|
||||
setup();
|
||||
ContactDetails revisedDetails = createRevisedDetails();
|
||||
|
||||
book.changeDetails(existingContact.getName(),
|
||||
revisedDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add for a second time an entry with duplicate name
|
||||
* and phone details.
|
||||
* This should trigger an AssertionError.
|
||||
*/
|
||||
public void testForAdditionError()
|
||||
{
|
||||
setup();
|
||||
book.addDetails(createRevisedDetails());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The sample address book.
|
||||
*/
|
||||
public AddressBook getBook()
|
||||
{
|
||||
return book;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The details of a contact who is originally in
|
||||
* the address book.
|
||||
*/
|
||||
public ContactDetails getExistingContact()
|
||||
{
|
||||
return existingContact;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The details of a further contact, not originally
|
||||
* in the address book.
|
||||
*/
|
||||
public ContactDetails getFurtherContact()
|
||||
{
|
||||
return furtherContact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a contact based on an existing contact.
|
||||
*/
|
||||
private ContactDetails createRevisedDetails()
|
||||
{
|
||||
return new ContactDetails(existingContact.getName(),
|
||||
existingContact.getPhone(),
|
||||
existingContact.getAddress() + "X");
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
#BlueJ class context
|
||||
comment0.params=name\ phone\ address
|
||||
comment0.target=ContactDetails(java.lang.String,\ java.lang.String,\ java.lang.String)
|
||||
comment0.text=\n\ Set\ up\ the\ contact\ details.\ All\ details\ are\ trimmed\ to\ remove\n\ trailing\ white\ space.\n\ @param\ name\ The\ name.\n\ @param\ phone\ The\ phone\ number.\n\ @param\ address\ The\ address.\n\ @throws\ IllegalStateException\ If\ both\ name\ and\ phone\ are\ blank.\n
|
||||
comment1.params=
|
||||
comment1.target=java.lang.String\ getName()
|
||||
comment1.text=\n\ @return\ The\ name.\n
|
||||
comment2.params=
|
||||
comment2.target=java.lang.String\ getPhone()
|
||||
comment2.text=\n\ @return\ The\ telephone\ number.\n
|
||||
comment3.params=
|
||||
comment3.target=java.lang.String\ getAddress()
|
||||
comment3.text=\n\ @return\ The\ address.\n
|
||||
comment4.params=other
|
||||
comment4.target=boolean\ equals(java.lang.Object)
|
||||
comment4.text=\n\ Test\ for\ content\ equality\ between\ two\ objects.\n\ @param\ other\ The\ object\ to\ compare\ to\ this\ one.\n\ @return\ true\ if\ the\ argument\ object\ is\ a\ set\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ of\ contact\ details\ with\ matching\ attributes.\n
|
||||
comment5.params=otherDetails
|
||||
comment5.target=int\ compareTo(ContactDetails)
|
||||
comment5.text=\n\ Compare\ these\ details\ against\ another\ set,\ for\ the\ purpose\n\ of\ sorting.\ The\ fields\ are\ sorted\ by\ name,\ phone,\ and\ address.\n\ @param\ otherDetails\ The\ details\ to\ be\ compared\ against.\n\ @return\ a\ negative\ integer\ if\ this\ comes\ before\ the\ parameter,\n\ \ \ \ \ \ \ \ \ zero\ if\ they\ are\ equal\ and\ a\ positive\ integer\ if\ this\n\ \ \ \ \ \ \ \ \ comes\ after\ the\ second.\n
|
||||
comment6.params=
|
||||
comment6.target=java.lang.String\ toString()
|
||||
comment6.text=\n\ @return\ A\ multi-line\ string\ containing\ the\ name,\ phone,\ and\ address.\n
|
||||
comment7.params=
|
||||
comment7.target=int\ hashCode()
|
||||
comment7.text=\n\ Compute\ a\ hashcode\ using\ the\ rules\ to\ be\ found\ in\n\ "Effective\ Java",\ by\ Joshua\ Bloch.\n\ @return\ A\ hashcode\ for\ ContactDetails.\n
|
||||
numComments=8
|
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Name, address and telephone number details.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class ContactDetails implements Comparable<ContactDetails>
|
||||
{
|
||||
private String name;
|
||||
private String phone;
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* Set up the contact details. All details are trimmed to remove
|
||||
* trailing white space.
|
||||
* @param name The name.
|
||||
* @param phone The phone number.
|
||||
* @param address The address.
|
||||
* @throws IllegalStateException If both name and phone are blank.
|
||||
*/
|
||||
public ContactDetails(String name, String phone, String address)
|
||||
{
|
||||
// Use blank strings if any of the arguments is null.
|
||||
if(name == null) {
|
||||
name = "";
|
||||
}
|
||||
if(phone == null) {
|
||||
phone = "";
|
||||
}
|
||||
if(address == null) {
|
||||
address = "";
|
||||
}
|
||||
|
||||
this.name = name.trim();
|
||||
this.phone = phone.trim();
|
||||
this.address = address.trim();
|
||||
|
||||
if(this.name.isEmpty() && this.phone.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"Either the name or phone must not be blank.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The telephone number.
|
||||
*/
|
||||
public String getPhone()
|
||||
{
|
||||
return phone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The address.
|
||||
*/
|
||||
public String getAddress()
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for content equality between two objects.
|
||||
* @param other The object to compare to this one.
|
||||
* @return true if the argument object is a set
|
||||
* of contact details with matching attributes.
|
||||
*/
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if(other instanceof ContactDetails) {
|
||||
ContactDetails otherDetails = (ContactDetails) other;
|
||||
return name.equals(otherDetails.getName()) &&
|
||||
phone.equals(otherDetails.getPhone()) &&
|
||||
address.equals(otherDetails.getAddress());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare these details against another set, for the purpose
|
||||
* of sorting. The fields are sorted by name, phone, and address.
|
||||
* @param otherDetails The details to be compared against.
|
||||
* @return a negative integer if this comes before the parameter,
|
||||
* zero if they are equal and a positive integer if this
|
||||
* comes after the second.
|
||||
*/
|
||||
public int compareTo(ContactDetails otherDetails)
|
||||
{
|
||||
int comparison = name.compareTo(otherDetails.getName());
|
||||
if(comparison != 0){
|
||||
return comparison;
|
||||
}
|
||||
comparison = phone.compareTo(otherDetails.getPhone());
|
||||
if(comparison != 0){
|
||||
return comparison;
|
||||
}
|
||||
return address.compareTo(otherDetails.getAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A multi-line string containing the name, phone, and address.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return name + "\n" + phone + "\n" + address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a hashcode using the rules to be found in
|
||||
* "Effective Java", by Joshua Bloch.
|
||||
* @return A hashcode for ContactDetails.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
int code = 17;
|
||||
code = 37 * code + name.hashCode();
|
||||
code = 37 * code + phone.hashCode();
|
||||
code = 37 * code + address.hashCode();
|
||||
return code;
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
Project: address-book-assert
|
||||
Authors: David J. Barnes and Michael Kölling
|
||||
|
||||
This project is part of the material for chapter 12 of the book
|
||||
|
||||
Objects First with Java - A Practical Introduction using BlueJ
|
||||
Sixth edition
|
||||
David J. Barnes and Michael Kölling
|
||||
Pearson Education, 2016
|
||||
|
||||
A simple address-book implementation.
|
||||
|
||||
How to start this project:
|
||||
Create an AddressBookDemo object and then use its
|
||||
test methods to check for assertion errors.
|
@@ -0,0 +1,64 @@
|
||||
#BlueJ package file
|
||||
dependency1.from=AddressBook
|
||||
dependency1.to=ContactDetails
|
||||
dependency1.type=UsesDependency
|
||||
dependency2.from=AddressBookDemo
|
||||
dependency2.to=ContactDetails
|
||||
dependency2.type=UsesDependency
|
||||
dependency3.from=AddressBookDemo
|
||||
dependency3.to=AddressBook
|
||||
dependency3.type=UsesDependency
|
||||
objectbench.height=76
|
||||
objectbench.width=842
|
||||
package.editor.height=458
|
||||
package.editor.width=734
|
||||
package.editor.x=70
|
||||
package.editor.y=80
|
||||
package.numDependencies=3
|
||||
package.numTargets=3
|
||||
package.showExtends=true
|
||||
package.showUses=true
|
||||
project.charset=UTF-8
|
||||
readme.editor.height=559
|
||||
readme.editor.width=784
|
||||
readme.editor.x=53
|
||||
readme.editor.y=23
|
||||
target1.editor.height=742
|
||||
target1.editor.width=883
|
||||
target1.editor.x=145
|
||||
target1.editor.y=58
|
||||
target1.height=60
|
||||
target1.name=AddressBook
|
||||
target1.naviview.expanded=true
|
||||
target1.showInterface=false
|
||||
target1.type=ClassTarget
|
||||
target1.typeParameters=
|
||||
target1.width=140
|
||||
target1.x=240
|
||||
target1.y=160
|
||||
target2.editor.height=735
|
||||
target2.editor.width=879
|
||||
target2.editor.x=53
|
||||
target2.editor.y=60
|
||||
target2.height=60
|
||||
target2.name=ContactDetails
|
||||
target2.naviview.expanded=true
|
||||
target2.showInterface=false
|
||||
target2.type=ClassTarget
|
||||
target2.typeParameters=
|
||||
target2.width=130
|
||||
target2.x=400
|
||||
target2.y=260
|
||||
target3.editor.height=743
|
||||
target3.editor.width=853
|
||||
target3.editor.x=50
|
||||
target3.editor.y=57
|
||||
target3.height=60
|
||||
target3.name=AddressBookDemo
|
||||
target3.naviview.expanded=true
|
||||
target3.showInterface=false
|
||||
target3.type=ClassTarget
|
||||
target3.typeParameters=
|
||||
target3.width=150
|
||||
target3.x=90
|
||||
target3.y=60
|
Reference in New Issue
Block a user