public static boolean Equals Method - java

I have to objects.
Student and Course (both of which have this static equals method)
I also have the driver which my professor wrote and I have been told not to touch.
My goal is to make two arraylists of courses taken by the student, and current courses the student is taking.
My professor gave me all of the methods, I am supposed to fill in the bodies.
I double checked, and the equals method is copied exactly as he wants it to be.
This is a homework problem.
I need to fill in the body of this equals method.
I have tried things like if(this.id == other.getID()) but I keep on receiving this error:
error: non-static variable id cannot be referenced from a static context
I have tried using this.getID() instead but to no avail. I think this probably has something to do with this being static. (I am not allowed to change that.)
What is the correct way to go about writing this? I am not going to include all of the getters and setters in the below code.
public class Student {
private String id;
private String firstName;
private String lastName;
private String major;
private String minor;
private ArrayList<Course> coursesTaken;
private ArrayList<Course> currentSemesterCourses;
private double gpa;
/**
Course constructor
*/
public Student(String id, String firstName, String lastName, String major, String minor, ArrayList<Course> coursesTaken, ArrayList<Course> currentSemesterCourses) {
/*Your code goes here */
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.major = major;
this.minor = minor;
this.coursesTaken = coursesTaken;
this.currentSemesterCourses = currentSemesterCourses;
}
public static boolean Equals(Object obj) {
//Your code goes here
//base it on id firstName, lastName, major, minor and gpa
}

I think this probably has something to do with this being static. (I am not allowed to change that.)
Then your assignment makes no sense whatsoever and there is no way to solve it.
If you are writing a static equals(Object) method, then you have no Student. There is only one object that got passed in, and it could be any type. "Equals" is a question you ask about two things, and you don't even have two things to compare, you have only one thing that might not even be a Student.
The method you've been asked to write is like asking "Is this object equals?" It makes exactly as little sense as that sentence.

Related

i Have written this membership class, how can i create a method to find a specific ID given to a member?

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());

Setter params final in Java

