• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • Devaka Cooray
Saloon Keepers:
  • Ganesh Patekar
  • Tim Moores
  • Carey Brown
  • Stephan van Hulst
  • salvin francis
Bartenders:
  • Ron McLeod
  • Frits Walraven
  • Pete Letkeman

assign array to object  RSS feed

 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm taking my first Java course ever and can not seem to finish this week's assignment on my own. I've created a class called Measurements
in which values are stored in an array connected to an object. I've created a lot of methods doing all kinds of stuff with the array that works just fine but
the second constructor where I'm supposed to create an object with an array as parameter doesn't work. I get an object "m" but it's always empty.



Tried to paste the lines of code that I think are relevant. Any help will be much appreciated.
 
Marshal
Posts: 6075
418
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First, welcome to the Ranch!

Well, with the code snippet you showed us - it is not possible what you just said.

Add the following line right after the line 13 and you'll see yourself.

However, since you trimmed some of the code, it is possible you do something else with it so we don't see yet. Please post more code.
 
Sheriff
Posts: 12447
205
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jess Ericsson wrote:.. but the second constructor where I'm supposed to create an object with an array as parameter doesn't work. I get an object "m" but it's always empty.


Welcome to the Ranch!

How are you making the determination that "it doesn't work"? Please show us what you did that didn't give the expected results. What were the results and what was it exactly that you expected instead?
 
Marshal
Posts: 60704
189
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch (again)

I can see a potential problem, which you haven't been taught about yet, I'll bet. You can get problems if you simply pass an array as an argument. You are taking the array unchanged into the Measurements object. which means naughty people (e.g. I) can change it. Let's make some changes to your code:-Cure: Search for “defensive copies”. Take a defensive copy of that array whenever it comes into your constructor, or if you return it via a getXXX() method or similar. If you look in the Java® Language Specification (=JLS) (look for §10.7) you will find that all arrays have a clone() method ready‑made, which in the case of a double[] will do everything you require. Now it's easy: change the constructor to this:-Why have you got the constructor taking an int parameter? Do you know what your values array would look like after calling that constructor?

I haven't corrected your indentation. Look at lines 5 and 11‑14 (your line numbers, not mine). I know I appear to be fussy going on about indentation, but poor indentation is an effective way to hide errors from yourself. Spacing is important too. Put a space before the { in line 11 and no space before the [ in line 55. Most of your formatting however, is better than some people manage.
 
Jess Ericsson
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for all the replies!

*When I say that "m" is empty what I mean is that when I try to print it out in the Interactions window with the help of my toString method all I get is " ".

*Yes, I know it's not exactly neatly done. I've been given a sheet with rules for coding and I am going to make sure I follow all of them before I submit but my main focus right now is finishing the code.

*I'm probably not allowed to use .clone or anything else since I'm supposed to write basic code. For instance I'm not allowed to use Arrays.copyOf.

I'll paste all of the code so I know I'm not missing anything important.

 
Junilu Lacar
Sheriff
Posts: 12447
205
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The problem is that you are using the instance variable i in your for-loop in the toString() method. When you create a new object, the value of i is 0. It doesn't get updated to the number of elements that are in the array that you passed to the constructor. So when you call toString(), i is still 0 and you end up with an empty string. If you did what Liutauras suggested earlier, you would see what the actual contents of the array are.
 
Junilu Lacar
Sheriff
Posts: 12447
205
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The design of your class has some problems that contributed to the bug you have. First, you have this instance variable i that you use to track the number of elements added to the values array. The variable i is key to a number of things working correctly. With as much code as you have in that class, it's easy to lose track and miss updating the value of i correctly in every usage scenario. That is what happened when you added the constructor that takes an array as its argument.

If you are going to have a data structure that expands as you add elements to it, an array that you manage yourself is a poor choice. A better choice would be to use a List, like java.util.ArrayList. This takes care of the logic that you tried to code yourself. Use an array if you know the number of elements will be fixed. Use the more flexible List if you will have a variable number of elements.
 
Junilu Lacar
Sheriff
Posts: 12447
205
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In academic terms, your design is based on the invariant that the variable i always represents the number of elements in the values array. The correctness of your program depends on this condition to be always true. The bug came from the code in your second constructor not maintaining that condition. It changes the values array without updating the variable i thus invalidating the invariant condition that i represents the number of elements in values.
 
Junilu Lacar
Sheriff
Posts: 12447
205
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Compare the code you wrote for your add() method on lines 14-25 with the "before" in this article https://www.industriallogic.com/xp/refactoring/composeMethod.html

You have fundamentally the same code. Now examine how they used the Compose method refactoring in that article to make the code much cleaner and readable.

You may think that is too advanced for you right now but I still would encourage you to think about how to write clean, clear code by applying some very simple techniques. All that was done to clean that code up was to eliminate some temporary variables, and extract a few calculation details out to their own small methods. What is left in the original method are calls to the extracted methods.

It may seem like there's not much of a difference but the difference in readability and cognitive load is quite significant. This is the kind of thing I wish more schools would teach their students. Unfortunately, not many do.
 
