So in the previous video we actually implemented our add-in order method,
which was a way to iterate through the list of rare entries in our linked list.
And we found out that the list iterator is great for actually going through
linked lists and actually going through the actual entries one by one.
But I just wanna make a point before we move on and enhance this a little bit,
is the first time you actually create the list iterator, like on this first line
here, line 40, that's not actually yet pointing to the first record.
So you actually have to use a stringListIterator.next
to go to the first record.
So it's important to know that the first one is just a set up.
It's not automatically pointing to the first entry.
You need to use that .next first to actually get to the first entry.
And one thing I didn't do down here, was I needed to return true as well.
Return true, because at that point, we know that
things have been ordered correctly because we've been through these other tests here.
So, that's why I'm returning true there.
Then, obviously, it makes the method valid.
So, that's ListIterator.
That's just one method of actually going through and sorting our capital cities.
Now I just wanna make a point that writing methods with side effects
such as using .next is generally to be avoided.
So unless you really know what you're doing,
it's not a good idea to write a method that both returns a value and
changes the object that it's called from.
And that's what's happening in this method.
So we're returning the fact that it's true or false.
But we're also modifying the link list that was parsed by it.
We're actually changing the actual entries.
So generally speaking, you don't wanna do it that way.
But the Java people,
people who actually created Java, they do have a pretty good idea of these things,
and that's the way they've implemented iterators to work like that.
But generally speaking, again you probably wouldn't wanna do it that way.
So let's get back to our main class, I should say.
And we'll put some code in.
And this well test it to see if it actually works.
And if you can actually see the code all order in there.
So we'll come back in here, because we're gonna code in here already.
We got Sydney, Melbourne, Brisbane, Perth, Canberra, Adelaide and Darwin.
So what we need to do to implement this,
is we need to change this code a little bit.
We need to add the method call to our addInOrder, and
we need to pass the actual linked list as well as the entry that we want to save.
So we want to do something like addInOrder, placesToVisit.
So that's the linked list that we're sending to it, in Sydney.
So we're going to be calling that method.
And I'll just delete some of this so we can see what we're doing.
We're going to be calling the method at an order when passing the linked list toward,
and also the name of the city, in this case Capital City we want to add.
So I'm gonna do that for each one.
I'm gonna do one for Melbourne, Brisbane, Perth, Canberra, Adelaide and Darwin.
So I'm gonna go and change these.
Melbourne.
Brisbane.
Perth.
Incidentally, this wouldn't be a good order of actually visiting states, capitol
cities in Australia because we're going sort of left to right of the country.
So a lot of extra traveling but it's purely there for demonstration purposes.
Okay, so there's some, so what we then want to do now that that's been added,
we just want to do our printList again.
So I printList and we're passing places to visit.
So if we execute that, what should actually happen is we should get these,
actually added, or shown we should say, in an alphabetical order.
So let's just try that.
Going to run that.
And you can see that is working quite nicely.
You've got Adelaide, Brisbane, Canberra, Darwin, Melbourne, Perth, and Sydney.
So it's actually in the correct order, which is fantastic.
And just to verify that because the other thing we put in there,
we actually put in this comparison down here if comparison
equal is equal to zero to not allow a destination city to be added twice.
So let's just test that that actually works.
So i've put something like addInOrder, placesToVisit and
if we try say Alice Springs, well of course that should work.
Cuz Alice Springs is not on the list.
But if we do addInOrder.
Places to visit.
Darwin, that should actually fail because it's already in the list.
So when we rerun this again we should find the Alice Springs has been added,
but Darwin hasn't been added again.
And we should see a message on the screen indicating that Darwin was not added
because it's already included.
So we'll paste that in there now.
So we can reprint that after that of those two extra entries.
So we tried to add the second one, run it again.
You can see Darwin is already included as a destination.
Now the reason that that message is coming up earlier than all the is of course
is calling the add in order method first before printing it out.
So you can see the Darwin wasn't duplicated but
Alice Springs was correctly added to the list.
So you can see the link lists are extremely powerful.
And it's perfect for the type of data.
This scenario I'm actually showing you where we want to inserting records at
a regular basis, when you're needing to sort things or things like that.
This is a great way that we have to do that, to use linked list for that scenario.
So, let's actually now enhance this a little bit more.
So, what we're gonna do is we're gonna include a menu and
it's gonna allow us to decide when to move onto the next city.
And, we can also look at how to go back to a city we've already visited because
that's something we haven't talked about with linked lists.
We've got this .next, which we had.
I'll just close that down.
The .next which we had in our main, or our addInOrder method.
Of course that went to the next entry.
And we saw that on the slides that I showed in the previous video.
But the way that this actually works, and
the way that Java has implemented it is seriously pretty cool because what they've
done is I've given you the option to actually go back in both directions.
So you can actually go the next record in a forward motion.
The next, in this case, capital city.
But you can also go backwards as well.
So in other words, we could, if we're at Canberra, we could go back to Brisbane.
And this is possible because Java have implemented the link list
as a double link list.
So in other words it stores a reference to the previous item as well as a link,
a reference I should say, to the entry that's next as well.
So that's pretty cool that it actually handles both of those.
So let's actually add some code and implement that.
We're going to add a method called visit, which gives you the option of specifying
whether you want to go forward or back when you're actually searching.
You'll come down here and create that method.
You're gonna call it as I mentioned visits.
So I private static void visit.
And it's going to require of course the link list.
Linked List and that's going to be to house cities.
So we've seen this before, you can add some Scanner for
some inputs, scanner = new Scanner.
Scanner is going to be System.in.
And we'll put boolean quit = false so
we can set that to true if we want to actually exit.
I want a ListIterator of String cuz that says our data type for our cities.
ListIterator = cities.listed Iterator.
So, okay, so the first thing that we have to do.
We wanna do a test to see whether there's no cities.
So we can put in cities.getfirst.
And that's a way to actually retrieve the very first entry link in the link list.
So if that is equal to nothing.
That should be of course, not setting a value.
We're actually comparing it.
So it's equal to an entry, a null entry if that's the case.
We're gonna do a system out.
No cities in the itinerary.
Like so.
Then we go to return at that point.
We don't wanna do anymore processing cuz there's nothing to show.
And I'm adding this part to the video after I actually recorded the first bit.
I'm not actually too sure why I actually did this first piece of code
here cuz this is not actually right.
So .getFirst does actually get the entry.
There's no problems there.
But the == and the "" is no way ever to check for a string anyway.
And actually, in this case, it will return an error.
So if we actually send this an empty link list, it will actually return an error.
The correct way to actually test this is to actually to check is empty.
So we want isEmpty.
So again, I'm inserting this into the video after so use .isEmpty.
So when this little component stops, we go back to the other video again,
you'll see the old code.
But ignore that and use cities.isEmpty in its place.
And I'll also make sure I update that in the source code as well,
which you can download if you ever want to check the code for any reason.
Okay, back to the main video.
Else, we'll actually put the name that we're visiting, we'll put so Now Visiting.
+ listIterator.next, so we're actually moving to that first entry again.
So getFirst allows you to get the first entry without actually
changing the pointer.
But .next actually physically moves that next entry.
At that point we want to print the menu.
To get some options, we're gonna create that method shortly.
And then the actual loop is gonna be while Not quit.
So, we're gonna keep going until quit is set to true.
int action = scanner.nextInt, and we've seen a lot of this code before.
So, I'm not gonna spend any time going through it.
We've done this quite a few times.
nextLine is gonna clear the input line after that.
I'm gonna go through now and actually add a few switches.
And what we're going to do is, firstly, case 0.
So, if I enter 0, we're gonna put Holiday over.
We'll put Holiday (Vacation).
In Australia, we call them holidays, but I know overseas, it's often called vacation.
And we'll put quit = true.
Break. And I've actually forgot,
in my haste to type ahead, to actually put a switch on action.
Of course we need to do that.
And I'll just paste the case in there, we can continue going.
Okay. That's what I should have done right
the first time.
Okay, so that if you enter 0, then the vacation's over.
If we enter 1, we're going to do the following.
We're gonna go Now visiting, gotta move to the next one,
"Now visiting" = listIterator.next.
What I need to actually put, is actually put a test there or
course to actually check we can do it.
So if(listIterator.hasNext), so
we can only go to the next one if there is an entry there.
Then we need to do it that way.
Else, wanna print some output to say, Reached the end of the list.
So in other words, we've got to the last city in the list at that point.
So we're gonna keep on going if I select one to do just that.
And of course, importantly, I need to add a break as well.
I'm just going to move this up a little bit, so
I can see the top a little bit better.
Okay? So that's case 1.
In case 2, we're gonna do something we haven't seen before.
We're gonna go back to the previous entries.
Case 2, if(listIterator.hasPrevious), previous goes to the back,
as you would suggest, or goes to the previous entry.
We're gonna put, Now visiting.
This is rator.previous.
Else.
We are at the start of the list.
So, you can see what we've done there.
So, 0 is typed.
We're going to end the holiday so that's our way of exiting out.
If 1's typed, we're going to go to the next entry, the next city in our list.
But, if 2 is typed, we're going to go back to the previous entry.
So, in other words, then, we also need to do a test to see whether there's
Previous and we also have to do listIterator.previous as well.
And just to be clear, because we're doing the .next, you might be wondering,
well, how does it know it's a string?
Well if you recall, when we actually, at the start, we defined the listIterator,
we actually said it was on top string here.
So consequently, when we're actually going to print this out, system.out.print line,
it knows .next, it looks at that and says oh okay, that's a string.
And that's why it can actually print that out.
That, of course, is the same for next and also for previous.
And then case 3, we're just going to add our only data break there.
Case 3,
we're going to add just to redraw the menu in case it's going off the screen.
You've forgotten the option, so we'll printMenu and break on that as well.
Of course, we haven't implemented that yet.
Okay, so that's the basic visit class.
What we need to do is now implement that printMenu as well.
And that's gonna be very basic as well.
So we're going to just go into here, and
we're going to just do our private static void printMenu.
Available actions.
Press.
Then we'll do.
Row 0 to quit.
1, go to, oops,
go to next city.
2, go to previous city.
And 3, print menu options.
So that's our print menu.
So let's now try this.
Let's now add the code to actually start the visit command.
So we're going to just actually call the visit method, I should say command.
And check that it does, and we'll just see what happens.
So we're gonna put visit(placesToVisit).
So if we run that now.
Okay, so available actions, it now says, Now visiting Adelaide.
So if you go to the next city, type 1.
Now visiting Alice Springs.
Go to the next entry.
Visiting Brisbane.
Next entry, visiting Canberra.
If you try to go back to the previous city.
You notice there's a problem.
You notice what's happening?
Why did it actually double up there?
Actually notice that it seemed to not work, and
then it actually started going back in the right order.
Well the problem is that Java does not implement the link list in quite the way
that we've actually described.
Now there's actually an explanation of the listIterator I wanted to you show you
on the screen to help you sort of understand how this actually works.
So let's just open a browser, gonna paste this link in.
There we go, that's the listIterator, and if you actually go through here and
actually have a look,
you see that the problem actually is that there's no current position as such.
So the listIterator actually hovers between the items that would be
returned when you go to previous or you go to next.
So if you go forward with one and then go back with two, then go forward
with one etc, you never actually leave the city that you're actually in.
So this is actually a problem.
But there actually is a good reason for this.
So, it's ahead of actually allowed access to the item at .next or
previous in the normal way.
Then an error would actually lead to loops in the list.
For example, if it made a mistake where we're moving Perth from the list,
we'd end up with something like this.
And I'll just show this on the screen.
And we'll just go to that entry.
So in this scenario, if again, if I had left it how you would think it would
normally work, then traversing in this would then return Sidney, Alice Springs,
Melbourne, Brisbane, Alice Springs, Melbourne, Brisbane, Alice Springs,
Melbourne, Brisbane.
So it's sort of like an infinite loop, and of course, we don't want that to happen.
So this is like a really sufficiently serious problem in the past that
algorithms have been developed for detecting and
fixing loops in structures like linked lists.
So you can Google something like Tortoise and
the Hare Algorithm if you wanna do that in your own time.
You'll see that there's actually a big issue with that, and
that's about this linked list sort of looping over itself.
But the great thing is that Java have it set up in such a way,
that that is not going to happen to you.
So it doesn't really allow you to make that type of mistake where you'll
get into a loop.
What it does mean, is we need to keep tracking of which direction we're going,
and allow for the in between nature of the iterater.
>> So in other words,
there's a little bit more work that you need to do to get that to work.
But in the scheme of things, it's not really that hard.
So let's just go back and modify that code, to get it working correctly.
What we actually really need to do is, go back to our visit method.
And I'll close down this to make a bit of space, or
disconnect to close the program down.
Going to go back here now, to our visit.
And we need to add another variable.
We need to put a variable to track the direction.
So then we'll call it goingForward, we'll set that to true.
And what we need to do is, when we're going forward or backwards,
we'll need to do a test and we need to set that direction.
We'll start off with the first one, which is goingForward, case one.
So we're going to put if(!goingForward), so
in other words, that the user has previously selected going back.
Then we need to do for test input, if (listIterator.hasNext()
listIterator.next() and then, goingForward=true.
If we're doing that additional check to actually make sure,
that we actually can go, that there is the ability to go next.
And then actually go to the next entry again, so
that we can actually continue where we left off.
So it's actually let that extra step that I talked about to make sure that
[INAUDIBLE] scenario where you're doing a loop.
And likewise if we're going backwards.
If it's actually going forward currently, then we put if (listIterator.has,
if it's got a previous record, we go then to the previous entry.
Like so.
And of course we set going forward = false.
So just as a recap, again what we're doing is, we're actually setting this up.
If the user has selected to go forward and if we count it not going forward,
we check to see whether there's an entry we can go forward to.
We set it to go there.
That sets it up in the right direction so that the following code actually works.
And the other thing I'll need to do here is the end, going forward = false.
Because we reached the end of the list, so there's no more way to go forward.
So, we're gonna set that to false, once we actually have reached the end of the list.
And likewise, if we get to the start of the list., to the very first entry,
we need to do a similar thing.
We need to set goingForward, need to set that to true.
Because that's the only direction we can go now, cuz we've reached the first entry.
So we automatically change the direction, in pointing forward again.
So you can see what we're doing there, so we're just controlling the state.
We're just doing a little bit more house keeping,
to make sure that in the event that we're going in a particular direction,
once we reach either the start, in this case, with the going forward.
So in this case, if we actually are going forward, what we're doing is we're doing
a test to make sure that if we weren't going forward, prior to the actual menu
option being selected, we need to point in that direction to be going forward.
But also, if we get to the end of the list, we need to set going forward to
false, which means from now on we'll actually be navigating going backwards.
And we're doing the reverse in this scenario with case two.
If we were going forward, but the user has selected to go previous,
then we need to check whether we can go previous.
If we can, we go to that previous entry to point it in the right direction.
Then we set our flag to the fact that we actually are going
in a backwards direction, going to the previous entry.
And likewise when we reach the start of the list, the very first entry.
We can't actually go to any other previous records cuz we're at the first one, so
we're set going forward to true.
So hopefully that sort of makes sense, of what we've actually done.
So there's actually an extra check, there's an extra .next you need to
actually use, and the .previous if you're moving from one direction to another.
So just to confirm that's working, lets actually run it.
So let's just try it now.
So we can see we're now visiting Adelaide.
We're gonna got to the next city, Alice Springs, Brisbane.
So let's go back to the previous city now, Alice Springs, Adelaide.
We're at the start of the list, so we're not getting an error there.
So now if we go back, I'll go to the next entry, or next city I should say.
We're back to Adelaide again, cuz that's the first one in the list.
One, one, we can keep on going.
We've reached the end of the list.
It's not actually letting us do a thing.
It's not gonna let us go further and it's not crashing.
And go back again, and it goes backwards just fine.
So that's actually it, that's how to actually achieve that, and
to get our link list working.
So I hope you actually enjoyed that.
It can take a little while to get your head around link lists, but
they are extremely powerful.
And especially with the way that Java have implemented them,
to avoid you having to get in this scenario where there's an infinite loop
that we talked about in the Power Point slide.
So you don't need to worry about that, you just need to do a little bit more
housekeeping, if you do want your lists to have the capability of going into the next
entry and the previous entry, but you've never seen that code.
So in the next video, it's time for a challenge.
So, I will see you in that next video.