In lecture today, we reviewed the ArrayList
class and how to be clients of that data structure. We talked about how ArrayList
is a generic class because you can create ArrayList
s to hold different types of data. In class we talked about ArrayList<String>
but you could put any object type between the <>
(e.g. ArrayList<Scanner>
, ArrayList<Random>
, even ArrayList<ArrayList<String>>
!).
This idea of generic structures should be familiar to you since we have seen this before when we first learned arrays. In Java, you can have an array of String (String[]
), array of scanners (Scanner[]
), or even an array of ints (int[]
); it's the exact same idea with slightly different syntax.
What if we wanted to make an ArrayList
that held ints? Your first guess would follow the example syntax from the arrays and say ArrayList<int>
, but this unfortunately does not work! There is a subtle difference between the generics of structures like ArrayList
and arrays: generics for structures like ArrayList
can only be Object types which means primitive types like int
are not allowed.
Do not fret, as all hope is not lost! Java provides object types for primitives that it calls "wrapper types" to navigate this limitation. The idea is instead of using int
s you will use an object type called Integer
that acts as a "wrapper" around the primitive int
value so that it can work as elements in an ArrayList
; the syntax for this would be
ArrayList<Integer> list = new ArrayList<Integer>();
Outside of creating a generic structure like ArrayList
, you don't really have to worry about the distinction of Integer
and int
because Java knows how to automatically translate between int
and Integer
wherever necessary (called auto-boxing and auto-unboxing). For example, if you wanted to add values to the list above
list.add(2); // automatically converts from int to Integer
int num = list.get(0); // automatically converts Integer return to int
// You can also do this, but no one does because it looks ugly. Don't do this unless you really need to
list.add(new Integer(2));
Integer num = list.get(0);
Java provides wrapper types for all primitives we have seen in 142 and they all have pretty intuitive names
primitive type | Wrapper type |
---|---|
int | Integer |
double | Double |
char | Character |
boolean | Boolean |
In summary, you are not able to create ArrayList<char>
, so instead you must create ArrayList<Character>
. However, you do not have to think about the wrapper types outside of specifying the types for generics structures since Java will auto-box and auto-unbox the values where necessary.
In 142, we learned the "standard traversal" for an array that uses a for
loop to iterate over the indices. As we saw in lecture, the standard traversal works for ArrayList
s too. For the following examples in this section, imagine we have the following variable declared
ArrayList<String> names = new ArrayList<String>();
names.add("Kyle");
names.add("Maria");
names.add("Chin");
names.add("Anika");
Using the same standard traversal, we could write a for
loop to access all the indices of the list
for (int i = 0; i < names.size(); i++) { // notice .size() instead of .length
String name = names.get(i);
System.out.println(name);
}
This would produce the output
Kyle
Maria
Chin
Anika
The previous approach is nice because it's familiar, but there is a downside to it since you have to worry about all the nitty-gritty details of the index variable i
. It would be nice if we could write a loop over the list and it would figure the iteration for you! That way we don't have to think about the nitty-gritty details, but let the list handle the ordering for us.
Java does provide this construct and calls it a for-each
. The syntax is as follows
for (String name : names) {
System.out.println(name);
}
This reads "for each name in the structure called names" and has the following output
Kyle
Maria
Chin
Anika
Students often are a bit confused about this since the name
variable is different on each iteration (first it's Kyle
, then Maria
, and so on). However, that aspect of the for-each loop isn't new! It's exactly what happens with for
loop and its i
variable; on the first iteration i
is 0
, then it's 1
, and so on. Essentially what is going on here is that i
variable is placed "behind the scenes" so you don't have to think about it and instead you get to work at a higher level and are just given the elements of the list.
Foreach loops are almost always preferred to for-loops when possible because they are much easier to read and can sometimes be implemented a bit faster than the standard for
loop. You can for-each
over almost every data structure we learn in this class (e.g. ArrayList
) and you can also for-each
over arrays! Unfortunately, you can't use the for-each
over String
s, so you are stuck using regular for loops there.
Try solving this array problem by using a for-each
loop.
Foreach loops unfortunately can't be used in every context. For example, you can't for-each
over strings which would be nice. For-each
loops are also known as "read-only" loops which means you aren't allowed to modify the list as you are for-each
ing. For example, if we wanted to remove all the names that have even length and tried to write
for (String name : names) {
if (name.length() % 2 == 0) {
names.remove(name);
}
}
We would get the following error
Exception in thread "main" java.util.ConcurrentModificationException
This happens because we broke the "read-only" rule of for-each
loops and tried to modify the list while we were iterating. If you want to change the list, you either have to use a for
loop or one last strategy for accessing the elements of a structure that we will learn next week.
Try solving this ArrayList
problem using the material we have discussed in this reading.
Have any feedback about this reading? Please let us know using this form.
Copyright © 2019 Hunter Schafer and Porter Jones. All rights reserved. Permission is hereby granted to students registered for University of Washington CSE 143 for use solely during Winter Quarter 2019 for purposes of the course. No other use, copying, distribution, or modification is permitted without prior written consent. Copyrights for third-party components of this work must be honored. Instructors interested in reusing these course materials should contact the authors.