Copy constructor create garbage objects - java

My teacher gave me 2 classes, one is passport and the other is date.
date contain 3 attributes (string day,string month, string year), getters, setters and 2 constructors, one of them is a copy constructor:
public date(date dt)
this.day=dt.getd();
this.month=dt.getm();
this.yaer=dt.gety();
passport class contain 2 attributes (string name, date exp(from date class))and there is this construcor:
public passport(string name, date exp)
this.name=name;
this.exp= new date(exp);
now in the main class, every time i create new date and new passport, every date is duplicate and i get 1 garbage object for every passport.
how can i get over this garbage object?

how can i get over this garbage object?
If date instances are mutable, you don't; you do what you're doing.
if date instances are immutable (their state cannot be changed once they've been created), then you just use the instance you're given rather than creating a new one:
public passport(string name, date exp)
this.name = name;
this.exp = exp;
}
You wouldn't want to do that if exp could be modified, because it would create cross-talk between your passport instance and whatever passed the exp to it.

how can i get over this garbage object?
Let the garbage collector does its job : as the Date variable passed as parameter to the Passport constructor will be out of scope of the execution context, the underlying Date object will be eligible to be collected.
The way the most straight to do it is to not assign the Date object to a variable.
Just inline its instantiation in the Passport constructor invocation :
Passport passport = new Passport(name, new Date(day, month, year));

optional solution:
in the main class:
passport[] arr = new passport[100]; // we have 100 passports
date d1= new date () //null date
for (int i=0,i<100,i++) // we have 100 passports
{ d1.setd(); //our setter asks for an input
d1.setm();
d1.sety();
arr [i]=new passport (string name, d1); }

Related

How to declare the variables which are of date type and to sort based on the date?

I have the transaction class where I have variables like Arrival date, departure date, I am not sure how to define the date data types, so that transaction info must be sorted on basis of start date. I want to give the date in an explicit manner to the class. For example, I want to give 5 dates and sort them. Can you please let me know, how to do that.
public class Transaction implements Comparable<Transaction>
{
private Dog dogID;
private Date startDate;
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;
}
tl;dr
Use only java.time classes, never legacy Date class.
Implement the one method required by Comparable interface.
#Override
public int compareTo( Transaction other )
{
return this.startDate().compareTo( other.startDate()
}
Details
Both Date classes included with Java are terrible, badly designed by people who did not understand date-time handling.
If you want a date only, without time of day, and without the context of a time zone or offset-from-UTC, use java.time.LocalDate.
private LocalDate startDate;
private LocalDate departureDate;
If the main purpose of your class is to communicate data transparently and immutably, define the class as a record. The compiler implicitly creates the constructor, getters, equals & hashCode, and toString.
And never use a floating-point type like double where accuracy matters such as moment. Use BigDecimal where accuracy trumps speed.
A list should generally be named in the plural, for clarity.
The Java naming convention is camelCase. So totalCharge.
public record Transaction
(
Dog dogID ,
LocalDate startDate ,
LocalDate departureDate ,
List<Integer> serviceLevels ,
List<BigDecimal> ratesPerDay ,
BigDecimal totalCharge ,
BigDecimal deposit
) {}
If you want to usually sort by the start date member field, implement the Comparable interface with its one required method, compareTo. We implement that method by calling upon the compareTo method built into the LocalDate class.
public record Transaction implements Comparable < Transaction >
(
Dog dogID ,
LocalDate startDate ,
LocalDate departureDate ,
List<Integer> serviceLevels ,
List<BigDecimal> ratesPerDay ,
BigDecimal totalCharge ,
BigDecimal deposit
)
{
#Override
public int compareTo( Transaction other )
{
return this.startDate().compareTo( other.startDate()
}
}

How to pass a value from a constructor to a setter in another class in JAVA?

Im learning object oriented programming in school right now, and there are some aspects of it I don't quite understand yet. I have a program that creates a database of users with their names, and birthdates. So I have 3 classes: person, PersonProgram(the main), and Date. The Person class has the constructor, setter, and getters for the names and the birth date. The Date class has error checking for proper dates and leap years etc. In the main program I create 5 People, and then give menu options to change and modify the names and dates. So for example, if the user wants to change the name my code looks like this:
System.out.println("Enter new first name:");
people[choice-1].setFirstName(input.next());
and that works and makes sense to me. But I want to know how I can change the date properly? The Date constructor takes 3 integers for the day, year, and month, so in the main program I prompt the user to input the 3 new dateswhich are stored in day, month, year integers. So my understanding is from there I would pass those 3 integers to the Date constructor:
new Date(month, day, year);
What I am confused on is where to go from there. The Date constructor gets the new Date call, and passes it to the setters. How can this newly created date object be passed back to the Person program, so the setter in Person for the birthdate can update the corresponding Person object? If I am not clear on my question please let me know, I figured I could articulate what I am trying to ask without posting all my code.
In your Person class you should have something like this:
public class Person {
private Date birthDate;
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate){
this.birthDate = birthDate;
}
}
And then in you would set the birthDate like:
person[choice-1].setBirthDate(new Date(month,day,year));
Taking into consideration that you are starting with OOP there is an important concept here, Encapsulation, the Person class restricts the free access to its fields, like birthDate, and sets the rules for the interaction with them. As an example you could check if the date is null before assigning it.
public void setBirthDate(Date birthDate){
if(birthDate != null) {
this.birthDate = birthDate;
} else {
//Whatever you wanna do here (throw an Exception, etc, etc)
}
}
Comment Question
Although it would be better to create another question:
Do I have to create an instance of the Date class in my Person class? Or anywhere for that matter?
No, the property/field birthDate is a reference to a Date object which will be stored in memory until no references are left. And it's up to you where to create them, nonetheless there are Creational Patterns, a familiy of Design Patterns that help you with this matter.
is it the birth date in person class of type 'Date'?
if so, you should create an instance of your class Date , do the control that you need and pass it to the constructor or setter of the birth date in the persson instance .
Date birthDate = new Date(month, day, year);
// Some controls
people[choice-1].setBirthDate(birthDate);
Date the_birth_date = new Date(mounth, day, year);
people[choice - 1].setBirthDate(the_birth_date);
You can set it like this: people[choice-1].setBirthday(new Date(month, day, year));. You would have to give the option to select the Person first.

enum test junit arraylist being overwritten reinstantiating not working

I have a post that describes the class structure a
enum static variable reference between java but as I began finishing up testing I'm running into a trivial error where I create the ArrayList but the debug statement show me that the Class Object is either the new list item created or the constructor default values.
#Test
public GoodsTest()
clearProductMaps();
Goods item = new Goods();
calendar.set(Calendar.MONTH, Calendar.JULY);
calendar.set(Calendar.DAY_OF_MONTH, 21);
calendar.set(Calendar.YEAR, 2016);
date = calendar.getTime();
item.setName("FirstItem_A");
item.setPrice(4.10);
item.setStatus(Library.STATUSES.US);
item.setDate(date);
actualGoods.add(0,item);
item = new Goods();
item.setProductName("FirstItem_A");
item.setPrice(3.70);
item.setStatus(Library.STATUSES.ME);
calendar.set(Calendar.MONTH, Calendar.AUGUST);
date = calendar.getTime();
item.setDate(date);
actualGoods.add(item);
System.out.println("debug " + actualGoods.get(0).getStatus());
}
My clearProductMaps just mandates the List is empty for the test.
The print statement is : debug ME
when I am expected the statement to be : debug US
Evidently setStatus of both different Goods seem to write to the same field. So this field is static. Static fields are fields of the class object Good.
As you spoke of enum, every enum constant is a static global singleton too.
enum Status {
SLEEPY,
ENERGETIC;
public int coffee;
}
Now the two objects each have a single coffee. Assigning it would be valid for either all SLEEPY or ENERGETIC occurrences. Such a confusion seems to be the case with Library.STATUSES.ME/US.

