Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Wrapper Types

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 ArrayLists 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 ints 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.

Looping through Lists

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 ArrayLists 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");

For loop

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

Foreach loop

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 Strings, so you are stuck using regular for loops there.

Self-check

Try solving this array problem by using a for-each loop.

Limitations of Foreach 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-eaching. 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.

Self-check

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.