Issue
I am not sure how to call the dogID from dog class and add it to the dogID class which is present in the customer. I also have the owner in the dog class which is the customer ID of that particular dog. I also have the transaction class where I need to access the dog ID from dog class. I have the other variables like Arrival date, departure date, service rate which can take only 3 values like 1,2,3 and rate per day. I am not sure how to define the date data types, so that transaction info must be sorted on basis of start date.
public class Customer implements Comparable<Customer>{
private int CustomerID;
private String lastName;
private String firstName;
private Set<Dog> dogs;
}
public class Dog implements Comparable<Dog>{
private int dogID;
private String dogName;
private Customer owner;
private String breed;
private String color;
}
public class Transaction implements Comparable<Transaction> {
private Dog dogID;
private Date arrivalDate;
private Date departureDate;
private List<Integer> serviceLevel = Arrays.asList(1,2,3);
private List<Integer> ratePerDay = Arrays.asList(89,129,149);
private double totalcharge;
private double deposit;
}
Solution
On Getters and Setters
As all the variables in the classes are private, I am not sure how to call these variables
private
variables are not visible outside of the class in which they are defined.
If you want to access the value of a private variable from another class, then you need to provide an accessor method with higher visibility. That would be a getter and (if necessary) a setter. Then call that on the encapsulating class to access the encapsulated variable value, e.g. dog.getId()
.
Most IDEs can autogenerate getters and setters for you. I recommend using the IDE functionality to automatically generate standard code like constructors, getters, setters, toString, and hashCode functions.
Example App
For your example, you could have something like the following. This example may be a bit more complicated than you need. But perhaps you might learn some things by studying it.
App Output
Opening shop
Servicing customer: Customer{id=0, dogs=[Dog{id=1, name='Fido', ownerId=0}, Dog{id=2, name='Dido', ownerId=0}]}
Servicing customer: Customer{id=3, dogs=[Dog{id=4, name='Poly', ownerId=3}, Dog{id=5, name='Anna', ownerId=3}]}
Servicing customer: Customer{id=6, dogs=[Dog{id=7, name='Butch', ownerId=6}]}
Closing shop
DogGroomingService
import java.util.ArrayList;
public class DogGroomingService {
private ArrayList<Customer> customers = new ArrayList<>();
private void enrollCustomers() {
addCustomer("Fido", "Dido");
addCustomer("Poly", "Anna");
addCustomer("Butch");
}
private void addCustomer(String... dogNames) {
Customer customer = new Customer();
for (String dogName: dogNames) {
Dog dog = new Dog();
dog.setName(dogName);
customer.addDog(dog);
}
customers.add(customer);
}
private void serveCustomers() {
System.out.println("Opening shop");
for (Customer customer: customers) {
System.out.println("Servicing customer: " + customer);
}
System.out.println("Closing shop");
}
public static void main(String[] args) {
DogGroomingService groomingService = new DogGroomingService();
groomingService.enrollCustomers();
groomingService.serveCustomers();
}
}
IdService
public class IdService {
private static final IdService instance = new IdService();
private int nextId = 0;
public int generateNextId() {
return nextId++;
}
public static IdService getInstance() {
return instance;
}
}
Customer
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class Customer {
private int id;
private final Set<Dog> dogs = new HashSet<>();
public Customer() {
this.id = IdService.getInstance().generateNextId();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Set<Dog> getDogs() {
return Collections.unmodifiableSet(dogs);
}
public void addDog(Dog dog) {
dogs.add(dog);
dog.setOwner(this);
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", dogs=" + dogs +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return id == customer.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
Dog
import java.util.Objects;
public class Dog {
private int id;
private String name;
private Customer owner;
public Dog() {
id = IdService.getInstance().generateNextId();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Customer getOwner() {
return owner;
}
public void setOwner(Customer owner) {
this.owner = owner;
}
@Override
public String toString() {
return "Dog{" +
"id=" + id +
", name='" + name + '\'' +
", ownerId=" + owner.getId() +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dog dog = (Dog) o;
return id == dog.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
General Notes
I autogenerated some of the code using the IDE (getters/setters/equals/hashcode).
I did make a couple of minor modifications to the generated code, e.g. when generating the string for a dog, I just reference the customer id rather than the full customer data, otherwise, you end up in an endless loop because there is a two-way reference established between those entities.
See the Baeldung tutorial on equals and hashcode, if you are unfamiliar with them and why you might what to use them rather than implementing Comparable as you have in your question code.
Comparable is used for ordering, but what does it mean for one dog to be less than another dog or for one customer to be more than another? Perhaps you could define a default order based on dog name or customer id (I don't know it depends on your requirements). Perhaps defining comparators might be better. See the difference at:
Follow-up for additional questions
I have two classes Customer information and Dog information, which will include the following data variables, customer ID, dog ID list (contains the dog ID for each dog owned by the customer).
I have Dog information class which takes the dog information and the owner ID(Customer ID) of that dog.
I am not sure how to add the dog ID from the dog class to the corresponding customer (owner of the dog) in the customer class dog list
If you only want to store IDs and not full object references, you can do that.
See the Customer addDog
method below:
public void addDog(Dog dog) {
dogIds.add(dog.getId());
dog.setOwnerId(this.id);
}
You do however lose the ability to see other information in the objects outside of the ID. To find that out you would need to provide separate functions to find the full object data by id. For example:
public interface DataAccess {
Customer findCustomerById(int customerId);
Dog findDogById(int dogId);
}
I won't provide an implementation for those find features here as I don't know how you store and retrieve data in your application.
Here are some modified output and classes that just refer to customers and dogs by IDs rather than by object references.
Opening shop
Servicing customer: Customer{id=0, dogIds=[1, 2]}
Servicing customer: Customer{id=3, dogIds=[4, 5]}
Servicing customer: Customer{id=6, dogIds=[7]}
Closing shop
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class Customer {
private int id;
private final Set<Integer> dogIds = new HashSet<>();
public Customer() {
this.id = IdService.getInstance().generateNextId();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Set<Integer> getDogIds() {
return Collections.unmodifiableSet(dogIds);
}
public void addDog(Dog dog) {
dogIds.add(dog.getId());
dog.setOwnerId(this.id);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return id == customer.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", dogIds=" + dogIds +
'}';
}
}
import java.util.Objects;
public class Dog {
private int id;
private String name;
private int ownerId;
public Dog() {
id = IdService.getInstance().generateNextId();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getOwnerId() {
return ownerId;
}
public void setOwnerId(int ownerId) {
this.ownerId = ownerId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Dog dog = (Dog) o;
return id == dog.id;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public String toString() {
return "Dog{" +
"id=" + id +
", name='" + name + '\'' +
", ownerId=" + ownerId +
'}';
}
}
Answered By - jewelsea
Answer Checked By - Cary Denson (JavaFixing Admin)