Upload
holly-owen
View
213
Download
0
Tags:
Embed Size (px)
Citation preview
Nodes & You
Understanding the changes that are happening to your code
Nodes & YouThis presentation uses the Magazine example from the book. Files you need can be found on the class website under “Lab Menu > Book Examples > Chapter 12.” You need Magazine.java, MagazineList.java, and MagazineRack.java.
This presentation brought to you courtesy of the Better Coding Bureau.
(If viewing this on your own, please view as a slideshow instead of using creator mode; believe me, it helps)
Nodes & YouOn each of the slides, when talking about code examples or on diagrams, bold represents class names or variable types, and italics represents individual objects or variables:
String myName;int count;Magazine magazine;
wuts a nodeI’m glad you asked, Johnny. Nodes, at their most basic level, are pointers, which means they point at things, usually other objects. But how do they do this?
In order to understand, first let’s examine how Java handles objects in memory, using the example of the String class, with which you are hopefully all familiar.
StringsWhen you type some code like,
String myName = “johnny”;here’s how Java actually stores the String myName in memory:
Mem. Address
Mem. Contents
0x1000
0x1001 0x2001
0x1002myName
Mem. Address Mem. Contents
0x2000
0x2001 ‘j’
0x2002 ‘o’
0x2003 ‘h’
0x2004 ‘n’
0x2005 ‘n’
0x2006 ‘y’
0x2007
StringsAs you can see, myName’s own memory space holds only another memory address; in other words, myName points at 0x2001, which is where the array of characters “johnny” is actually stored.
Mem. Address
Mem. Contents
0x1000
0x1001 0x2001
0x1002myName
Mem. Address Mem. Contents
0x2000
0x2001 ‘j’
0x2002 ‘o’
0x2003 ‘h’
0x2004 ‘n’
0x2005 ‘n’
0x2006 ‘y’
0x2007
Please stare at the diagram until you understand
StringsIn Java, all objects are handled this way. Every object you’ve ever made has been merely a pointer to where the data actually resides in memory. So, if you say:String aName = myName;
Mem. Address
Mem. Contents
0x1000
0x1001 0x2001
0x1002
myName
Mem. Address Mem. Contents
0x2000
0x2001 ‘j’
0x2002 ‘o’
0x2003 ‘h’
0x2004 ‘n’
0x2005 ‘n’
0x2006 ‘y’
0x2007aName0x2001
StringsAs you can see, myName and aName now have not only the same value, but they actually point to the same location in memory, so any changes to aName will also affect myName.
Mem. Address
Mem. Contents
0x1000
0x1001 0x2001
0x1002
myName
Mem. Address Mem. Contents
0x2000
0x2001 ‘j’
0x2002 ‘o’
0x2003 ‘h’
0x2004 ‘n’
0x2005 ‘n’
0x2006 ‘y’
0x2007aName0x2001
ok but why shuld i carYou should care, because
I find your lack of faith disturbing
It’ll make sense in a minute, ok?
Example Time!Time to bust out MagazineRack.java, MagazineList.java, and Magazine.java, assuming you have not already done so.
First, an overview of how this program fits together:
- MagazineRack has the main method, so it’s the “driver”, the file that’s actually in control.
- MagazineList is the data structure; it has its own private class called MagazineNode; the nodes are individual elements in the data structure.
- Magazine is the class used to store each piece of data; all it holds is one String so it’s pretty boring.
Overview
MagazineRackHere is MagazineRack’s main method (which comprises basically the whole class). As you can see, it:
- Creates a new MagazineList called rack
- Adds several Magazine objects to rack
- Prints out rack (this will call MagazineList’s toString() method)
And that’s it! Now, before we look at MagazineList, let’s take a gander at Magazine.
MagazineHere is the Magazine class. As you can see, it is very simple, with only one class variable, a String.Let’s see what happens when a new Magazine object is created with this line of code from MagazineRack:
1. - The String literal “Time” is passed to Magazine’s constructor as the String object newTitle; in other words, newTitle now contains the data “Time”.
2. - title is assigned newTitle’s value. As we just learned, that means that they point at the same memory address. The purpose of this is to keep the String “Time” somewhere permanent, because newTitle will disappear once the constructor ends.
MagazineAnd that’s it! So really, when you construct a new Magazine, only those two things happen. The other method you see in Magazine, toString(), does only one thing when it is called: it returns the String object title that each instance of Magazine contains.
All righty, time to look at MagazineList!
MagazineList
HereItIs.
MagazineListMagazineList has only one class variable, a MagazineNode called list.
MagazineList’s constructor only does one thing: it sets list to null; in other words, list initially points at nothing.
MagazineList’s add() method takes one parameter, a Magazine object. That’s why in the driver, we see that a new Magazine object is created when MagazineList’s add() method is used:(rack is an instance of MagazineList)
There’s a lot more to the add() method, but we’ll cover it later.
MagazineListMagazineList’s toString() creates a blank String called result, then uses a while loop to append data from individual Magazines to it. (you don’t have to completely understand this part yet)Then result is returned.
As you can see, next up is MagazineNode. This is where it starts to get tricky.
MagazineNodeMagazineNode is a private subclass of MagazineList. That means that only code in MagazineList can directly access any of MagazineNode’s class variables or methods. MagazineNode has two class variables:
- A Magazine called magazine (please do not follow this terrible naming convention in your own code)- A MagazineNode called next. It probably seems weird that each instance of MagazineNode has its own instance of a MagazineNode, but it makes more sense if you keep in mind that each of these nodes, because they are objects, really just contain a memory address that they point to.
MagazineNodeMagazineNode’s constructor takes a Magazine
object called mag as a parameter. It then assigns its class variable magazine to have
the same value (point to the same address) as mag.
Then, next is initialized to null.
There’s no arrow coming out of null,because null means nothing
Mem. Address
Mem. Contents
0x1000
0x1001
0x1002
magazine
Mem. Address Mem. Contents
0x2000 ‘T’
0x2001 ‘i’
0x2002 ‘m’
0x2003 ‘e’
mag
0x2000
nullnext
0x2000
ok I think I get itActually, you don’t. That’s ok though, only geniuses do (the first time).
But, don’t let your lack of coding skills stop you from getting at the upcoming slides!
Don’t worry, even this guy will understand eventually
add (Magazine mag)Ah, the add method, the core of this class. This is the most difficult part to follow, so pay attencion!
The add method in all its verboten glory
First, we will explore what happens the first time a new Magazine is added (in other words, when the MagazineList is created but currently empty).
add (Magazine mag)Recall that the class variable list is initialized to null in MagazineList’s constructor.
The add method in all its verboten glory
Mem. Address
Mem. Contents
0x1004
0x1005
0x1006
list null
Because of this, list, which is of type MagazineNode, currently points at nothing.
add (Magazine mag)
Mem. Address
Mem. Contents
0x1000 0x2000
0x1001
0x1002
Mem. Address Mem. Contents
0x2000 ‘T’
0x2001 ‘i’
0x2002 ‘m’
0x2003 ‘e’
mag
The first thing to notice is that the add method starts out with a (presumably valid) Magazine object named mag, which it takes in as a parameter.
add (Magazine mag)Next, a new MagazineNode creatively named node is created using mag as a parameter.For the sake of being less confusing, you may now think of node as being a pointer at a MagazineNode object that contains a magazine and a pointer.
0x1234
node
0x1234
MagazineNode
Magazine
“Time”
next
null
add (Magazine mag)
0x1234
node
0x1234
MagazineNode
Magazine
“Time”
next
null
Recall that each MagazineNode object has two class variables, a Magazine (whose name isn’t that important) another MagazineNode named next. Remember that next will essentially act as a pointer to the next MagazineNode in the list. Right now it’s null.
add (Magazine mag)Next in the add method, a new MagazineNode named current is declared, but not initialized. It won’t be used the first time the add method is called.
add (Magazine mag)We are now asked if list is null.Is it? Well, let’s look at the constructor.
So, it was initialized to null, and since we haven’t executed any code that changes its value yet, yes, it is null. Therefore, we execute the single line of code that “if (list == null)” is tied to.
add (Magazine mag)
0x1234
node
0x1234
MagazineNode
Magazine
“Time”
next
null
null
list
Immediately before this next line of code is executed, this is the current state of list and node.
add (Magazine mag)
0x1234
node
0x1234
MagazineNode
Magazine
“Time”
next
null
null
list
Now, let’s go ahead and execute it.
0x1234
Ba-zing! As you can see, list being assigned the value of node means that it now stores the same address, and therefore points at the same thing.
add (Magazine mag)
0x1234
node
0x1234
MagazineNode
Magazine
“Time”
next
null
list
Since we went inside the if, we skip the else block, reach the end of the method, and node ceases to exist because it was declared inside the method.
0x1234
MagazineRackNow, it’s time to go onto the next add call, with the Magazine “Woodworking Today”. For the sake of brevity, I’ll call it “Wood…”.
A ReminderOn each of the slides, when talking about code examples or on diagrams, bold represents class names or variable types, and italics represents individual objects or variables:
String myName;int count;Magazine magazine;
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
null
list
Here’s the current state of our MagazineList when we enter the add method again.
0x1234
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
null
list
Next, node is declared and initialized, and current is declared but not given a value, so it doesn’t point at anything (yet).
0x1234 0x2345
node
0x2345
MagazineNode
Magazine
“Wood…”
next
null
null
current
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
null
list
list has a value, therefore it is not null, so we skip the if code and go to the else block.
0x1234 0x2345
node
0x2345
MagazineNode
Magazine
“Wood…”
next
null
null
current
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
null
list
current is assigned the value of list. Since the value that list has is a memory address, current now points at the same object in memory.
0x1234 0x2345
node
0x2345
MagazineNode
Magazine
“Wood…”
next
null
current
0x1234
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
null
list
Now we hit a while loop that asks if current.next is not null. Is it?
0x1234 0x2345
node
0x2345
MagazineNode
Magazine
“Wood…”
next
null
current
0x1234
current.next
No! It is null, therefore the condition evaluates to false and we skip the loop.
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
null
list
Then, current.next is assigned the value of node.
0x1234 0x2345
node
0x2345
MagazineNode
Magazine
“Wood…”
next
null
current
0x1234
current.next
0x2345
So, the first node in the list now has a pointer to the next node.
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
Since we’re at the end of the method, current and node die a horrible, lonely death.
0x1234 0x2345
node
0x2345
MagazineNode
Magazine
“Wood…”
next
null
current
0x1234
0x2345
MagazineRackAll right, we’ll go through one more iteration of the add method, this time with “Communications of the ACM”, or “Comm…”.
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
Here is the current state of our MagazineList at the beginning of the method.
0x1234
0x2345
Magazine
“Wood…”
next
null0x2345
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
As before, we create a new MagazineNode named node and a blank MagazineNode named current.
0x1234
0x2345
Magazine
“Wood…”
next
null0x2345
0x3456
node
MagazineNode
current
null
0x3456
Magazine next
null
MagazineNode
“Comm…”
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
The if condition is false, so we skip over it. Inside the else block, current is given list’s value.
0x1234
0x2345
Magazine
“Wood…”
next
null0x2345
0x3456
node
MagazineNode
current
0x1234
0x3456
Magazine next
null
MagazineNode
“Comm…”
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
We now check the condition in the while loop. Is current.next not null?
0x1234
0x2345
Magazine
“Wood…”
next
null0x2345
0x3456
node
MagazineNode
current
0x1234
0x3456
Magazine next
null
MagazineNode
Yes! It isn’t null, because it has a value (0x2345), and so the condition is true and we go inside the loop.
“Comm…”
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
This line of code assigns current.next’s value to current.
0x1234
0x2345
Magazine
“Wood…”
next
null0x2345
0x3456
node
MagazineNode
current
0x1234
0x3456
Magazine next
null
MagazineNode
Boom! current now points to the next MagazineNode in the list!
0x2345
“Comm…”
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
Since current.next is now null again, we exit the loop.
0x1234
0x2345
Magazine
“Wood…”
next
null0x2345
0x3456
node
MagazineNode
current
0x3456
Magazine next
null
MagazineNode
0x2345
“Comm…”
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
Just like the end of the last call to the add method, current.next is assigned to point to node.
0x1234
0x2345
Magazine
“Wood…”
next
null0x2345
0x3456
node
MagazineNode
current
0x3456
Magazine next
null
MagazineNode
0x2345
Ba-zam! Mission, complete!
0x3456 “Comm…”
add (Magazine mag)
0x1234
MagazineNode
Magazine
“Time”
next
list
0x1234
0x2345
Magazine
“Wood…”
next
0x2345
0x3456
node
MagazineNode
current
0x3456
Magazine
“Comm…”
next
null
MagazineNode
0x2345
0x3456
you are here
MagazineRackAnd we’ve returned from the add method, back to the driver. Don’t worry though, there’s still two more calls to add! Just kidding, I’m out of space to display MagazineNodes, soI’ll let you figure outhow the rest of it wouldgo down.
Hope you understood
If not, here’s a sweet picture of a cartoon pig!
Probably not actually copyright Neil Self, 2009This took way too freaking long