So it's time now for the generics challenge.
And if you haven't actually looked at the previous videos, I do suggest you'd make
sure you do that because you'll need to understand the concepts of generics.
And what I've done is I've just added this little bit of code that I talked about
right at the end of the previous video relating to
how to go about actually sorting an array list of teams that we had in that example.
You'll need to know something like that when you're actually implementing
this challenge.
Let me go now and actually type out the generics challenge.
Okay, so here is the challenge.
So, you'll need to create a generic class to implement a league table for a sport.
Now the class should allow teams to be added to the list, and
it should also store a list of teams that actually belong to the league.
Now, your class should have a method to print out the teams in order.
And the team at the top of the league should be printed first.
Now only teams of the same type should be added to any particular instance of
the lead class.
And the program should actually fail to compile even if an attempt
is made to add it in compatible team.
And this is relating to the concepts you've learned in the last four videos
in this generic section.
So basically if you've watched those videos you'll have basically
everything you need to be able to go ahead and actually do this challenge.
All right, so when you're ready pause the video and go away.
And see if you can actually figure out this challenge and
come up with your own solution.
When you're ready to come back and see what my implementation is,
start the video again, and I'll actually show you how to do it.
So for now, pause the video and I'll be waiting here patiently for
you to get back.
Okay, so how did you get on, did you figure out the solution?
Hopefully you figured it out, and have come up with a good alternative.
And just a reminder, I know I've said this a few times,
is there is no one answer that's perfect.
So if you're basically fulfilling the criteria that I've typed in here in
the challenge, and your programs does that, then that's great.
You don't have to have typed the same code as me, so
it's important to actually know that.
Let's continue and start work on it.
So firstly we actually need a class, we're gonna call it league.
New class, call it League.
And what we're going to do with the league, we're gonna
be using generics of course, so we're gonna come over here, T extends Team.
And what I will need to do which I haven't yet
is I will need to actually paste the Team code in.
I'm gonna do that in a sec.
The Team code is obviously the code that we used previously.
So I'm gonna do public String name,
private ArrayList, of the same type
league = new ArrayList, like so.
So, I'm not sure if I've shown you how to do this before.
I think I may have.
But, if you've got one IntelliJ project open you can actually open
up a second one.
So, we're going to leave this one open under File > Open Recent.
I'm gonna go to the generics challenge which was the last video
prior to this one.
I'll open that and it should come up with an option here and
I'm gonna select New Window.
I'll select this window.
It's going to effectively close this current project, and open another one.
But click on New Window.
It's going to have both open at once.
Then I can either come up here, to Windows, probably the easiest way, and
then choose GenericsChallenge, which is the other project.
So, what I'm going to do is start copying some of these over, so
I'm going to tab over.
Now I'm gonna actually use the command tutor on a Mac, which actually switches,
and you can see down there it's a new window project.
Ctrl+Alt+Close Bracket for Windows or Linux.
And I can go to my generics challenge and I can actually select say a player first.
I can copy that, copy, tab back over, and then paste.
Now if this is depending on the number of classes, it may or
may not be appropriate for you to actually do this amount of work.
It should get tedious doing sort of a heap like this.
But, if it's only got a few classes, it can be a good way of doing it.
It's a couple and we'd have a few more football.
We might see whether we can get by with just football and we'll come back and
do some more when we need to.
We'll paste that as well.
Now that we've done that, we'd just actually do a build.
And I got the same error, source 1.6.
I need to make sure I'm running source 1.8.
And I fixed that.
That should actually make that problem go away, okay?
I'll get rid of that window down at the bottom.
Okay, so we've got now the basic mechanism so we can go back and
continue with our league.
I'm gonna close down these other classes.
We don't need them for a while.
Go back to our league.
Our league has now got an array list, got a type there, the parameter so that we're
using the team, and we're going to make sure that that's actually enforced.
And just a note here we don't actually need to have that in there.
We have always put the diamond by itself to actually get rid of any errant,
any warnings.
Okay, we need to add a constructor.
Constructor's only gonna be the name of the league.
We're going to add a function for add, the public boolean add which will be the team.
And to simply if(league.contains(team),
return false, except any duplicates,
otherwise we're gonna do a league.add.
Add to the array list with team, and return true.
That is a mechanism now to allow us to actually save teams to the league.
Then the other thing we wanna do is actually go through and
show the league table.
We can do that quite simply with
public void showLeagueTable.
And we use that Collections.sort(league).
And we're gonna accept import and
that should come in through automatically by IntelliJ.
Now again the reason that sort works, is because within team
we've actually written or compared to, or obviously implements the comparable.
But we've actually written our compare to and
this will be used automatically by the collection's framework when we're sorting.
As you can see that this is incredibly powerful to have our own compare to method
because it makes sorting quite trivial.
And this is sort of like an automatic thing that will actually take that into
account now which is fantastic.
So now that's now sorted in this method.
Then we can go through and we could put for top,
the top and T call league cuz for each entry,
you can do an output of a t.getName, + t.ranking, like so.
So that's our showLeagueTable method.
And again, we defined league to be a parameterized type.
That's bound by the Team class.
So in other words a Team or any subclasses would be allowed
as the type argument when we create an instance of this league.
And the parameterized type is used in the declaration
of the ArrayList up here as well.
And that's obviously gonna hold the league's teams.
And also we're using that again in the add team.
And finally when we're in the for loop in the showLeagueTable.
That method sorts the arrays as I talked about Collections.sort.
And you can see that I'm actually going through now and
actually printing that out in the right order.
And again we've got the parameterized type as well in use there.
So to actually go back to the main now we can actually write a bit of code
there now.
So we could put something like League<Team,
like so, so we're defining the type of team.
And we'll call that a footballLeague = new League and
we'll say that's that AFL string, footballLeague AFL.
And what we'll need to do is to go back and copy those variables for
those various teams.
So I'm just gonna head back over to that other class.
And from our main method we're gonna add some of these.
And so what I'll do is I'll just copy a heap of these.
And then I'll actually just remove what we need to.
Paste that in, so with Adelaide Crows.
And then we also have these other teams here, Melbourne, and we had Hawthorn and
Fremantle, so we actually had, in this case we actually had four teams.
Let's actually go ahead now and actually add those.
So, it'd be footballLeague.add(adelaideCrows),
footballLeague.add(melbourne), footballLeague.add(hawthorn),
and footballLeague.add(fremantle).
Fremantle like so, and that's actually all working perfectly as we'd expect.
But also let's go back and just copy from the other project, the baseball
league which I probably shouldn't have deleted that, so let's just copy that one.
And we come up here and we put that in there.
It's our definition.
So what we need to do is copy the BaseballPlayer class as well.
So I'm just gonna come back here, BaseballPlayer, right-click, copy, come
back to our generics challenge project, right-click and paste BaseballPlayer.
And obviously that now if we go back to league, should fix that error, so
if I go back to main, I should say.
And you've got that.
So, if we actually now try and add it, so footballLeague.add,
baseball player team, we actually get a compile time error, as we should now
because obviously the baseball player cannot be applied to the league,
because we've actually said this particular league, we're using generics.
Yes, it's a team but this is the type of FootballPlayer only.
So that's good. That's actually working.
And now to actually print out the results, we can do footballleague.showLeagueTable.
If we do that by default, we should run that.
Haven't got any results in there at the moment.
So everything's on zero.
So what we'll need to do is actually again copy through results.
We'll copy these three results.
Paste those in, let's put them in there, some results,
we'll have to actually run it again.
And we've actually got things in the right order.
Adelaide Crows on 4 points, Hawthorn, 2, Melbourne, 0 and Fremantle, 0.
So that's actually good.
So that's the basic challenge.
But what I wanna do is, before I finish, I wanna just talk a little bit more about,
go through the warnings about using raw types,
cuz it's really important to actually understand.
Well actually we don't wanna do that, and probably a little bit of code will help,
cuz again the raw types are actually allowed in order to allow the legacy code.
That's code prior to Java 1.5 or
code written before the generics was introduced to Java to allow that to work.
But you can't rely on the root, compiling it to give you an error when you use those
raw types, should actually getting a warning.
IntelliJ will also warn you, but the code will compile.
So again just as a confirmation we're gonna paste a bit of code in here.
And I just need, we'll change that to Adelaide, Adelaide.
And we need a couple of players.
We'll go back to Beckham.
Pat, we'll copy those two.
And so now I probably should have done this at the start,
copy the soccer class as well, copy that, paste it over here into this [INAUDIBLE].
Okay, go back to main again.
So again, in this example this code will actually run.
It's an unchecked warning.
So if I actually close down the run window you can probably see this
a little bit easier.
IntelliJ is gonna be telling you that this is an unchecked call.
So we're not actually defining the types as we have up here.
So the code will still actually run, but we'll get those warnings.
And notice how we can actually add literally whatever we want.
We're adding Adelaide Crows baseball team and rawTeam to this league.
And it's quite happily allowing us to do that even though of course they're all
parts of different types of sports, and you wouldn't normally wanna do that.
And this is all because we're using the raw types, not the generics.
So it's really, should hopefully really sort of hitting home to you that you wanna
be using these generics whenever you can, cuz it makes your code cleaner,
less likely to have crashes and easy to debug essentially, cuz
the errors that you're getting are gonna be there at compile time and not obviously
when the code's in production when you're trying to fix these weird bugs.
So again the real issue is the line, something like this,
where we're actually just not specifying a type for the team.
So without going into it any further, we could actually mitigate some
of these problems, to at least prevent the rawLeague declaration from compiling.
We could actually go back into our League class where it's got T extends T,
T extends Player.
We could put something like U extends Player.
T extends Team, something along those lines, if you go back and
actually have a look at main.
It's now requiring two parameters.
And we could actually put League.
We could actually force it there by putting something like FootballPlayer,
Team.
That would be one way that you're solving the problem cuz it's now actually coming
up and saying that there's a problem with the baseball team.
But still not an ideal solution.
And for that reason,
I would actually recommend you do yourself down in the challenge.
And you actually come back and that you do something
Like we did there to actually make it far easy to actually work with.
So, that's it with generics.
I hope you got a lot out of this section.
And, we'll see you in the next section, when we continue on our journey into Java.