Liutauras Vilda
Marshal
Posts: 6075
418
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jess Ericsson wrote:*...I've been given a sheet with rules for coding and I am going to make sure I follow all of them before I submit but my main focus right now is finishing the code.

*I'm probably not allowed to use .clone or anything else since I'm supposed to write basic code.


Do you mind (if allowed) to share these instructions?
 
Liutauras Vilda
Marshal
Posts: 6075
418
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:this article...
https://www.industriallogic.com/xp/refactoring/composeMethod.html


Nice example, but I missed one important thing there - lack of response in case of read-only. That's essentially the case in both examples, however, probably the actual demo is in refactoring and not the correctness (not saying it is certainly incorrect, I don't know full context) of an imaginable method.

Anyway, just mentioning, so people would consider (instead of using this form by default) whether it is fine to have method in this form, meaning to leave the task unaccomplished and not to tell anything.
 
Junilu Lacar
Sheriff
Posts: 12447
205
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right, the point was to demonstrate how to refactor the code, not in API design.

For the benefit of OP and anyone interested (hopefully there are), here's the refactoring and the thought process involved.

Starting with this:

As small as this method may be, the code is still difficult to comprehend at one glance. I would like to be able to understand it with less effort, say in 3 seconds or less. You can't do that in its current form because the details obscure the code's intent. That is, the implementation details, the how of this code, drown out the what or the intent.

We can easily remedy this situation and clear up the code's intent by applying a series of code simplifying techniques, namely, Extract Method, Rename, and eliminating temporary variables that have limited use.

The first change is to combine lines 15 and 16:

Next, the local variable max is a temp variable that is used in only one place. So you can eliminate it and inline the expression that was assigned to it where max was used.

Next, you extract the expression i == values.length, which is a "formula" to its own method and give it an expressive name:

Next, you extract all the operations inside the if-statement to its own method and give that an expressive name:

Then, you make everything in add() a high level idea by extracting the statement on line 15 to its own method:

Finally, I would rename the variable i to make it more expressive:

I also changed the loop variable in grow() to i because that's the variable most people expect to see when they see a for-loop. The variable k is usually used when i and j have already been used.

Now the add() method has been transformed to a Composed Method, keeping it at a high level of abstraction and clearly expressing what it does, not how it does it. When I read in that form, I can immediately grok what the add() method is doing.

How cool would that be if you were a maintenance programmer coming into this code for the first time?
 
Jess Ericsson
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi again everyone.

I'm very grateful for all the input. I couldn't find the time to use all tips and hints but they will surely come in handy for the next assignment. I can't post my instructions sheet since it's in Swedish but I'll post the given main code and the required output. I won't post my own code again, it's unnecessary long. My guess is that if someone come's here looking for an answer they can figure it out by reading the various replies.

Main code:



Required output:



Also, all method heads were given.
 
Jess Ericsson
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry, it appears to be called "method header" in English.
 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jess Ericsson wrote:I'm taking my first Java course ever and can not seem to finish this week's assignment on my own. I've created a class called Measurements
in which values are stored in an array connected to an object. I've created a lot of methods doing all kinds of stuff with the array that works just fine but
the second constructor where I'm supposed to create an object with an array as parameter doesn't work. I get an object "m" but it's always empty.



Tried to paste the lines of code that I think are relevant. Any help will be much appreciated.


in the second constructor you had used formal parameter as double array, you are sending reference of array which stores values not the array so remove the [] in the second constructor as only only double and compile it
 
sohail hussain
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

sohail hussain wrote:

Jess Ericsson wrote:I'm taking my first Java course ever and can not seem to finish this week's assignment on my own. I've created a class called Measurements
in which values are stored in an array connected to an object. I've created a lot of methods doing all kinds of stuff with the array that works just fine but
the second constructor where I'm supposed to create an object with an array as parameter doesn't work. I get an object "m" but it's always empty.



Tried to paste the lines of code that I think are relevant. Any help will be much appreciated.[/quot


i tried it and got this result
public ara2(double[] b)
{
for(double d:b)
{
System.out.println(d);
}
}
public static void main(String[] args)
{
double[] a= {2,3,5};
ara2 c= new ara2(a);

 
Sheriff
Posts: 5247
141
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

sohail hussain wrote:

in the second constructor you had used formal parameter as double array, you are sending reference of array which stores values not the array so remove the [] in the second constructor as only only double and compile it


This is not correct, I'm afraid.  The second constructor is setting values which is declared a double array, so the parameter needs to be a double array too.
 
Knute Snortum
Sheriff
Posts: 5247
141
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

sohail hussain wrote:
i tried it and got this result


I'm not sure what this code is demonstrating.
 
Knute Snortum
Sheriff
Posts: 5247
141
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sohail hussain:

* When you post, there is no need to quote the entire previous post.  Only quote what is necessary to provide context.
* Please UseCodeTags (that's a link) when you post code.
* You can prevent mistakes in your formatting by using the Preview button before you submit.  It's right next to the Submit button.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!