I have always been programming in java, and recently i started learning some c++.
In C++ it is conventional to set setter params as const, why don't we see this as much in java ?
I mean are there any disadvantages to creating a setter like so:
public void setObject(final Object o){ this.o=o; }
vs
public void setObject(Object o){ this.o=o; }
The first one should enforce for Object param o to stay constant through the whole set function, not ?
Edit:
A final param would enforce this NOT to happen :
public void setName(String name){
name="Carlos";
this.name=name;
}
The user will never be able to set the name different from "Carlos"
There's little advantage to setting a Java method parameter as final since it does not stop someone from changing the parameter reference's state within the method. All it prevents is the re-assignment of the parameter variable to something else, which does nothing to the original reference, and it allows for use of the parameter in anonymous inner classes. If you wanted true safety in this situation, you'd strive to make your parameter types immutable if possible.
Edit
You've posted:
public void setObject(Object o){
o++; // this does not compile
this.o=o;
}
Which mixes primitive numeric and reference type. It only makes sense if o is an Integer or other numeric wrapper class, and even so, making it final would not prevent someone from creating:
private void setI(final Integer i) {
this.i = 1 + i;
}
But neither your code nor this code above would affect the parameter object on the calling code side.
Edit
OK now you've posted:
public void setName(String name){
name="Carlos";
this.name=name;
}
But then someone could write
public void setName(final String name){
this.name= name + " Carlos";
}
Here's where the danger comes and where final doesn't help. Say you have a class called Name:
public class Name {
private String lastName;
private String firstName;
public Name(String lastName, String firstName) {
this.lastName = lastName;
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
And then a class, Foo, with a Name field and a setter. This is dangerous code:
class Foo {
private Name name;
public void setName(final Name name) {
name.setFirstName("Carlos");
this.name = name;
}
}
Because not only does it change the state of the field, it changes the state of the Name reference in the calling code, and the final modifier won't help one bit. The solution: make Name immutable.
e.g.,
import java.util.Date;
// class should be declared final
public final class BetterName {
private String lastName;
private String firstName;
private Date dateOfBirth;
public BetterName(String lastName, String firstName, Date dob) {
this.lastName = lastName;
this.firstName = firstName;
// make and store a private copy of non-immutable reference types
dateOfBirth = new Date(dob.getTime());
}
// only getters -- no setters
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public Date getDateOfBirth() {
// return copies of non-immutable fields
return new Date(dateOfBirth.getTime());
}
}
Okay, a final parameter/variable cannot be assigned to. As the java compiler needs to be capable to determine if a variable/parameter is actually final (for anonymous inner classes), optimization is no factor AFAIK.
It is more that C++ has a larger tool set, which java tried to reduce. Hence using C++ const string& is important, saying
The string is passed by pointer, access is automatically dereferenced.
If the actual argument is a variable, the variable itself is not changed.
Mind there might be a conversion operator for passing something else than a const string&.
Now java:
Java does not allocate objects on the stack, only keeps primitive types and object handles on the stack.
Java has not output parameters: a variable passed to a method call will never change its immediate value.
Back to your question:
As a setter in java mostly would not benefit from a final parameter.
A final will be a contract to not use the variable for a second assignment.
However:
public final void setXyz(Xz xyz) {
this.xyz = xyz;
}
is more useful: this method cannot be overriden, and hence may be safely used in a constructor. (Calling an overriden method in a constructor would be in a context of a still not initialized child instance.)

Java class storing static data

I have a large amount of static data that I want to store in my code, and I'm not sure the best way to do this. As an example, I want to store some fields like first name, last name, address, and phone number. I want to store this for several different users.
My initial thoughts were that I'd create a class with the fields I want, and then I'd make that class a nested class. I would make the outer class singleton and have an ArrayList of the inner class. I'd then instantiate several copies of the inner class. I feel like this is going to be awful though, because I don't want to instantiate several copies of a class. I want to just have one class with all the information.
Anyone know how I should go about this?
I hope I got you right. It seems that you want to have a set of constant (immutable) Person objects. If it is true, enumeration is the thing you are looking for. You can have something like:
enum Person {
Kent("myLast","Kfirst","kfoo"),
Someone("sLast", "sFirst", "sfoo");
private String lastname;
private String firstname;
private String foo;
Person(String lastname, String firstname, String foo) {
this.lastname = lastname;
this.firstname = firstname;
this.foo = foo;
}
public String getLastname() {
return lastname;
}
public String getFirstname() {
return firstname;
}
public String getFoo() {
return foo;
}
}
you can get field value by:
Person.Kent.getFirstname();
I am not sure if I understand you right.
What you are looking for is inheritance. You can have a class called Person which contains all the fields you want (along with appropriate methods). Then you can have other specialized persons like a Manager or what not by extending that class (If you want to, that is. Or else, you can just instantiate a Person).
You use static when your data is to be shared among objects of the class. If you have the name and age, say, as static then you will be in hot water. You need them to be non-statics. That way every object will have their own copy of the fields.
Have a look : http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
What about making an interface with all needed constants?
Then every class you want to contain those static values will implement that interface?

Passing a Class type within a constructor of another class?

Do forgive me if the title is not correct, I thought this very question has to with "Polymorphism" but didn't want to complicate the title.
I am learning Java and following "Java: Learn to Program", As I am going along, I am applying the knowledge and creating my own scenarios to see
how "Polymorphism" is applied. I would appreciate it if someone can help me understand how to do this task. I have three classes:
Abstract Employee
Manager (Subclass of Employee)
Restaurant
Employee class and Manager class are pretty straight forward. I am trying to create a restaurant and every restaurant has a manager. My question is:
Should I pass "Manager" type as constructor arguments of "Restaurant" class or instantiate the "Manager" object in the constructor?
public abstract class Employee{
private String _empName;
private double _empSalary;
public Employee( string name, double salary){
_empName = name;
_empSalary = salary;
}
public void setEmpName( String name ){
_empName = name;
}
public String getEmpName(){
return _empName;
}
public void setEmpSalary( double salary ){
_empSalary = salary;
}
public double getEmpSalary(){
return _empSalary;
}
}//CLASS
public class Manager{
private double _yrsOfExp;
public Manager( String name, double salary, double experience ){
super(name, salary);
_yrsOfExp = experience;
}
public void setManagerExperience( double years ){
_yrsOfExp = years;
}
public double getManagerExperience(){
return _yrsOfExp;
}
}//CLASS
This is where I need help, I am declaring the constructor with "MANAGER TYPE". Should I be declaring the instance of "Manager" with the construction instead of
passing "Manager type" with the constructor, please?
public class Restaurant{
private Manager _manager;
private String _location;
//CONSTRUCTOR 1
//SHOULD I PURSUE IT THIS WAY OR
public Restaurant( Manager manager, String location){
_manager = manager;
_location = location;
}
//CONSTRUCTOR 2
//SHOULD I DO IT THIS WAY?
public Restaurant( String name, double salary, double experience, String location){
super(name, salary, experience);
_location = location;
}
public String toString(){
String str = "";
return str;
}
}//CLASS
This is partly a matter of taste and of what else you're going to do with the objects.
If you may ever want to refer to Managers independently, then they want to be their own object rather than properties of the Restaurant.
Since a Restaurant is not itself a Manager, I would suggest that it shouldn't take a Manager's properties in its constructor, and should instead have a Manager assigned to it (either in the constructor or in a setManager() call).
Among other things, that will make much more sense if one Manager is ever in charge of two Restaurants.

What's the most object-oriented way to design an address book?

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;
}
}

Categories