# Yhteystiedot ja osoitekirja 2/3 - Olioiden vertaileminen Kuten merkkijonoja käsiteltäessä olemme huomanneet, merkkijonojen vertailu `==`-vertailuoperaattorilla vertailee olioviittauksia eikä merkkijonojen sisältöä. Samalla tavoin käy vertailtaessa Contact-olioita. Merkkijonoille on toteutettu oma `equals`-metodinsa, jonka avulla pystytään vertailemaan kahden eri merkkijonon sisältöä. Tässä tehtävässä sinun tulee toteuttaa vastaavasti `Contact`-luokkaan `equals`-metodi, joka vertailee, ovatko kaksi `Contact`-oliota sisällöiltään samanlaiset. Lue sivu [Olioiden samankaltaisuus](https://ohjelmointi-19.mooc.fi/osa-6/3-olioiden-samankaltaisuus) saadaksesi lisätietoa olioiden vertailusta ja `equals`-metodin toteuttamisesta. ## ADD-KOMENTO Jatkokehitä myös `AddressBook`-osoitekirjan ominaisuutta yhteystietojen lisäämiseksi siten, että osoitekirjaan ei lisätä kahta sisällöiltään täysin samanlaista yhteystietoa: ``` > add Maija Meikäläinen, maija@example.com, +35850555556 Added Maija Meikäläinen (email: maija@example.com, phone: +35850555556) > add Maija Meikäläinen, maija@example.com, +35850555556 That contact already exists. ``` Jos käyttäjän syöttämä yhteystieto löytyy jo valmiiksi osoitekirjasta, sitä ei pidä lisätä, vaan ohjelman tulee tulostaa teksti `That contact already exists.` ## ESIMERKKI ``` This is an address book application. Available commands: list help add , , search exit > add Maija Meikäläinen, maija@example.com, +35850555556 Added Maija Meikäläinen (email: maija@example.com, phone: +35850555556) > add Matti Meikäläinen, matti@example.com, +35850555555 Added Matti Meikäläinen (email: matti@example.com, phone: +35850555555) > add Maija Meikäläinen, maija@example.com, +35850555556 That contact already exists. ... ``` **AddressBookApp.java** ``` import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class AddressBookApp { private static String welcomeText = "This is an address book application. Available commands:\n"; private static String commandMenu = " list\n" + " help\n" + " add , , \n" + " search \n" + " exit\n"; // Keep here instead of translating to a local variable private static String inputCLIPrefix = "> "; // Keep added addressBook values during application runtime private static AddressBook addressBook = new AddressBook(); public static void main(String[] args) { System.out.print(welcomeText + commandMenu); while (true) { runApp(); } } private static void runApp() { Scanner inputPrompt = new Scanner(System.in); Object[] getInput = parseInput(inputCLIPrefix, inputPrompt); String inputCmd = String.valueOf(getInput[0]); // TODO Avoid risk of ClassCastException List inputArgs = (ArrayList)getInput[1]; int argsCount = 3; switch(inputCmd) { case "list": System.out.println(addressBook.toString()); break; case "help": System.out.print(welcomeText + commandMenu); break; case "add": // TODO Should this be checked in AddressBook.add method instead? if (inputArgs.size() != argsCount) { System.err.printf("Invalid count of input arguments (expected %d).\n", argsCount); break; } String name = String.valueOf(inputArgs.get(0)); String email = String.valueOf(inputArgs.get(1)); String phone = String.valueOf(inputArgs.get(2)); Contact contact = new Contact(name, email, phone); // NOTE: Else condition not needed as 3 arguments is always passed to this object method call if(addressBook.add(contact)) { System.out.printf("Added %s\n", contact.toString()); } break; case "search": String searchTerm = String.valueOf(inputArgs.get(0)); Contact match = addressBook.search(searchTerm); if (match == null) { System.out.printf("%s does not match any contact.\n", searchTerm); } else { System.out.println(match.toString()); } break; case "exit": System.out.print("Bye!\n"); System.exit(0); default: System.err.println("Command not found."); //break; } } private static Object[] parseInput(String prefix, Scanner inputRaw) { System.out.print(prefix); String inputR = inputRaw.nextLine(); String command = inputR.split(" ")[0]; String[] theRest = inputR.split(","); theRest[0] = theRest[0].replaceAll("^\\s*" + command + "\\s*",""); List arguments = new ArrayList(); for (int i = 0; i < theRest.length; i++) { arguments.add(theRest[i].trim()); } Object[] parsedOutput = new Object[2]; parsedOutput[0] = command; parsedOutput[1] = arguments; return parsedOutput; } } ``` **AddressBook.java** ``` import java.util.ArrayList; import java.util.List; public class AddressBook { private List contacts; public AddressBook() { this.contacts = new ArrayList<>(); } public boolean add(Contact newContact) { // Create a temporary ArrayList, if we have contacts already // Get list of all contacts, put them into the new ArrayList contactsTemp // Loop through all contacts in contactsTemp // Check the current contact in contactsTemp against newContact if (this.contacts.size() > 0) { List contactsTemp = new ArrayList<>(this.contacts); for (Contact tempContact : contactsTemp) { if (tempContact.equals(newContact)) { System.out.println("That contact already exists."); return false; } } } this.contacts.add(newContact); return true; } public Contact search(String keyword) { for (Contact current : this.contacts) { String name = current.getName(); if (name != null && name.toLowerCase().contains(keyword.toLowerCase())) { return current; // palautetaan löytynyt arvo heti } } return null; // palautetaan null, jos ei löytynyt } @Override public String toString() { String returnString = ""; for (Contact contact : this.contacts) { returnString += contact + "\n"; } return returnString; } } ``` **Contact.java** ``` public class Contact { private String name; private String email; private String phone; // NOTE: This does not validate or check input String values // (Is name actually a name, email a valid email, and phone number an actual phone number?) public Contact(String name, String email, String phone) { this.name = name; this.email = email; this.phone = phone; } public String getName() { return this.name; } @Override public boolean equals(Object contact) { if (this == contact) { return true; } if (!(this instanceof Contact)) { return false; } Contact contactT = (Contact) contact; if (this.name.equals(contactT.name) && this.email.equals(contactT.email) && this.phone.equals(contactT.phone)) { return true; } return false; } public String toString() { // Haluttu muoto: "Maija Meikäläinen (email: foo@bar.fi, phone: 5555)" return this.name + " (email: " + this.email + ", phone: " + this.phone + ")"; } } ```