Alphabet Soup
The List
class is part of the C# System Collections Framework, which real people generally call "Collections".
We use List
as a tool to make dealing with sequences or collections of things easier. It offers us an abstraction to do away with fiddling about with arrays. We're going to contrast using List
with using arrays.
Arrays are fixed size
We can't change the size of an array once we've created it. It will never grow or shrink. This array will always have a Length
of three:
int[] threeThings = new int[3];
If I wanted to add a 4th element to this array, I would be forced to do something like this:
int[] myArray = { 1, 2, 3 };
int[] arrayTwo = new int[4];
for (int i = 0; i < arrayTwo.Length; i++)
{
arrayTwo[i] = myArray [i];
}
myArray[4] = 42;
We are forced to create a new array and assign it the values of our myArray
variable. Imagine if we needed to insert a new element in the middle? Yuck!
Lists can grow and shrink
List
is a standard class, so we create an instance of it just like any class we'd create:
List<string> giantWords = new List<string>();
giantWords.Add("fee");
giantWords.Add("fie");
giantWords.Add("foe");
Console.WriteLine(giantWords);
Console.WriteLine("my list has " + giantWords.Count + " elements");
giantWords.Add("fum");
Console.WriteLine(giantWords);
Console.WriteLine("my list has " + giantWords.Count + " elements");
I'm not even forced to specify the size! The Count
property tells me how big my list currently is.
If you run this code, you'll also see that List
also gives us a better String
representation than arrays did. (It does this in its ToString
method. All classes have one.)
Something there looks strange, though, eh?
Generic Types
The syntax for our declaration and initialization probably looks a bit funky at first:
List<string> giantWords = new List<string>();
One would read this as "a List
of Strings
named giantWords
".
List
is a generic type, List<string>
is a parameterized type, and giantWords
is an instance of parameterized type. Here, that type is String
.
What does this mean? When we declare a List
, we also declare what type of things it will hold. We can only add String
s to this List
.
Objects like any other
The way we use List
s is the same as we would use any other class. We create an instance of it, then we call methods (send messages) to ask it to modify itself or give us information.
How big is it?
We've already seen the Count
property in use. It corresponds to Length
for an array.
To check whether an array is empty, we would compare its Length
to zero:
if(myArray.Length == 0) {
Console.WriteLine("I'm empty!");
}
Do you have one of these?
If we wanted to check whether an array contained an element, we would iterate over it, checking each element:
string[] myTools = { "hammer", "shovel", "wrench" };
foreach (string tool in myTools)
{
if (tool.Equals("hammer"))
{
Console.WriteLine("I have a hammer!");
}
}
List
has a Contains
method for this:
List<string> myTools = new List<string>();
myTools.Add("hammer");
myTools.Add("shovel");
myTools.Add("wrench");
if(myTools.Contains("hammer")) {
Console.WriteLine("I have a hammer!");
}
Where is it?
If I want to know the index of an element in an array, it's a bit painful:
string[] myTools = { "hammer", "shovel", "wrench" };
for(int index = 0; index < myTools.Length; index++) {
if(myTools[index].Equals("shovel"))
{
Console.WriteLine("Shovel is element " + index);
}
}
With a List
, we have the IndexOf
method:
List<string> myTools = new List<string>();
myTools.Add("hammer");
myTools.Add("shovel");
myTools.Add("wrench");
Console.WriteLine("Shovel is element " + myTools.IndexOf("shovel"));
Look, ma! No curly brackets!
Order is important
Lists remember the order in which you Add
elements. Other types of collections don't care so much, but order is one of the intrinsic properties of a list. Try running this code, then changing the order of the Add
calls and running it again:
List<string> giantWords = new List<string>();
giantWords.Add("fee");
giantWords.Add("fie");
giantWords.Add("foe");
Console.WriteLine(myList);
Loopy again
Like arrays, a List
is iterable, so we can use the enhanced for loop with it:
List<string> giantWords = new List<string>();
giantWords.Add("fee");
giantWords.Add("fie");
giantWords.Add("foe");
foreach(string word in giantWords) {
Console.WriteLine(word + "! ");
}
More Tools
List
has a number of other useful methods. The examples assume our list was created like so:
List<string> myThings = new List<string>();
myThings.Add("this");
myThings.Add("that");
myThings.Add("the other");
Here are some other methods we can use:
method | example | what it does |
---|---|---|
Clear() |
myThings.Clear(); |
removes all the elements |
Insert(int index, string element) |
myThings.Insert(1, "foo"); |
assigns "foo" to index 1, replacing "that": "this", "foo", "the other" |
Add(int index, string element) |
myThings.Add(1, "foo"); |
inserts "foo" at index 1, shifting the others down to make room: "this", "foo", "that", "the other" |
RemoveAt(int index) |
myThings.RemoveAt(1); |
removes the element at index 1: "this", "the other" |
Remove(string element) |
myThings.Remove("that"); |
removes the value from the list: "this", "the other" |
Exploring List
s
As you move into exercises, you'll be inclined to dig into the List
class. You might not find what you expect. As part of the Collections framework, List
is just one piece of the puzzle. You'll find that some of the methods we're using aren't even in List
!
A method by any other name…
Notice the convention we're seeing with methods. It's a good one to follow when you create your own methods. Generally, a method should be doing something or giving us information, not both. It's a good practice to use verbs for methods that do things (public void Quit()), and VerbNoun for method names for methods that give us things (for example: public
int
CalculateAgeInYears()
{}
) It is also common to see methods whose names start with get
or is
that give us information.
Not all bad
When might we use an Array
rather than a List
?
Do It!
-
Create a
List
. Add five animals to your list. Print each animal in your list. -
Create a list that contains the following boolean values:
true
,false
,false
,true
,false
. Loop through your list. Based on the value of each element, print a message:true
: "Better bring an umbrella"false
: "No rain today, enjoy the sun!"
-
Create a list with the following numbers: 1, 23, 9, 77, 922, 6, 32, 63, 14, 5, then: - determine whether each of the following values is an element in the list: 23, 77, 15 - remove the following elements: 23, 922, 32, 6 - again determine whether each of the following values is an element in the list: 23, 77, 15 (Stretch: create a method so that you don't need to duplicate this work.)
-
Come up with an example of how you might use each of the methods from the "More Tools" slide.