Alternative for using set methods when creating a new object

So I am trying to create a program that helps me keep track of my expenses and i have a question to do with how I create my objects.
So far i have been creating my objects like so:
Grocery milk = new Grocery();
milk.setName("Milk");
milk.setCost(2.84);
milk.setDate(30, 12, 2014);
milk.setType("Food");
My grocery class extends this expense class:
public Expense(){}
public Expense(String name, Double cost, Calendar purchaseDate){
name = _name;
cost = _cost;
purchaseDate = _purchaseDate;
}
So far my grocery class only adds another string parameter that i call type, and so here is my question:
Instead of using set methods to set my paramters for each new created object i would like to do it like this:
Grocery milk = new Grocery("Milk", 2.84, ??Date??, "Food")
But the date parameter is a little more complicated than the other parameters that are just of type string and double, is there a way to do what I want or am i better off using the set methods?
Thanks in advance for any help.
You can simply use an Object of type Date
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date date = formatter.parse("16/01/2015");
Grocery milk = new Grocery("Milk", 2.84, date, "Food")
Alternatives include using a Calendar object (which has more flexible/powerful date manipulation methods), or just storing your date as a String.
As for deciding whether you should use setX() methods or using a comprehensive constructor, unless there is a reason not to you can just have both available, and just use the most suitable at any one time.
Further reading:
Official Java Date & Time tutorials
Official Java Calendar tutorials

Can I have the time of an object from its creation or instance?

I have a code where a Student Object is created and depending on its time has to move from one list to another, therefore I need to timestamp those objects to know when they were created
class Student
{
private Date creationDate = new Date();
public Date getCreationDate()
{
return new Date(creationDate.getTime());
}
}
Initialize an instance variable with the current time in the constructor.
The code that created it can then interrogate the new instance and move it to the appropriate list.
If the creation time only matters once, don't even use an instance variable, just get the current time when you create it and act accordingly.
System.currentTimeMillis() returns the current time in milliseconds.

Categories

Resources