I'm trying to create a contact service to add/modify/delete contacts and I'm stuck on how to modify a contact. This is the Contact class that I'm starting with:
public class Contact {
private String contactId;
private String firstName;
private String phone;
public Contact (String contactId, String firstName, String phone) {
if (contactId == null || contactId.length() > 10) {
throw new IllegalArgumentException("invalid contact ID");
}
if (firstName == null || firstName.length() > 10) {
throw new IllegalArgumentException("invalid first name");
}
if (phone == null || phone.length() != 10) {
throw new IllegalArgumentException("invalid phone number");
}
this.contactId = contactId;
this.firstName = firstName;
this.phone = phone;
}
public String getContactId() {
return contactId;
}
public String getFirstName() {
return firstName;
}
public String getPhone() {
return phone;
}
}
In my contact service class, I have written the methods for creating and getting a contact
public class ContactService {
int Id = 000;
//create contactList array
private ArrayList<Contact> contactList = new ArrayList<>();
public Contact getContact(String ID) {
//iterates through contact list
Iterator<Contact> itr = contactList.iterator();
while (itr.hasNext()) {
Contact contact = itr.next();
if (contact.getContactId().equals(ID)) {
//returns contact object for matching ID
return contact;
}
}
return null;
}
//adds a contact to the contactList array
public Contact addContact(String firstName, String Phone) {
Id++; //increment ID to make a unique ID
//convert integer to string for ArrayList
String contactId = Integer.toString(Id);
//create contact object
Contact contact = new Contact(contactId, firstName, Phone);
//add contact to list
contactList.add(contact);
return contact;
}
For my updateContact() method, I want to call getContact() which should return a contact object but I'm not sure how to update the object from there. This is probably this closest I've come:
public void updateContact(String contactId, String firstName, String phone) {
getContact(contactId);
contact.setFirstName(firstName);
contact.setPhone(phone);
}
However, not only does this approach not work but it would require me to create setter methods. If I do that the new input does not go through the null and length checks contained in the Contact constructor.
Your update method does not work because you are calling getContact without storing return value of the method
public void updateContact(String contactId, String firstName, String phone) {
Contact contact = getContact(contactId);
contact.setFirstName(firstName);
contact.setPhone(phone);
}
For make sure your checks are called you can call setter methods in your constructor like this
public Contact(String contactId, String firstName, String phone) {
setFirstName(firstName);
setPhone(phone);
setContactId(contactId);
}
And check your values into setter methods
public void setFirstName(String firstName) {
if (firstName == null || firstName.length() > 10) {
throw new IllegalArgumentException("invalid first name");
}
this.firstName = firstName;
}
public void setPhone(String phone) {
if (phone == null || phone.length() != 10) {
throw new IllegalArgumentException("invalid phone number");
}
this.phone = phone;
}
public void setContactId(String contactId) {
if (contactId == null || contactId.length() > 10) {
throw new IllegalArgumentException("invalid contact ID");
}
this.contactId = contactId;
}
Furthermore, you can improve your performance using an HashMap instead of ArrayList, so that you don't need to iterate whole the list every time you need a contact.
private final Map<String, Contact> contactList = new HashMap<>();
public Contact getContact(String ID) {
return contactList.get(ID);
}
//adds a contact to the contactList array
public Contact addContact(String firstName, String Phone) {
Id++;
String contactId = Integer.toString(Id);
Contact contact = new Contact(contactId, firstName, Phone);
return contactList.put(contactId, contact);
}
As #Atryom noted, you can add the same null and length checks that you have in your constructor to your setter methods. There's no restriction specifying that your setters cannot have those checks.
Related
i dont know how to add an update firstName function with my code. i am fairly new.
public class Contact {
private final String contactID;
private String firstName;
private String lastName;
private String Number;
private String Address;
private static AtomicLong idGenerator = new AtomicLong();
//CONSTRUCTOR
/*
* The constructor takes first name, last name, phone number, and address as parameters.
* The first thing it does is generates a new ID for the contactID field.
*
* First name and last name are checked for null condition or blank fields. If either of
* those conditions exist, fill in the field with the phrase "NULL" so that something exists
* to protect data integrity while making it clear it is a placeholder.
* In both cases, if the first or last name is greater than 10 characters, truncate it
* so that only the first 10 characters are used.
*
* For the number field, if the phone number is not exactly 10 characters then fill it with
* the placeholder '5555555555'.
*
* Address is like first and last names. If it is blank or null, set it to "NULL".
* If it is more than 30 characters, truncate to the first 30 characters.
*/
public Contact(String firstName, String lastName, String number, String address) {
//CONTACTID
//Contact ID is generated when the constructor is called. It is set as a final variable and has
//no other getter or setter so there should be no way to change it.
//The idGenerator is static to prevent duplicates across all contacts.
this.contactID = String.valueOf(idGenerator.getAndIncrement());
//FIRSTNAME
if (firstName == null || firstName.isBlank()) {
this.firstName = "NULL";
//If first name is longer than 10 characters, just grab the first 10 characters
} else if(firstName.length() > 10) {
this.firstName = firstName.substring(0, 10);
} else {
this.firstName = firstName;
}
//LASTNAME
if (lastName == null || lastName.isBlank()) {
this.lastName = "NULL";
} else if(lastName.length() > 10) {
this.lastName = lastName.substring(0,10);
} else {
this.lastName = lastName;
}
//NUMBER
if (number == null || number.isBlank() || number.length() != 10) {
this.Number = "5555555555";
} else {
this.Number = number;
}
//ADDRESS
if (address == null || address.isBlank()) {
this.Address = "NULL";
} else if(address.length() > 30) {
this.Address = address.substring(0,30);
} else {
this.Address = address;
}
}
//GETTERS
public String getContactID() {
return contactID;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getNumber() {
return Number;
}
public String getAddress() {
return Address;
}
}
package ContactService;
import java.util.ArrayList;
public class ContactService {
//Start with an ArrayList of contacts to hold the list of contacts
ArrayList<Contact> contactList = new ArrayList<Contact>();
//Display the full list of contacts to the console for error checking.
public void displayContactList() {
for(int counter = 0; counter < contactList.size(); counter++) {
System.out.println("\t Contact ID: " + contactList.get(counter).getContactID());
System.out.println("\t First Name: " + contactList.get(counter).getFirstName());
System.out.println("\t Last Name: " + contactList.get(counter).getLastName());
System.out.println("\t Phone Number: " + contactList.get(counter).getNumber());
System.out.println("\t Address: " + contactList.get(counter).getAddress() + "\n");
}
}
//Adds a new contact using the Contact constructor, then assign the new contact to the list.
public void addContact(String firstName, String lastName, String number, String address) {
// Create the new contact
Contact contact = new Contact(firstName, lastName, number, address);
contactList.add(contact);
}
public void removeContact (String firstName, String lastName, String number, String address) {
Contact contact = new Contact (firstName, lastName, number, address);
contactList.remove(contact);
}
public void updateFirstName {
}
}
how do i get the updateFirstName function to work. i need to be able to update the first name within a contact, but i dont know if i need to create a new contact like what was done in the add and remove contact functions. ive tried contact.setfirstname = new firstName but that did not work and i am at a loss on what to do.
I have a customer, customers and main class. I have an ArrayList in the customers class to store each customer. I think I have successfully added customers. How do I display all the customers in the ArrayList and how would I remove a specific one? I am trying to create a method in the customer class and call on it in the main.
Customer Class:
import java.util.ArrayList;
import java.util.Scanner;
public class customer {
//create variables
private int Id;
private String firstName;
private String lastName;
public customer() {
}
//setters and getters
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) throws InputValidationException {
if (firstName.matches("\\p{Upper}(\\p{Lower}){2,20}")) {
} else {
throw new InputValidationException();
}
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) throws InputValidationException {
if (lastName.matches("\\p{Upper}(\\p{Lower}){2,20}")) {
} else {
throw new InputValidationException();
}
this.lastName = lastName;
}
//constructor
public customer(int Id, String firstName, String lastName) {
this.Id = Id;
this.firstName = firstName;
this.lastName = lastName;
}
//get user input
public void customerInfo() {
Scanner input = new Scanner(System.in);
{
while (true) {
//ask user for input and get input
System.out.println("Enter id (press 'q' to quit): ");
String temp = input.nextLine();
if (temp.equals("q")) break;
int id = Integer.parseInt(temp);
System.out.println("Enter first name:");
String firstName = input.nextLine();
System.out.println("Enter last name:");
String lastName = input.nextLine();
//add customer
customers.add(new customer(id, firstName, lastName));
}
}
}
public void displayCustomers() {
System.out.println("Customer List : ");
}
}
Customers Class:
import java.util.ArrayList;
//creates an array of the customers
public final class customers {
public static ArrayList<customer> customers;
public customers() {
customers = new ArrayList<customer>();
}
public static void add(customer customer) {
}
}
Main Class:
public class Main {
public static void main(String[] args) {
customer customerInfoObject = new customer();
customerInfoObject.customerInfo();
customer displayCustomersObject = new customer();
displayCustomersObject.displayCustomers();
}
}
To print the information of all customers of the list, use a loop.
There are different ways for the user to delete a customer. You could receive an integer from the user and delete the customer at the given index. You could also receive the customer-name and compare it in a loop to the names of the customers and delete the one with the received name.
Also, dont use empty brackets. Just put an ! in front of the if-condition to invert it
I need help creating a method to find an object in an array and making a loop to change the object.
public void changeABFF() {
System.out.println("Enter first and the last name of the best friend you would like to change: ");
String fname = keyboard.next();
String lname = keyboard.next();
BestFriends other = new BestFriends(fname,lname,"","");
boolean found = false;
for(int i=0;i<myBFFArray.length && found == false;i++) {
if(other.equals(myBFFs.get(i))) {
found = true;
System.out.println("Enter a First Name: ");
String fName = keyboard.next();
System.out.println("Enter a Last Name: ");
String lName = keyboard.next();
System.out.println("Enter a Nick Name: ");
String nName = keyboard.next();
System.out.println("Enter a phone number");
String cPhone = keyboard.next();
BestFriends tmp = myBFFs.get(i);
tmp.firstName = fName;
tmp.setLastname(lName);
tmp.setNickName(nName);
tmp.setCellPhone(cPhone);
}
}
}
So I'm changing from array list to array and changed the name to myBFFArray
My question, is how do I create a find method to match up user input to value in the array?
You can edit your BestFriends class to override equals and hashCode to compare two BestFriends objects
public class BestFriends {
private String firstName;
private String lastName;
private String nickName;
private String cellPhone;
public BestFriends(String firstName, String lastName, String nickName, String cellPhone) {
this.firstName = firstName;
this.lastName = lastName;
this.nickName = nickName;
this.cellPhone = cellPhone;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getCellPhone() {
return cellPhone;
}
public void setCellPhone(String cellPhone) {
this.cellPhone = cellPhone;
}
#Override
public int hashCode() {
return this.hashCode();
}
#Override
public boolean equals(Object obj) {
BestFriends bf = (BestFriends) obj;
return bf.getFirstName().equals(firstName) && bf.getLastName().equals(lastName) && bf.getNickName().equals(nickName) && bf.getCellPhone().equals(cellPhone);
}
After that when you iterate over the array
public BestFriends find(String firstName, String lastName, String nickName, String cellPhone) {
BestFriends bestFriends = new BestFriends(firstName, lastName, nickName, cellPhone);
for (BestFriends b: myBFFArray) {
if (b.equals(bestFriends)) {
return b;
}
}
}
What would be the best data structure to store phone book contacts, each consisting of first name, last name and phone number. The user must be able to search by each one of the fields.
There has been similar questions, but none of the answers were clear enough.
Create a POJO type, that stores first name, last name, and phone number (could make it mutable if needed).
class PhoneBookEntry {
public final String firstName;
public final String lastName;
public final String phoneNumber;
public Entry(String firstName, String lastName, String phoneNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
}
//... equals + hashcode implementation
}
You can create your phone book like this:
class PhoneBook {
private Map<String, Set<PhoneBookEntry>> firstNameMap;
private Map<String, Set<PhoneBookEntry>> lastNameMap;
private Map<String, Set<PhoneBookEntry>> phoneNumberMap;
public void add(PhoneBookEntry entry) {
Set<PhoneBookEntry> set
= firstNameMap.computeIfAbsent(entry.firstName, k -> new HashSet<>());
set.add(entry);
set = lastNameMap.computeIfAbsent(entry.lastName, k -> new HashSet<>());
set.add(entry);
set = phoneNumberMap.computeIfAbsent(entry.phoneNumber, k -> new HashSet<>());
set.add(entry);
}
public Set<PhoneBookEntry> getByFirstName(String firstName) {
return firstNameMap.get(firstName);
}
public Set<PhoneBookEntry> getByLastName(String lastName) {
return lastNameMap.get(lastName);
}
public Set<PhoneBookEntry> getByPhoneNumber(String phoneNumber) {
return phoneNumberMap.get(phoneNumber);
}
}
Using Maps allows for fast lookup.
As yitzih said, Multiple contacts can have the same first name, last name, or phone number. So a lookup by first name (for instance), will return a set of contacts.
Create a Contact object that stores the variables needed for each contact. Use an ArrayList to store them.
Without having more information about the contact there isn't really any way to use a HashTable, Map or Graph. There is no real key value pair for a HashTable unless you want to use a combination of first and last names, but you would need some way to handle conflicts (if 2 people have the exact same name.), or you would need to forbid having 2 people having the same Contact name (but why would you want to do that?)
Class Contact{
String forename;
String Surname;
String phoneNo;
public Contact(fName, sName, pNo){
forename = fName;
Surname = sName;
phoneNo = pNo;
}
public String getForename(){}
public String getSurname(){}
public String getPhoneNo(){}
}
in the class handling the search,
you declare an arrayList of type Contact, and when searching for a contact say John,
public Contact searchContact(String s){
for(int i = 0; i< ContactList.size(); i++){
if(ContactList.get(i).getForename().equals(s) ||
ContactList.get(i).getSurame().equals(s) ||
ContactList.get(i).getPhoneNo().equals(s)
){
return ContactList.get(i);
}
}
return null;
}
Kind of a vague question, but what the heck, maybe this'll chase away my post-lunch sleepies. I'm assuming a simple String representation of the phone number, but the best data object to store all the possible varieties of world phone numbers along with a method to intelligently search them (e.g. is "(123) 456-7891" the same as "1234567891"?) could be it's own question entirely.
Here a PhoneBook class stores all of the contacts. The methods searchFirst(), searchLast() and searchPhoneNumber() each return lists of matching contacts.
public class PhoneBook {
ArrayList<Contact> contacts;
public PhoneBook() {
contacts = new ArrayList<>();
}
public void addContact(Contact contact) {
contacts.add(contact);
}
public ArrayList<Contact> searchFirst(String first) {
ArrayList<Contact> foundContacts = new ArrayList<>();
for (Contact contact: contacts) {
if (contact.first.equals(first)) {
foundContacts.add(contact);
}
}
return foundContacts;
}
public ArrayList<Contact> searchLast(String last) {
ArrayList<Contact> foundContacts = new ArrayList<>();
for (Contact contact: contacts) {
if (contact.last.equals(last)) {
foundContacts.add(contact);
}
}
return foundContacts;
}
public ArrayList<Contact> searchPhoneNumber(String phoneNumber) {
ArrayList<Contact> foundContacts = new ArrayList<>();
for (Contact contact: contacts) {
if (contact.phoneNumber.equals(phoneNumber)) {
foundContacts.add(contact);
}
}
return foundContacts;
}
class Contact {
String first;
String last;
String phoneNumber;
public Contact(String first, String last, String phoneNumber) {
this.first = first;
this.last = last;
this.phoneNumber = phoneNumber;
}
}
}
I have two string
private StringProperties firstName;
private StringProperties lastName;
private StringProperties nickName;
the first and last name are picked by user, the nickName is a concatenation of first 3 character of first and lastname
How i can do that?
Actually i initialize it like that (this is the entire class).
public class Person {
private StringProperty firstName;
private StringProperty lastName;
private StringProperty nickName;
private ObservableList<Evento> eventi = FXCollections.observableArrayList();
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
if (firstName.length() > 2 && lastName.length() > 2)
this.nickName = new SimpleStringProperty(firstName.trim().substring(0,3).concat(lastName.trim().substring(0,3)));
else
this.nickName = new SimpleStringProperty("");
}
public ObservableList<Evento> getEventi() {
return eventi;
}
public String getFirstName() {
if(firstName == null) firstName = new SimpleStringProperty(this,"firstName");
return firstName.get();
}
public StringProperty firstNameProperty() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public String getLastName() {
if(lastName == null) lastName = new SimpleStringProperty(this, "lastName");
return lastName.get();
}
public StringProperty lastNameProperty() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public String getNickName() {
if(nickName == null) nickName = new SimpleStringProperty(this,"nickName");
return nickName.get();
}
public StringProperty nickNameProperty() {
return nickName;
}
#Override
public String toString() {
return getNickName() + "(" + getLastName() + " " + getFirstName() + ")";
}
}
but when i let the user change first or lastName, the nickName won't update.
You should use ReadOnlyStringProperty for the nickname:
private ReadOnlyStringWrapper nickName= new ReadOnlyStringWrapper();
...
public final String getNickName() {
return nickName.get();
}
public final ReadOnlyStringProperty nickNameProperty() {
return nickName.getReadOnlyProperty();
}
As for binding, you can use utility methods from Bindings class or implement your own binding for any other complicated cases. This example uses createStringBinding() method. It takes Callable functional interface, which will be used to calculate new value, and list of observable properties, which values will be observed for changes:
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
this.nickName.bind(Bindings.createStringBinding(()->{
if(this.firstName.get().length() > 2 && this.lastName.get().length() > 2) {
return this.firstName.get().substring(0,3).concat(this.lastName.get().trim().substring(0,3));
} else {
return "";
}
}, this.firstName, this.lastName));
}
You can use Bindings.format:
nickName.bind(Bindings.format("%.3s%.3s", firstName, lastName));
The 3 in %.3s is the maximum length of the string.
This won't do any trimming of the strings though, (you could do that before passing the strings to firstName and lastName).
It will also work on strings that are smaller than 3 characters. So, you can get nicknames like FoBar, FooB or Bar (if the first name is an empty string).