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\ address\ book.\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\ @return\ The\ number\ of\ entries.\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\ @return\ A\ sorted\ list\ of\ the\ details.\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,35 @@
|
||||
#BlueJ class context
|
||||
comment0.params=
|
||||
comment0.target=AddressBookTest()
|
||||
comment0.text=\n\ Set\ up\ the\ sample\ details.\n
|
||||
comment1.params=
|
||||
comment1.target=void\ setUp()
|
||||
comment1.text=\n\ Sets\ up\ the\ test\ fixture.\n\n\ Called\ before\ every\ test\ case\ method.\n
|
||||
comment10.params=
|
||||
comment10.target=void\ testAddDetailsError()
|
||||
comment10.text=\n\ Trigger\ an\ assertion\ error\ by\ adding\ revised\ details\ via\n\ addDetails\ rather\ than\ changeDetails.\n
|
||||
comment2.params=
|
||||
comment2.target=void\ tearDown()
|
||||
comment2.text=\n\ Tears\ down\ the\ test\ fixture.\n\n\ Called\ after\ every\ test\ case\ method.\n
|
||||
comment3.params=
|
||||
comment3.target=void\ testGetNumberOfEntries()
|
||||
comment3.text=\n\ Test\ that\ the\ count\ matches\ the\ number\ of\ sample\ entries.\n\ Then\ remove\ one\ and\ check\ for\ a\ reduced\ count.\n\ Then\ add\ one\ and\ check\ for\ an\ increased\ count.\n
|
||||
comment4.params=
|
||||
comment4.target=void\ testGetDetails()
|
||||
comment4.text=\n\ Check\ that\ the\ existing\ contact\ can\ be\ found,\ and\ that\ a\ non-existent\n\ one\ cannot\ be\ found.\n
|
||||
comment5.params=
|
||||
comment5.target=void\ testKeyInUse()
|
||||
comment5.text=\n\ Test\ that\ the\ name\ and\ phone\ numbers\ of\ an\ existing\ contact\n\ are\ registered\ as\ existing\ keys.\n
|
||||
comment6.params=
|
||||
comment6.target=void\ testAddDetails()
|
||||
comment6.text=\n\ Test\ that\ a\ further\ contact\ can\ be\ added.\n
|
||||
comment7.params=
|
||||
comment7.target=void\ testRemoveDetails()
|
||||
comment7.text=\n\ Test\ that\ we\ can\ add\ a\ further\ contact\ and\ then\ remove\ them.\n
|
||||
comment8.params=
|
||||
comment8.target=void\ testChangeDetails()
|
||||
comment8.text=\n\ Test\ that\ details\ of\ an\ existing\ contact\ can\ be\ changed.\n
|
||||
comment9.params=
|
||||
comment9.target=void\ testSearch()
|
||||
comment9.text=\n\ Test\ that\ a\ search\ for\ an\ existing\ contact\ finds\ one\ entry.\n\ Then\ test\ that\ a\ search\ for\ a\ non-existent\ contact\ fails\n\ to\ find\ any\ entries.\n\ Then\ add\ a\ new\ contact\ and\ test\ that\ a\ search\ finds\ them.\n
|
||||
numComments=11
|
@@ -0,0 +1,191 @@
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* An outline test class for AddressBook.
|
||||
* Not all methods are tested. Neither are those methods
|
||||
* that are tested tested thoroughly.
|
||||
*
|
||||
* @author David J. Barnes and Michael Kölling.
|
||||
* @version 2016.02.29
|
||||
*/
|
||||
public class AddressBookTest
|
||||
{
|
||||
// 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;
|
||||
// Revised details for an existing contact.
|
||||
private ContactDetails revisedDetails;
|
||||
|
||||
/**
|
||||
* Set up the sample details.
|
||||
*/
|
||||
public AddressBookTest()
|
||||
{
|
||||
// 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"),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the test fixture.
|
||||
*
|
||||
* Called before every test case method.
|
||||
*/
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
book = new AddressBook();
|
||||
for(ContactDetails details : sampleDetails) {
|
||||
book.addDetails(details);
|
||||
}
|
||||
// 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");
|
||||
// Change the address of an existing contact.
|
||||
revisedDetails = new ContactDetails(existingContact.getName(),
|
||||
existingContact.getPhone(),
|
||||
existingContact.getAddress() + "X");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the test fixture.
|
||||
*
|
||||
* Called after every test case method.
|
||||
*/
|
||||
@After
|
||||
public void tearDown()
|
||||
{
|
||||
book = null;
|
||||
existingContact = null;
|
||||
furtherContact = null;
|
||||
revisedDetails = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the count matches the number of sample entries.
|
||||
* Then remove one and check for a reduced count.
|
||||
* Then add one and check for an increased count.
|
||||
*/
|
||||
@Test
|
||||
public void testGetNumberOfEntries()
|
||||
{
|
||||
assertEquals(sampleDetails.length, book.getNumberOfEntries());
|
||||
book.removeDetails(existingContact.getName());
|
||||
assertEquals(sampleDetails.length - 1, book.getNumberOfEntries());
|
||||
book.addDetails(furtherContact);
|
||||
assertEquals(sampleDetails.length, book.getNumberOfEntries());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the existing contact can be found, and that a non-existent
|
||||
* one cannot be found.
|
||||
*/
|
||||
@Test
|
||||
public void testGetDetails()
|
||||
{
|
||||
assertEquals(existingContact, book.getDetails(existingContact.getName()));
|
||||
assertNull(book.getDetails(furtherContact.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the name and phone numbers of an existing contact
|
||||
* are registered as existing keys.
|
||||
*/
|
||||
@Test
|
||||
public void testKeyInUse()
|
||||
{
|
||||
assertEquals(true, book.keyInUse(existingContact.getName()));
|
||||
assertEquals(true, book.keyInUse(existingContact.getPhone()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a further contact can be added.
|
||||
*/
|
||||
@Test
|
||||
public void testAddDetails()
|
||||
{
|
||||
assertEquals(false, book.keyInUse("ian"));
|
||||
book.addDetails(furtherContact);
|
||||
assertEquals(true, book.keyInUse("ian"));
|
||||
assertEquals(sampleDetails.length + 1, book.getNumberOfEntries());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can add a further contact and then remove them.
|
||||
*/
|
||||
@Test
|
||||
public void testRemoveDetails()
|
||||
{
|
||||
book.addDetails(furtherContact);
|
||||
assertEquals(true, book.keyInUse("ian"));
|
||||
book.removeDetails("ian");
|
||||
assertEquals(false, book.keyInUse("ian"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that details of an existing contact can be changed.
|
||||
*/
|
||||
@Test
|
||||
public void testChangeDetails()
|
||||
{
|
||||
assertEquals(existingContact, book.getDetails(existingContact.getName()));
|
||||
book.changeDetails(existingContact.getName(), revisedDetails);
|
||||
assertEquals(revisedDetails, book.getDetails(revisedDetails.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a search for an existing contact finds one entry.
|
||||
* Then test that a search for a non-existent contact fails
|
||||
* to find any entries.
|
||||
* Then add a new contact and test that a search finds them.
|
||||
*/
|
||||
@Test
|
||||
public void testSearch()
|
||||
{
|
||||
assertEquals(book.search(existingContact.getName()).length, 1);
|
||||
assertEquals(book.search(furtherContact.getName()).length, 0);
|
||||
book.addDetails(furtherContact);
|
||||
assertEquals(book.search(furtherContact.getName()).length, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger an assertion error by adding revised details via
|
||||
* addDetails rather than changeDetails.
|
||||
*/
|
||||
@Test
|
||||
public void testAddDetailsError()
|
||||
{
|
||||
assertEquals(existingContact, book.getDetails(existingContact.getName()));
|
||||
book.addDetails(revisedDetails);
|
||||
assertEquals(existingContact, book.getDetails(existingContact.getName()));
|
||||
assertEquals(revisedDetails, book.getDetails(revisedDetails.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -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=
|
||||
comment5.target=java.lang.String\ toString()
|
||||
comment5.text=\n\ @return\ A\ multi-line\ string\ containing\ the\ name,\ phone,\ and\ address.\n
|
||||
comment6.params=otherDetails
|
||||
comment6.target=int\ compareTo(ContactDetails)
|
||||
comment6.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
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A multi-line string containing the name, phone, and address.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return name + "\n" + phone + "\n" + address;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,14 @@
|
||||
Project: address-book-junit
|
||||
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 JUnit framework for testing an address-book implementation.
|
||||
|
||||
How to start this project:
|
||||
Use AddressBookTest to test the methods of AddressBook.
|
@@ -0,0 +1,65 @@
|
||||
#BlueJ package file
|
||||
dependency1.from=AddressBookTest
|
||||
dependency1.to=ContactDetails
|
||||
dependency1.type=UsesDependency
|
||||
dependency2.from=AddressBook
|
||||
dependency2.to=ContactDetails
|
||||
dependency2.type=UsesDependency
|
||||
dependency3.from=AddressBookTest
|
||||
dependency3.to=AddressBook
|
||||
dependency3.type=UsesDependency
|
||||
objectbench.height=76
|
||||
objectbench.width=842
|
||||
package.editor.height=462
|
||||
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=536
|
||||
readme.editor.width=825
|
||||
readme.editor.x=42
|
||||
readme.editor.y=23
|
||||
target1.editor.height=734
|
||||
target1.editor.width=853
|
||||
target1.editor.x=97
|
||||
target1.editor.y=66
|
||||
target1.height=60
|
||||
target1.name=AddressBookTest
|
||||
target1.naviview.expanded=true
|
||||
target1.showInterface=false
|
||||
target1.type=UnitTestTargetJunit4
|
||||
target1.typeParameters=
|
||||
target1.width=150
|
||||
target1.x=150
|
||||
target1.y=110
|
||||
target2.association=AddressBookTest
|
||||
target2.editor.height=742
|
||||
target2.editor.width=934
|
||||
target2.editor.x=50
|
||||
target2.editor.y=58
|
||||
target2.height=60
|
||||
target2.name=AddressBook
|
||||
target2.naviview.expanded=true
|
||||
target2.showInterface=false
|
||||
target2.type=ClassTarget
|
||||
target2.typeParameters=
|
||||
target2.width=150
|
||||
target2.x=120
|
||||
target2.y=140
|
||||
target3.editor.height=725
|
||||
target3.editor.width=939
|
||||
target3.editor.x=50
|
||||
target3.editor.y=60
|
||||
target3.height=60
|
||||
target3.name=ContactDetails
|
||||
target3.naviview.expanded=true
|
||||
target3.showInterface=false
|
||||
target3.type=ClassTarget
|
||||
target3.typeParameters=
|
||||
target3.width=130
|
||||
target3.x=350
|
||||
target3.y=250
|
Reference in New Issue
Block a user