My assignment is to create a basic contact list program that lets the user
Enter a new contact,
Print the contact list,
Retrieve a contact by last name,
Email, and
Retrieve contacts in a specific zip code.
My idea is to create 3 classes:
Main(), Contact(), and ContactList(). I would proceed by having the main() handle the menu and the logic. Contact() would be a class object I would instantiate for each contact. ContactList() would be the class that defines an array of Contact objects, and define methods to enter and retrieve information.
The problem is I'm not sure how to go about this. Would my approach stated above work? I'm not quite sure how to go about this and any suggestions and ideas would be greatly appreciated.
Here are my thoughts on this, with some pseudocode to help.
The following class is a basic implementation for what a contact should consist of based on the requirements. I opted for using String fields since this is just a homework problem and requires no extra engineering.
public class Contact
{
private String firstName;
private String lastName;
private String email;
private String zipCode;
public Contact()
{
//initialize all variables to empty string
}
public Contact(String firstName,String lastName, String email, String zipCode)
{
//Use this.variableName to set values
}
//getters/setters
}
public class Assignment1 //Or whatever assignment number this is == Main()
{
List<Contact> contacts;
public static void main(String[] args)
{
//Retrieve user input
// Execute rest of program
}
void printContacts(List<Contact> contacts)
{
foreach(Contact in contacts)
{
print(Contact.toString());
}
}
Contact getContactByLastName(String lastName)
{
foreach(Contact in contacts)
{
if(Contact.lastName == lastName)
return Contact;
}
else
Contact does not exist
}
void addContact(Contact contact)
{
contacts.add(contact);
}
}
I would have the ContactList only habe the required methods that make sense:
interface ContactList {
void add(Contact)
List<Contact> getList()
Contact getContactByLastName(String)
Contact getContactByEmail(String)
Contact getContactByZipCode(String)
}
then you can implement that interface with, lets say, an ContactArrayList that uses an ArrayList<Contact> for the backing object.
I would have your ContactList implement a generic list
public class ContactdList implements List<Contact>
but yeah, that sounds like it would work. I assume this is for a class, you don't want to get too far afield of what the the teacher has asked for/taught.
Related
Guys this is my membership class so far, i am struggling to create a method that finds the full members details that i have given just using a uniqueId finder. Please help.
public class Membership {
private String FirstName;
private String LastName;
private int memberId;
private String listOfMembers;
private int uniqueId;
private long phoneNumber;
public Membership(String FirstName, String LastName, int uniqueId,
long phoneNumber)
{
this.uniqueId = uniqueId;
this.FirstName = FirstName;
this.LastName = LastName;
this.phoneNumber = phoneNumber;
}
public String getMember()
{
return FirstName + LastName;
}
public String getlistOfMembers()
{
return (FirstName + LastName);
}
public int getId()
{
return uniqueId;
}
public void MemberId (int Id)
{
System.out.println("Id" + Id);
}
public String getMemberDetails ()
{
System.out.println("Member Id: " + uniqueId);
System.out.println("first name: " + FirstName);
System.out.println("LastName: " + LastName);
System.out.println("Member phone number: " + phoneNumber);
return listOfMembers;
}
}
This is what i have done so far.
Issues:
You've got user interface code where it doesn't belong. I would remove all System.out.println statements from this class and instead leave it in a UI class or main method (if very simple).
In particular, getter methods should return field values, and should not have System.out.println statements
I'm not sure why this class has a listOfMembers field, or why it's just a String. You look to be trying to combine Member and Membership together in one single class -- Don't do this.
I'd name this class Member since it holds information for just a single Member.
If I needed a Membership class, it would instead hold an ArrayList<Member>
And it would have a public Member getMember(int id) method that would return the item in the list above that shares the id passed into the method. A simple for loop that iterated through the list, comparing id's would suffice.
To add on Hovercraft's answer with an example.
You have your class handling all the members, very basic implementation of it.
public class Membership {
private final Map<Integer, Member> members = new HashMap<>();
public void addMember (Integer uniqueId, Member member) {
members.put (uniqueId, member);
}
public void getMember (Integer uniqueId) {
return members.get (uniqueId);
}
...
}
Then you have the Members themselves like this, more fields can be added as you want them.
public class Member {
private String firstName;
private String lastName;
public Member (String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName () {
return firstName;
}
...
}
This is a very basic, but strong, feature in OOP to use.
Again see Hovercraft's answer as it provides all the details. If they were to edit/remove I will update this one.
Map vs List
One minor thing is I'd vote against using an ArrayList<E> to store the Members. If you add to the implementation that you can remove users the uniqueId will shift from user to user. Instead I would be for making sure that you are not adding to an existing user.
If you want to keep it simple and just get going, an ArrayList<E> works, do know the problem you might get in the feature, an uniqueId is not necessarily tied to a Member.
"I am quite new to java and have never come across "map" can you please explain what it is?"
"An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value." - From: Documentation.
Instead of working with direct indexes as you do in an Array:
arr[5]; // here you get the value at index position 5.
Or like a List:
list.get(5); // here you get the fifth element, it can be stored (almost) anywhere in the memory, before or after 4, doesn't matter, as 4 knows where 5 is.
And for a Map:
map.get(5); // you get the object stored at 5, there might not be a 3 or 4 in the Map. You can store any Objects as anything. A String is another example of a common key.
I would suggest to use Map and use id as key of Map and store object of Membership as Value,thereby easy to retrieve and store also.
Something similar to this,
Map<Integer,Membership> map = new HashMap<Integer,Membership>();
Membership m = new Membership("First", "LastName", 1,1234567890);
map.put(m.getId(), m);
To get member by id,
System.out.println(map.get(id).getMemberDetails());
I'm trying to do something pretty simple but I can't seem to get it to work. I'm trying to iterate through an ArrayList but my for loop is always returning the same value when I output the results to the terminal.
Here is the code:
import java.util.*;
public class Contact{
public static ArrayList<Contact> contacts = new ArrayList<Contact>();
public static String name;
public static String phoneNumber;
public static String email;
private static int idCounter = 0;
private final int contactID;
public static void main(String[] args){
Contact bob = new Contact("bob","8493483943","jo#g.com");
Contact joe = new Contact("joe","940389439","something#g.com");
ArrayList<Contact> contacts = new ArrayList<Contact>();
contacts.add(bob);
contacts.add(joe);
for (Contact person : contacts) {
System.out.println(person.idCounter);
System.out.println(person.name);
System.out.println(person.phoneNumber);
System.out.println(person.email);
System.out.println();
}
}
public Contact(String name,String phoneNumber,String email){
this.contactID = idCounter++;
this.name = name;
this.phoneNumber = phoneNumber;
this.email = email;
}
}
The above code always returns this when I run the code:
2
joe
940389439
something#g.com
2
joe
940389439
something#g.com
It returns the same information even though I've added 2 different objects into the ArrayList.
When I do this inside the for loop:
System.out.println(person);
It returns a Contact object with different id's.
I'm a little confused as to why this is happening as I'm assuming I'm not referencing the same variable or object here, or that I'm doing something wrong in my loop.
If anyone could help me explain what's going on that'd be great, thanks!
your attributes are static: name, phoneNumber and email. Remove static keyword [static keyword make classlevel attributes] :)
All your class variables are static. This means they will be overwritten ones you create the second object.
I am coding in blueJ. My objectives are this: 1)Write a User class
A User:
has a username e.g 'fj3'
has a userType which can be: 'user', 'editor' or 'admin'
has a name e.g 'Francis'
has a constructor which takes the username, userType and name as parameters
has a getUsername() method
has a getUserType() method
has a getName() method
has a setUserType() method which takes one of the user types as a parameter
2)Write a UserGroup class
The UserGroup class must have an ArrayList of Users.
Write a constructor for the UserGroup class. It should instantiate the ArrayList.
In UserGroup write a method called .addSampleData() which creates 10 Users and using the ArrayList's add() method put the 10 new User objects into the ArrayList.
In UserGroup write a getUser method which takes an int as a parameter and returns the User in that slot of the ArrayList.
In UserGroup write a printUsernames() method in UserGroup:
Using an enhanced for loop (see above), loop through the ArrayList and print the username and userType of each user in the ArrayList.
What I have so far is:
package user;
public class User{
public enum UserType{
ADMIN, EDITOR, USER;
}
private String id;
private UserType userPermissions;
private String actualName;
public User(String username, UserType userType, String name){
id = username;
userPermissions = userType;
actualName= name;
}
public String getUsername(){
return id;
}
public UserType getUserType(){
return userPermissions;
}
public String getName(){
return actualName;
}
public void setUserType(UserType input){
userPermissions = input;
}
}
And my UserGroup class:
package user;
import java.util.*;
import user.User.UserType;
public class UserGroup{
private ArrayList<User> people;
public UserGroup(){
people = new Arraylist<User>();
}
public static void addSampleData(String username, UserType userType, String name){
people.add(new User(username, userType,name));
}
public User get(int){
return User;
}
public void printUsernames(){
for (User user: groupArray){
System.out.printf("%s %s\n", user.getUsername(), user.getuserType);
}
}
}
This is obviously far from being complete but I am completely stuck. My first problem is that I am unsure how to write the get method for this. Please help me with this!! I think my User class is fine but my UserGroup class is nowhere near completing all the objectives and I don't know how to do them!!
Looks good so far, some corrections:
The addSampleData()method should not be static, as it uses a non-static member of the class. The request also states it to add the sample data itself.
The getUser() is pretty straight forward then.
The printUsernames()method uses an unknown member.
public void addSampleData() {
people.add(new User("pe3", UserType.ADMIN,"Peter"));
people.add(new User("u987", UserType.EDITOR,"Udo"));
people.add(new User("frank123", UserType.USER,"Frank"));
// repeat ...
}
public User getUser(int idx) {
return people.get(idx);
}
public void printUsernames(){
for (User user: people){
System.out.printf("%s %s\n", user.getUsername(), user.getuserType);
}
}
In a main method then:
UserGroup grp = new UserGroup();
grp.addSampleData();
grp.printUsernames();
User u1 = grp.getUser(0);
A school assignment (in beginner Java) is asking me to create a small contact manager program, which I'm having trouble with.
It asks us to create a few classes - Address, PhoneNumber, Contact, and ContactManager.
In ContactManager, we're asked to create a method called addContact() which will add a brand new unique contact to an object array within ContactManager.
However I cannot figure out how to make this method do what I want it to do since each time it creates a new Contact, it always has the same name. How do I make the object it creates have a unique name (i.e. Contact001, Contact002 etc) each time?
Also, how do I feed through all the relevant information it needs to create it, assuming I can enter all the data in instance variables to test it?
This is my code class:
public class Contact {
//Contact Instance Variables
private String lastName;
private String firstName;
private String middleName;
private Address completeAddress[];
private PhoneNumber phoneNumer[];
private SocialNetworkAccount socialNetworkInfo[];
public Contact(String lastName, String firstName, String middleName,
Address[] completeAddress, PhoneNumber[] phoneNumer,
SocialNetworkAccount[] socialNetworkInfo) {
this.lastName = lastName;
this.firstName = firstName;
this.middleName = middleName;
this.completeAddress = completeAddress;
this.phoneNumer = phoneNumer;
this.socialNetworkInfo = socialNetworkInfo;
}
"private List contacts;" is a declaration of an instance variable called contacts.
The variable's type is a List, which is a specific kind of Collection object found in the java.util package.
List<Contact> is a way of stating to the compiler that this list contains only Contact objects. See "Generics" in the java tutorial.
In your ContactManager class, define these
private List<Contact> contacts;
contacts = new ArrayList<Contact>(); //you should put this in ContactManager constructor
public void addContact(Contact contact) {
contacts.add(contact);
}
When you want to add a new contact
//just supply different names, etc. load the information from a file
contactManager.addContact(new Contact(name,surname,....));
or...
To add a couple of placeholder contacts...
int NUM_OF_CONTACTS = 2; //how many contacts to create
for(int i = 0; i < NUM_OF_CONTACTS; ++i) {
contactManager.addContact(new Contact(("Contact" + i),"Placeholder Surname",..);
}
I am asking myself how to design an object-oriented address book in Java.
Let's say a contact can have several contact details, like addresses, phone numbers and e-mail addresses.
One way to implement this would be to give every contact an ArrayList for every type. But there must be a better and more object-oriented solution. What is it?
The most OOP suggestion I can give you is to create a class for every item/piece of information. For example:
public abstract class ContactInfo { /* ... */ }
public class Address extends ContactInfo { /* ... */ }
public class PhoneNumber extends ContactInfo { /* ... */ }
public class EmailAddress extends ContactInfo { /* ... */ }
public class Contact {
private String name;
private Set<ContactInfo> info;
// ...
}
and finally,
public class AddressBook {
List<Contact> contacts;
// ...
}
This may or may not be overkill for your specific case, but as a thought experiment, it's the way to go. It obviously takes care of the literal part of OOP — using objects — but also lays groundwork for encapsulation, abstraction and inheritance, which are closely related principles.
You're on the right track. The only thing I would do differently would be to use a List interface instead of an ArrayList collection to reference the contacts' attribute collections. This is advice based on the code-to-interfaces rule-of-thumb as described in this article and many others.
I don't think that's particularly un-object oriented. If your domain is such that a Person can have zero or more EmailAddresses, then you've almost exactly described the situation to use a list.
The only alternative approach I can think of would be to have fields such as
WorkEmail
PersonalEmail
OtherEmail1
OtherEmail2
OtherEmail3
but in my opinion that's worse, because:
You simply cannot support more than five email addresses (well, you could add more fields, but that increases the pain of the latter points and still imposes some finite limit.)
You're implying some extra semantics than may be present (what if the same address is used for work and personal? What if neither applies, can you just fill the Other ones? What if you don't know the purpose?)
You now have to test each field manually to see which is null, which is going to involve a non-trivial amount of duplication in Java. You can't use nice features like the enhanced-for loop to apply the same block to every email address, and you can't trivially count how many addresses there are
The list of properties that a Person has is now much less clean. I suppose you could package these properties into an EmailContactDetails class or something, but now you've got an extra level of indirection (more conceptual complexity) for no real gain.
So, if a person has a possibly-empty, unbounded list of email addresses, what's wrong with representing that as a list?
You can also use a Map, and then get specific values e.g. via myMap.get("emailAdress1") or iterate over the whole map like you would do with a list via myMap.entrySet().
One simple way to handle most of the use cases can be like this
public class AddressBook {
private Map<String, Contact> contacts;
AddressBook(){
contacts = new HashMap<String, Contact>();
}
public boolean addContact(Contact contact) {
if(contacts.containsKey(contact.getName())) {
System.out.println("Already exists");
return false;
}
contacts.put(contact.getName(), contact);
return true;
}
public boolean updateContact(Contact contact) {
contacts.put(contact.getName(), contact);
return true;
}
}
class Contact{
private String name;
private String email;
private String phone;
private Address address;
public Contact(String name) {
this.name = name;
}
public Contact(String name, String email, String phone, Address address) {
this.name = name;
this.email = email;
this.phone = phone;
this.address = address;
}
// getters and setters
#Override
public String toString() {
return "name is "+name+" and address is "+address;
}
}
class Address{
private String street1;
private String street2;
private String city;
private int zipcode;
public Address() {}
// getters and setters
#Override
public String toString() {
return "street1 is "+street1+" and zipcode is "+zipcode;
}
}