I was asked to write this part of a program and then test it in the following way:
Add some statements to the main method that create two or three contact instances, add them to the address book, and then search for one or two of them. Display the result of each search to see if they were retrieved correctly. Then remove one of them and show the list to be sure that it was removed correctly.
I wasn't entirely sure how to test this. What should I write in the main class? Also, is the rest of the code correct?
Do this for Contact Class:
Create this class in the client package. This class should have three fields (An email address, A full name, A nick name). All of these should be Strings.
Provide two constructors: one full constructor (parameters for all three member variables), and one that has a parameter only for the email address. This second constructor will leave the other two fields null.
Add a toString method (and use the #Override annotation) that works like this:
Contact c1 = new Contact("jenny#gmail.com");
c2.toString() should return "jenny#gmail.com".
Contact c2 = new Contact("jenny#gmail.com", "Jennifer Abott", "jenny");
c2.toString() should return "Jennifer Abott (jenny) jenny#gmail.com".
Do this for AddressBook Class:
Create this class and have a single member variable of type ArrayList<Contact>. Define the variable, don't just declare it
You do not need a constructor.
Write an add method that has a Contact parameter and adds the contact to the contact list.
Write a remove method that has a String parameter, which is the nick name of the contact to remove. It returns nothing. Remove that contact from the contact list. Hint: Use the search method that you already wrote in order to find the contact, then remove that contact from the contact list. See the online documentation for ArrayList for how the remove method works in the ArrayList class. Be sure that the remove method does not crash if you give it a nick name that does not exist in the list.
Write a search method that has a String parameter, which is a nick name to search for. The method must iterate over the contact list. If the nick name is found (use .equals), return that contact. If no contact is found, return null.
Write a show method that displays each Contact instance. It has no parameters and returns nothing. Display one contact per line, and number each line. Like this:
Jeff Meunier (jeff)
Bill Gates (money)
Vladimir Putin (vman)
Make sure that the numbers shown start at 1, not at 0.
Contact class:
package client;
public class Contact
{
private String _emailAddress;
private String _fullName;
private String _nickName;
public Contact(String emailAddress, String fullName, String nickName)
{
_emailAddress = emailAddress;
_fullName = fullName;
_nickName = nickName;
}
public Contact(String emailAddress)
{
_emailAddress = emailAddress;
}
#Override
public String toString()
{
if(_fullName == null)
{
return "<" + _emailAddress + ">";
}
else
{
return _fullName + " " + "(" + _nickName + ")" + " " + "<" + _emailAddress + ">";
}
}
}
Address Book class:
package client;
import java.util.ArrayList;
public class AddressBook
{
public ArrayList<Contact> contactList = new ArrayList<Contact>();
public void add(Contact _contact)
{
contactList.add(_contact);
}
public Contact search(String nickName)
{
for (int n=0; n < contactList.size(); n++)
{
if(contactList.get(n).equals(nickName))
{
return contactList.get(n);
}
}
return null;
}
public void remove(String nickName)
{
if(search(nickName) != null)
{
contactList.remove(search(nickName));
}
}
public void show()
{
for(int n=0; n<contactList.size(); n++)
{
System.out.println(n++ + ". " + contactList.get(n).toString());
}
}
}
I don't have much in the main class yet, but here it is:
Main Class
import java.util.ArrayList;
import client.Contact;
public class Main
{
public static void main(String[] args)
{
Contact c1 = new Contact("jeffm#engr.uconn.edu");
Contact c2 = new Contact("jeffm#engr.uconn.edu", "Jeff Meunier", "jeff");
}
}
"Add some statements to the main method that create two or three contact instances, add them to the address book, and then search for one or two of them. Display the result of each search to see if they were retrieved correctly. Then remove one of them and show the list to be sure that it was removed correctly."
If this is your task then:
1. You created a few contact instances, so this is done, but create a few more with all the available class fields set (this will be needed for the next steps)
2. Now you must create an instance of your address book class.
AddressBook addressBook = new AddressBook();
Add the created contacts to the adress book
addressBook.add(c1);
addressBook.add(c2);
// other contacts
Use the show method to see if everything is correct.
addressBook.show();
Try removing one and show the available contacts again to see if this worked.
addressBook.remove(c1.getNickName()); // Make get method for the nickname
addressBook.show();
Then search for a contact with a certain name, assign this to a new contact object and then print something from it to acknowledge that the object is the correct one.
Here your logic can break, because your search does not cover the possibillity that you have more then one contacts with the same name. So you should return an List of found contacts instead of one contact. Implement this and search again (make sure you search for objects with unique and non-unique names so the testing is acceptable).
Your search testing will look something like this at the end:
List <Contact> contacts = addressBook.search("John");
for(Contact contact in contacts) {
System.out.println(contact.toString());
}
Now since your delete method depends on the search, you will have to change it a bit too. When you do that, test the remove method again as above.
Work out every step until it works fine and your done.
P.S. You may want to print some description between different testing prints, so you can see clearly the results in the output
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last month.
Improve this question
I'm a newbie in Java and I have a file where every first line is the title of every second. For example the text file looks like this:
John Holm
blue
Anna Karina
orange
etc...
where every first line is the name of a person and every second is their favourite colour. Now I would like to use the information to for example find what is for example John Holm's favourite colour or change his favourite colour to green instead. How do I best access the data?
I tried with scanner to see all the lines where blue reoccurs, but I cannot get the code to write the previous line.
Should I split the text file into a table with name and favColour as columns or is there a way to assign the previous line to the next line as a name in Java? I also thought of splitting the file every second line. However, I am unsure which solution would be most efficient. Would be very thankful for some insights!
I think a solution would be to create an object containing the properties of your characters (their name and their favourite colour).
So, you can create a class named like how you want to name your object (let's call it Person), and set the name and the favourite colour as attribute of your Person object:
public class Person {
private String name;
private String favColour;
public Person(String name, String favColour) { // Constructor of your object
this.name = name; // Setting name
this.favColour = favColour; // Setting favourite colour
}
}
Now, create a main method to read your file, store the values into two lists, one containing the names, the other the colours, and then creating as many Person objects as you need:
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("src/wherever you stored it"); // Enter the file path as a String here
Scanner scanner = new Scanner(file); // Create a scanner that will read your file
List<String> names = new ArrayList<>(); // List that will contain the names read from the scanner
List<String> colours = new ArrayList<>(); // By the way don't forget to import *java.util.List* and *java.util.ArrayList* if your IDE doesn't do it automatically
int index = 0; // The index that'll know whether you store a name or a colour
try {
while(scanner.hasNext()) { // While the scanner still reads something from the file
if(index%2==0) { // If the index is even
names.add(scanner.next()); // Add the line to the names list
index++;
} else {
colours.add(scanner.next()); // Else add it to the colours list
index++;
}
}
} catch (Exception e) { // Don't forget to import *java.io.IOException*
System.err.println("Error: " + e.getMessage()); // You can write a custom message that will appear in your console if there's an error, e.g. if the program can't find your file
}
scanner.close(); // Close your scanner
// Now you can create a new Person object
Person p1 = new Person(names.get(0), colours.get(0)); // Create a Person object called p1, with the first element (index 0) of names and colours lists as attributes
System.out.println(p1); // Print your Person
}
}
Almost done, the last line must print some weird string. If you want to print your Person properly, you have to override the toString() method of your object:
// In the Person class:
#Override
public String toString() {
return "Name: " + this.name + "\nFavourite colour: " + this.favColour;
}
Now try again and you'll see the console prints properly what you want to see.
In the case of the example you gave, your console should print:
Name: John Holm
Favourite colour: blue
You can create as many Person objects as you want, and maybe store them into a list as well.
To make this simpler, you can create a function in your Person class:
public static Person newPerson(int i, List<String> names, List<String> colours) {
return new Person(names.get(i), colours.get(i));
}
And you can call it in your main:
Person p2 = Person.newPerson(1, names, colours);
You can now create a method that will create new Person objects from this function, and store them into a list or whatever you want.
To set a value, you'll have to create setters in your Person class, in order to modify the private characteristics of your Person from outside the Person class:
public void setName(String name) {
this.name = name;
}
You can do the same with the colour:
public void setFavouriteColour(String colour) {
this.favColour = colour;
}
And now, you can call these methods from your main:
p1.setName("John Doe");
p1.setFavouriteColour("green");
You can also create a method to combine both setters:
public void setPerson(String name, String colour) {
this.setName(name);
this.setFavouriteColour(colour);
}
By the way if you need these values at some point, you can also create a getter along with your setter:
public String getName() {
return this.name;
}
Feel free to ask anything you didn't understand or think is wrong :)
a simple android program which accept a user id and user name, and store them inside an arrayList using a subclass called Student. There are 2 buttons, one of them record the information and the other one display them. The top button seem to work fine, but for the other one it display something that looks like the address instead of the actual data, what's the problem? Thanks
Override Object.toString() in your Student class.
//Sample code
public String toString() {
return "id of the student:" + this.id + ",, "
+ "name of the student:" + this.name ;
}
For more info, see this answer
use this code for you funclist method
private void funclist(){
StringBuilder output = new StringBuilder();
for(int i=0;i<studentList.seize();i++){
output.append(studentList.get(i) + "\n");
}
}
this will convert your object to string or you can add
studentList.get(i).toString()
instead of your code.
I have two classes in BlueJ, SuperHero and SuperWeapon. I need to create a method that adds super weapons in the Arraylist. The method is supposed to be called with a parameter of the type SuperWeapon.
This means that the method assumes that a SuperWeapon object exists. The method is therefor not supposed instantiate a new SuperWeaponobject.
And only weapons with unique names may be added to the list, therefor a control of the new SuperWeaponobject is needed.
The code below is what i currently have, from what I understand, the code right now does not check if a superweapons name is unique when made. Sorry if the code is a little bit weird, i translated it to english from swedish but I hope someone understands what I am in need of.
Code:
import java.util.ArrayList;
public class SuperHero
{
private ArrayList<SuperWeapon> superWeaponList;
private String superHeroName;
public SuperHero()
{
superHeroName = "Superman";
superWeaponList = new ArrayList<SuperWeapon>();
}
public void addSuperWeapon(SuperWeapon superWeapon)
{
if(superWeaponList.contains(superWeapon))
{
System.out.println("The Superhero already has a superweapon with the name: " + superWeapon.getName() + ".");
}
else
{
superWeaponList.add(superWeapon);
System.out.println("A new superweapon has been registred for the superhero");
}
}
}
There are two options to solve your problem either change to a HashMap<String, ArrayList<SuperWeapons>> which maps the superhero's name to his weapons or else override the equals method in the superhero's class such that two superhero's are equal if their names are the same rather than the same object i.e., memory location
I am trying to get this program to get the passwords from an array list.
import java.util.ArrayList;
public class CompanyDatabase {
public ArrayList<Person> getPeople() {
ArrayList<Person> people = new ArrayList<Person>();
String[] u = {"Joe","Stan","Leo","John","Sara","Lauren"};
String[] p = {"pass4321", "asdfjkl", "genericpw", "13579", "helloworld", "companypass"};
for(int j = 0; j < u.length; j++){
Person temp = new Person(u[j],p[j]);
people.add(temp);
}
return people;
}
}
import java.util.ArrayList;
import java.util.Scanner;
public class CompanyDatabaseDriver {
private static Scanner scan = new Scanner( System.in ) );
public static void main(String args[]) {
CompanyDatabase bcData = new CompanyDatabase();
ArrayList<Person> people = bcData.getPeople();
// what i tried
System.out.println(bcData.getPeople());
// also tried this
System.out.println(people.get(1));
}
}
The output is
[Person#1c9b9ca, Person#c4aad3, Person#1ab28fe, Person#105738, Person#ce5b1c, Person#1bfc93a]
or just
Person#1995d80
for the 2nd thing I tried.
The specific number / letter combination seems to change each time the program is run. Is there a way to specify which string to display from the array list?
Override toString() in the Person class
What you are seeing is the String returned by Object's default toString() method which is the name of the class followed by its hashcode. You will want to override this method and give the Person class a decent toString() method override.
e.g.,
// assuming Person has a name and a password field
#Override
public String toString() {
return name + ": " + password; // + other field contents?
}
Edit: if you only want to display one field in your output, then use Dave Newton's good solution (1+).
Yes; print the object property you want to see:
out.println(people.get(0).getFirstName());
the default implementation when you print List is to call toString for all objects in this List. and because you don't override toString method, it will call the default toString from Object class, that will print objects hashCode in hexadecimal notation, so you get this result:
Person#1c9b9ca ( classname#hashcode) , and it can be changed every time you execute the application because this hashcode come from memory address of the object).
so one option, is to override toString in your class
#Override
public String toString() {
return String.format("First name %s, Last name %s", firstName, lastName);
}
and call
System.out.println(yourList); // this will print toString for each object
the other option, is to print these attributes when you iterate on the List
for(Person person: persons) {
System.out.println("Person first name: " + person.getFirstName() + " , Last Name: " + person.getLastName());
}
In the first print statement you are trying to print the object..that is why you always see different number/letter combination..
Task at hand:Consider a class ratingScore that represents a numeric rating for some thing such as a move. Attributes: A description of what is being rated, The maximum possible rating, rating.
It will have methods to: get rating from ta user, Return the maximum rating posisble, return the rating, return a string showing the rating in a format suitable for display.
a. write a method heading for each method
b. write pre and post conditions for each method
c. write some java statements to test the class
d. implement the class.
I think i did what i was supposed to do, but it is a method and i am not sure that i put enough room for it to be changed much, this is what i have so far.
import java.util.*;
public class MovieRating
{
// instance variables
private String description = " A movie that shows how racism affect our lives and choices";
private int maxRating = 10;
private int rating;
// methods
//precondition: Must have maxRating, rating and description before you post it back to the user.
//rating between 1 and 10, maxRating is set to 10, description of a movie
public void writeOutput()
{
System.out.println("The max rating is: " + maxRating );
System.out.println("Your rating is: " + rating );
System.out.println("The rating for" + description + " is " + rating);
System.out.println("while the max rating was " + maxRating);
}
// PostCondition: Will write maxRating, rating and description to the user.
//Precondition: description, enter the rating
public void readInput()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("What would you rate the movie \"American History x\" out of ten");
System.out.println(description);
rating = keyboard.nextInt();
}
//postcondition: rating will be set to user's input for the movie American History x.
}
This is my Tester program.. not much so far
public class MovieRatingTester
{
public static void main(String[] args)
{
//object of the class MovieRating
MovieRating rating1 = new MovieRating();
rating1.readInput();
rating1.writeOutput();
}
}
SO did i cover what was told to cover? i think i did but i think i did it the wrong way, let me know please.
Ok, my point of view is:
Your class, MovieRating is missing some basic elements of OOP, and that is what I think you suppose to learn in this homework.
The first element missing is a constructor method, what you did is automatically assigning each new MovieRating the same description. The job of the constructor function is giving a unique values to the Object when it first built in the system.
The constructor method is special, it is public and has the exact same name is the class, as we said, in this method you suppose to assign values to your object variables.
the second thing will be to put getters/setters, these are methods who has access to your private values and will be used to assign/get the values from them. Note the use of them in the code:
import java.util.*;
public class MovieRating
{
// instance variables
private String description;
private int maxRating;
private int rating;
/*This is the constructor
Note the use of .this - the expression is used to call the class form withing
itself*/
public MovieRating(String description, int maxRating, int rating) {
this.setDescription(description);
this.setMaxRating(maxRating);
this.setRating(rating);
}
/*These are the getters and setters - get is used for getting the value
and set is used for assigning a value to it*/
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getMaxRating() {
return maxRating;
}
public void setMaxRating(int maxRating) {
this.maxRating = maxRating;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
//This is a method for the printing commands - notice the use of the get methods//
public void printRatings()
{
System.out.println("The max rating is: " + this.getMaxRating() );
System.out.println("Your rating is: " + this.getRating() );
System.out.println("The rating for" + this.getDescription() + " is " +
this.getRating());
System.out.println("while the max rating was " + this.getMaxRating();
}
// PostCondition: Will write maxRating, rating and description to the user.
/*Precondition: description, enter the rating
Note the use of this.setRating()*/
public void readInput()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("What would you rate the movie \"American History x\" out of ten");
System.out.println(description);
this.setRating(keyboard.nextInt());
}
//postcondition: rating will be set to user's input for the movie American History x.
}
Using the constructor, you can create a different rating from your tester program
MovieRating rating1 = new MovieRating("description 1", 10, 5);
MovieRating rating2 = new MovieRating("description 2", 9, 7);
You should not ask / print the data from the Ratings class. These ratings can come from user input, but also from database, web, etc.
1 Add getters and setters for properties of MovieRating
2 Pass the read and write methods to the main. Something like
System.out.println("The rating for the movie |" + rating1.getTitle() + "| is " + rating1.getRating());
3 You are not aggregating ratings to a movie. You can't have two rating to the same movie (v.g., by different users) together. Convert the rating attribute into a Vector to solve it. Change setRating for addRating
There are many other things, but obviously this is a starters exercise and I do not want you to get confused. Work on these issues and check with your teacher.
Java (and OO in general) is all about abstractions. You want to keep your objects as general as possible so that you extend your programs functionality without modifying existing code. This may be beyond what your professor was looking for but here are my suggestions:
1) Rating - separate this into its own class
Again, the rating is totally separate from the movie - songs can have ratings, tv shows can have ratings. Today ratings can be 1-10, tomorrow ratings can up thumbs up or thumbs down, etc. A Movie "has a" rating. Let Rating decide how to prompt the user and how to display itself.
2) Now that you have a separate Movie class, I would take away the hard-coded title, description in my Movie class (this will let me create many movies and rate them).
Then I would eliminate System.out.println in writeOutput method (you can pass in the OutputStream to the function)
By hard-coding in System.in you are forcing implementation. What if tomorrow your professor says "now, instead of printing to the console, print to a file or a database"? You have to modify the code. Actually, instead of writeOutput, I would override the toString method that all Objects have and then just call System.in(movie.toString()) in main.
3) Your test method doesn't "test" anything - it is just executing a statement. Typically a test method will simulate input, execute the statements, and check for the proper state at the end. A good way to signal that the state is improper (if your test fails, like maybe your Movie Rating is -1), then you throw an exception.
4) This is un-OO related and just a preference, but I would put both Pre and Post conditions before the methods. This just makes it easier to find in my opinion.
The idea of OO is that you separate responsibilities/concerns into separate classes. Each class is responsible for itself. This helps to keep your code more flexible and maintainable. Good luck on the assignment!