This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I need some help to gather my thoughts on how to approach this particular problem. Here is is:
I have an input file with multiple records and fields within those records. I don't know why it's a .txt file instead of a database. Here's an example of the .txt file I'm working with (names have been changed to protect their true identity--hehe j/k):
I'm supposed to be storing this data "in tables" so I'm assuming that it's meant to be in multi-dimensional array(s). Is it a good idea to store each "record" in one dimension and then each "field" into another dimension of the same array? Or would it be a better idea to have the fields be a separate array and then store those array's into another array? I guess have an array of arrays.
**DISCLAIMER** This is only part of a larger homework project. [ July 26, 2007: Message edited by: Brian LaRue ]
Originally posted by Brian LaRue: ...I'm supposed to be storing this data "in tables" so I'm assuming that it's meant to be in multi-dimensional array(s). Is it a good idea to store each "record" in one dimension and then each "field" into another dimension of the same array? Or would it be a better idea to have the fields be a separate array and then store those array's into another array? I guess have an array of arrays...
My first reaction would be to suggest a more object-oriented approach and define a class like Person, where a Person HAS-A firstName, lastName, etc. Then you can store instances of Person in a Java List, Set, or Map. But since this is homework and you've been instructed to use "tables," I guess you should use "tables."
Note that in Java, "multi-dimensional" arrays really are just arrays of arrays, so -- if I'm understanding correctly -- your first and second approaches would give you the same result in the end.
For example, suppose you have a 2-dimensional array, called "myArray." Then myArray actually references a single-dimension array containing other arrays. In particular, myArray[x] would reference the array at index x, and myArray[x][y] would reference element y in the array referenced by myArray[x].
So yes, it would make sense for the first dimension to represent records and other dimensions to represent fields within the record.
"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer sscce.org
Joined: Feb 01, 2006
yes, I was surprised myself that we haven't even gone over classes talking to other classes (one class calling methods of another's). The scary thing is that and we're done with the semester in 1.5 weeks! Yes, I also agree that there would be a better collection to store the data in than an array. Array's seem so limited and much information is needed beforehand in order to use them. Oh well, this instructor was big on flowcharting and hasn't concentrated on actually coding until the last few weeks. A lot of our lectures has been theory and "language independent" stuff. So Java semantics/syntax is new to me.
Anyways, is my logic correct here (assuming everything else is right)? Is this how I would fill the two-dimensional array? Is it legal to do it this way (variables as the index marker)?
**EDIT** This keeps giving me an "incompatible types" compiler error. Is it because the split method returns a one-dimension array and I'm trying to store it in a two-dimension array? Where am I going wrong?
Thanks for your help. [ July 26, 2007: Message edited by: Brian LaRue ]
Originally posted by Brian LaRue: ...This keeps giving me an "incompatible types" compiler error. Is it because the split method returns a one-dimension array and I'm trying to store it in a two-dimension array? ...
That's exactly right. The error probably looks something like...
...meaning it found a single-dimension String array (), but it needs a 2-dimensional String array () to be compatible with the type of "myArray."
But remember that myArray[row] (with a single index provided) references a single-dimension String array. You can assign the array returned by split to that.
Joined: Feb 01, 2006
I cannot figure this out. Everything that I've tried gets unexpected results. Somewhere in my code it messes up on the row iteration. However, I cant see where I'm going wrong. Here's what I've got so far:
This is what it spits out to the console:
It picks up the first and second record, but the weird thing is... it keeps looping with the second record's data. What am I doing wrong? I hate these multi-dimensional arrays! It's getting really frustrating!
When you increment to the next row, don't you also want to reset col back to zero?
arrayTwoDim[row] (with only the "row" dimension) references a single-dimension String array. And String's split method returns a single-dimension String array. Do you see a direct way to put these together?
Joined: Mar 22, 2005
You should be incrementing 'row' for each line that has been read. As it is, you're always assigning (and printing) to row 0. It also seems that the loop incrementing 'col' isn't doing anything, and could be removed.
Are you certain that the file reading works OK? Earlier you showed an 'InputFile' class, which is not in the standard API, so it's hard to tell. The usual way of reading a file would be something like:
Joined: Feb 01, 2006
ok, so I can understand this:
You read a line into a string variable to get it in memory. Then you use the split method on that string to break it up into chunks and store it into an array (single-dimension). Each chunk of data is stored in a separate index of the array. Then with that single-dimension array, you want to store it in a second array one row at a time. The two-dimension array will only have one column per row (that contains a reference to your single-dimension array with the chunks of string broke off and stored earlier).
I thought after you had your first single-dimension array, you had to break it up again and then store each of those chunks into the columns of the two-dimension array. From the sound of it I'm making it harder than it has to be.
I guess it's back to the drawing board! Alright, I'll try that and then get back to ya. Thank you so much for your ongoing patience and willingness to help me learn this stuff! Java programmers are, I guess, a tight group of friends!
Thanks again, and hopefully I'll get it working this time!
don't you also want to reset col back to zero?
I can only say one thing to this: Duh! How could I forget that? Thanks for pointing that out. Yes it would have kept incrementing the row number until the end of file. D'oh!
Earlier you showed an 'InputFile' class, which is not in the standard API
Sorry, I didn't explain this one. The InputFile class I'm using was given to me by the instructor. It has many nifty methods .readWord(), .readInt(), .readDouble(), .readChar(), .readLine(), .peek() -- don't understand what that one does, .unRead(), .read(), etc... He has also given us another nifty class Keyboard which allows input from the console instead of file. They're just making it a little easier for us--so they don't have to teach us that I/O stuff in the API.
HTH [ July 29, 2007: Message edited by: Brian LaRue ]
See: Line-Oriented I/O, which is pretty close to the approach Mr. Dittmer provides, with some exception hanling and so on.
In general, I just take the approach of a nested loop, but working out loop logic is dicey for a beginner. A nested loop often looks like:
And sorting out where to increment the indexes becomes obvious if you just think about it calmly. It can be that you are making it harder than it has to be, but Java programmers are not a tight group of friends - we just enjoy coding .... look at the post times !
Peek is a lookahead, it will come up soon enough that if the next character in the file is (somthing), then some logic changes and you have to bee able to lookahead. Consider the bee mis-spelling:
The unget() stuff descends from an earler day when programmers would laugh that anyone would need more than 64k to write a program. I find that the brain burns calories while intensely working mentally through this stuff and occasional walkaround breaks allow you to make faster progress as a beginner.
nifty class Keyboard is better done from a file, in my experience.
"The differential equations that describe dynamic interactions of power generators are similar to that of the gravitational interplay among celestial bodies, which is chaotic in nature."
In this case, you don't even need a nested loop for valuing the 2-dimensional array.
String's split method returns an array. So for each row, just directly assign the array returned by split. There's no need to iterate through columns.
Joined: Feb 01, 2006
I think I finally got it working. I noticed another problem with my code and can't believe that I overlooked it:
Here's the code that got those pesky arrays working, I believe:
and here's what it returns when the class is executed:
are those references to the single dimension array's indexes? How do you access the data contained in that array?
One more question, notice that I've declared that method static. My instructor said that it must be declared this way in order to call it from the same class it's contained in. This doesn't sound right and seems to be a workaround to call the method. Is that good programming practice? Is it better to get an instance of that class then use the dot operator to call the method?
Originally posted by Brian LaRue: ... are those references to the single dimension array's indexes? How do you access the data contained in that array? ...
The line System.out.println(students[row]); prints a String representation of the element at students[row]. This element is an array, and the String representation is of the array itself (which is an object) -- not the contents of that array. (In this case, the String representation uses the left bracket "[" to indicate an array, "Ljava.lang.String" to indicate the type of array, followed by a memory address.)
If you want to print the contents of this array, you will need to iterate through the elements (columns). If you're doing this for multiple rows, that's where nested loops come in. In psuedo code (lacking the iteration details)...
Originally posted by Brian LaRue: ... I've declared that method static. My instructor said that it must be declared this way in order to call it from the same class it's contained in. This doesn't sound right and seems to be a workaround to call the method...
Well, if you're going to call this method directly from main (which is a static method), then it would need to be static, because you can't call an instance method from a static context. You're correct that you should be able to create an instance and dereference it (use the dot) to call the method. But whether this is "better" depends on the class -- whether it makes sense to create distinct objects that have unique state (fields), or whether all you need is a class to provide certain behavior (methods).
Something to consider...
The String "temp" and the array "student" seem to be just temporary holders...
You could do this in a single line...
...although cramming too much into a single line makes for confusing reading.
Joined: Feb 01, 2006
Thanks Ulf and Marc for your continued help and suggestions. I think I've learned a lot about arrays and especially those multi-dimension arrays. I think I got that part of my program working and now it's on to polish up the other parts. I'm sure you'll see me again in the forums and hopefully it won't have to do with arrays! Hehe..Thanks again for all of your help!