Advertisement

Java begginer question

Started by June 10, 2018 08:45 AM
1 comment, last by Alberth 6 years, 6 months ago

Hello. I'm trying to make an ArayList with data that includes when the user logged in and logged out and save everything in a file like the date and the total time and so on. The problem is that I get stuck on a simple issue.

I have this class:

public class DayTimeFrame {    int id;    public DayTimeFrame() {      FromHour = new ArrayList<Integer>();      ToHour= new ArrayList<Integer>();      FromMinute= new ArrayList<Integer>();      ToMinute= new ArrayList<Integer>();    }    public void AddFromHour(int hour) {        FromHour.add(hour);    }    public void AddFromMinute(int minute) {        FromMinute.add(minute);    }    public void AddToHour(int hour) {        ToHour.add(hour);    }    public void AddToMinute(int minute) {        ToMinute.add(minute);    }    public ArrayList<Integer> FromHour;    public ArrayList<Integer> ToHour;    public ArrayList<Integer> FromMinute;    public  ArrayList<Integer> ToMinute;}
	 
	

And with that structure I want to make another Array that contains the element for all days in a month. So day 1 is a DayTimeFrame object that can contain more Integer elements like FromHour, To Hour and so on. If the user loggs 100 times in day 5 the element in the ArrayList that us the 5th one contains the DayTimeFrame  that contaons 100 FromHour and ToHour elements.

The thing is that when I want to modify the elements for conviencence I first fill the 

ArrayList<DayTimeFrame> dayTimeFrame = new ArrayList<DayTimeFrame>(); for(int i=0;i<=31;i++) {     dayTimeFrame.add(emptyFrame); }
	[code]
	 
	And when the user updates a day I just modify like this:
	[code]dayTimeFrame.get(1).AddFromMinute(11);dayTimeFrame.get(5).AddFromMinute(22);dayTimeFrame.get(7).AddFromMinute(33);dayTimeFrame.get(0).id=8;
	

 

The problem is that even tho I specifically select only 1,5 and 7 and 0 index elements ALL THE ELEMENTS in the array change. Its like the objects share the same ArrayList<Integer>. I dont understand why. I come from C++ and I know if I declare an object inside another one it gets local to that object. Why the get function modifies all the elements ? Or is the problem with the members of the class and its another way to declare them?

 

 

 

Please format code using the 'code layout' (the <> brackets in the editor), code isn't readable this way.

 

1 hour ago, Azzazelus said:

I dont understand why. I come from C++

This is a standard gotcha when you switch to reference-based languages, like Java, Python, or C# (and likely a few others).

What you need to get your head around is that "MyClass c" is not a value, it's a pointer to a value managed by the JVM. You can see this by realizing my "c" is currently not filled, "c.myValue = 3" will crash the program on a NullPointerException. Also, you need "new MyClass()" to make a MyClass instance.

More concrete:


// Assume MyClass.java exists.

MyClass c;  // Still empty.
Myclass d;  // Still empty.

MyClass e = new MyClass(); // e refers to the created instance.
c = e; // c refers to the same instance.
d = e; // d refers to the same instance.

// Assign new value to a member of the instance
d.myValue = 3;

// Since c and e refer to the same instance, they also have the new myValue 3.

So while you never write "*c->myValue", you are effectively working in dynamically allocated memory in C++-speak.

 

In your code, you make 32 references to the same emptyFrame object in the same list. If you change the obect from one list-entry naturally they all change.

If you want to have independent DayTimeFrame objects, allocate new objects in the loop:


List<DayTimeFrame> dayTimeFrames = new ArrayList<DayTimeFrame>();
// Some suggested changed to the line above
// 1. Use the List<> interface as much as possible rather than the ArrayList<> implementation class.
//    It makes cleaner code, and changing ArrayList for another kind of list becomes much simpler.
//
// 2. Make your life much simpler by using plural form for container variables, and singular form for variables that hold a single instance.
//    for (DayTimeFrame dayTimeFrame : dayTimeFrames) ...    looks more natural than
//    for (DayTimeFrame dtFrame : dayTimeFrame) ...          doesn't it?

for (int i = 0; i <= 31; i++) {
    dayTimeFrames.add(new DayTimeFrame()); // Make new object for each element!
}

Note that unlike in C++, "new" is a quite cheap operation in Java, so don't be afraid to use it.

This topic is closed to new replies.

Advertisement