RU beehive logo ITEC dept promo banner
ITEC 120
2008spring
ibarland,
jdymacek

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs

lect11a
primitive Wrappers; Lists
and a hint of for-each

Wrapper classes for primitives

We have seen that java has the primitive types int, long, double, boolean, and char (along with the less-precise numbers: byte, short, float). For each1 of these primitive types, Java also provides a corresponding wrapper class: Integer2, Long, Double, Boolean, and Character, (along with Byte, Short, and Float).

For example, an instance of Double is just an object which contains one lonely field -- a field of type (you guessed it) double.

// Draw picture:
double d1;
d1 = 12.3;

Double dd1;
dd1 = new Double(12.3);
Double dd2 = new Double( 12.3 );
Double dd3 = new Double( d1 );
Double dd4 = dd1;

dd1.toString()
dd1.doubleValue()
dd1.intValue()

d1 = 45.6;
dd3.doubleValue(); // Could dd3's value change, by assigning to the contents of d1?
                   // If you weren't sure, re-read lect08a—References as Values: passing arrows to functions

dd3 = dd2;

dd1 == dd3         // true or false?  Try it out!  Your picture should explain.
dd1.equals(dd3);   // true or false?  Try it out!  Your picture should explain.

dd2 == dd3         // true or false?  Try it out!  Your picture should explain.
dd2.equals(dd3);   // true or false?  Try it out!  Your picture should explain.
You can glance over the Double docs, for more methods on Doubles.

Why do entire classes even exist, when we already have the primitive types, which work just fine? Good question. The reasons why these wrapper classes exist are:

Just to keep things from looking simple (even though they are), Java, as a favor, silently converts between primitive types and the wrapper classes:

dd1 = 3.4;      // "auto-boxing"   -- same as:  dd1 = new Double(3.4);
dd1 + d1        // "auto-unboxing" -- same as:  dd1.doubleValue() + d1
dd1 + dd2       // Does this mean auto-unboxing, or string-concatenation?!?!
dd1 == dd2      // Does this compare-objects, or unbox-and-then-compare-numbers?!?!

Lists

A list is a very handy thing. Today we'll look at a built-in Java class for lists. What behavior would we like to see, from a list of doubles, which is named dubs?

This class can do all that, and more. It's called LinkedList. (Full name: java.util.LinkedList.)

One weird thing about its name: As we've seen, Java is very type-hungry. So if we make a list of doubles, it's not enough to simply say we have an object of type LinkedList; we need to announce in advance what type of data the list will hold. That is, we actually have types LinkedList<PizzaServer> or LinkedList<Treasure> or LinkedList<Double>. Think of the <> as part of the type-name.

You can look at the official documentation. LinkedList Note that the documentation is for “Class java.util.LinkedList<E>” -- that is, “a LinkedList which has elements of type E”. Really, E is a type-variable; it stands for any Java type -- a generic type.

One small glitch: LinkedLists can't actually hold doubles; they may only contain objects (not primitive types like double, int, boolean etc.).

Using Lists

To type in BlueJ's code pad (note the lack of most semicolons):

new java.util.LinkedList<Double>()      /* Create a list which contains Doubles. */
java.util.LinkedList<Double> dubs = new java.util.LinkedList<Double>();
dubs

dubs.add( new Double(5.4) )       
dubs.add( new Double(-1.2) ) 
dubs.add( new Double(Double.MAX_VALUE))   // a static field, inside class Double 
dubs.toString();

dubs.add(4.2)       /* Note the autoboxing: 4.2 is auto-rewritten new Double(4.2) */
dubs.add(0.0) 
dubs.toString()

dubs.get(2)         /* Provide an index (not a Double). */
dubs.get(0)         /* Indices start at 0  (in java, and most languages). */
dubs.get(3)         /* Evidence of auto-boxing: we added double, got back Double. */
dubs.size()         /* Ask the list how many elements it has. */
dubs.get(dubs.size()-1)     /* The last element. */
dubs.get(dubs.size())       /* Pay attention to this error message. */

dubs.remove(Double.MAX_VALUE)  /* Remove items. */
dubs.toString()

dubs.add(5.4)
dubs.add(-1.2)
dubs.add(5.4)      /* You can add multiple copies of an element. */
dubs.toString()
dubs.remove(-1.2)  /* Which one gets removed?   ... Must check documentation! */
dubs.toString()

dubs.remove( new Double(5.4) )
dubs.toString()

dubs.remove(66.6) /* Hey, this had never been in the list?! */
dubs.size()

// Sneak preview of tomorrow's lecture:
/* Add up elements of a list, with a for-each loop. */
double totalSoFar = 0.0;   // The running total -- an "accumulator" variable.
for ( Double d : dubs ) {  // "for each d in dubs, ..."
  totalSoFar = totalSoFar + d;
  }
// For-each is only appropriate when we want to handle every element exactly the same.


// To-do:
// - Augment the above code so you also accumulate the sum-of-squares
//    (or, the absolute values)
// - Augment the above code so you also accumulate a String, with each
//    number separated by a space, with angle-brackets on each side:
//      "< 5.4 -1.2 4.2 0.0 5.4 >"

Lists aren't at all specific to Doubles; they can hold any sort of object at all. Note that technically, the list holds a reference to objects. Let's draw pictures on the board:

// ======================================

Dog d1 = new Dog( "lassie", 15 )
Dog d2 = new Dog( "fido", 3 )
Dog d3 = new Dog( "phydeaux", 5 )

java.util.LinkedList<Dog> pound = new java.util.LinkedList<Dog>();

pound.add( d1 )
pound.add( d2 )
pound.add( d3 )
pound.toString()
pound.contains( d1 )
pound.contains( new Dog( "fido", 3 ) )   /* .equals, or == ?  See docs. */
pound.contains( "fido" )
pound.remove( new Dog( "fido", 3 ) )     /* .equals, or == ?  See docs. */
pound.toString()
pound.remove( d1 )
pound.toString()

a Blah is not a List-of-Blah

A number is not a list of numbers; a Dog is not a LinkedList<Dog>. Think of the list as a bag. The bag might even be empty. It is a common confusion for people to declare a field to be (say) a Treasure, when really what they want to keep track of is a LinkedList<Treasure>. Or, to ask a LinkedList<Dog> to speak(), even though that's a behavior of things in the bag, not a behavior of the bag itself. (Use a for-each loop to work with each object inside the bag.)

a bag of items

Which of the following method calls make sense?

  1. pound.getSound()
  2. d1.get(1)
  3. pound.get(1)
  4. d1.get(1)
  5. Dog d = pound.get(1) followed by d.getSound()
  6. (pound.get(1)).getSound()

Packages

Why such a long unwieldy name like “java.util.LinkedList”? This is the class's full name. There are more long names: we've seen in documentation that String's full name is actually “java.lang.String”.

The reason for having full names is to reduce namespace collisions -- having two different programmers working on different parts of a program accidentally choose the same name for their own class. For example, we've written our own class Date, but there are also two other classes named Date which are part of the standard java libraries. java.util.Date and java.sql.Date. And other programmers might have further classes (for a singles-website, or a mideastern fruit-importing service) with that same name. And we certainly want to be able to use all these classes in a single program. Using a class's full name makes it clear, which class is being talked about!

A package is a family of classes. The two most common packages are:

Note that BlueJ's and Eclipse's “project”s (which often contain several related classes) correspond to Java's “package”s.

Optional: To save typing: import

The full name “java.util.LinkedList<SomeType>” is nice, but a bit long and unwieldy. It would be nice if we could avoid having to type the full name, and instead just type LinkedList<SomeType>. As a matter of fact, this is possible. At the top of your file, before the class declaration, you can include the following statement just once:

import java.util.LinkedList;      /* Note: no <SomeType> allowed! */

class SomeClassName {
  
  }
This import statement tells Java “whenever you see LinkedList in this file, I'm talking about java.util.LinkedList”.

import is a shallow concept -- it only helps you avoid typing.
If you're ever confused by import, don't use it -- just type out a class's full name.

We won't talk about making your own packages for large projects in this class; it involves setting the “classpath” in your IDE and making a directory structure mirroring your package hierarchy. (Note that each BlueJ window is looking at a single package.) In order to make sure your full-name doesn't conflict with other people in the world, a common convention is to mirror a domain-name you own -- for example, com.sun.javax.swing.JList.

Even though you don't type it yourself, Java re-writes every file to include the line import java.lang.* as the first line. This imports every class from the package java.lang, and this behind-the-scenes rewriting is why we've been able to use the short names of java.lang.String, java.lang.Math, java.lang.Double, ,etc.. Although you can use the * form of import yourself, I recommend spelling out exactly all your imports, especially when only importing two or three classes4


1There is also class Void, which technically isn't a wrapper class because there aren't any void values to wrap!      

2Integer and Character are the two wrapper classes whose name isn't quite just the capitalized version of its corresponding primitive.      

3A minor lie: it really rewrites it as Double.toString(3.0) + " blind mice", but we haven't yet discussed static methods.
And actually, I'm not sure whether the java compiler is required (or allowed or disallowed) to optimize early, and convert the literal 3.0 into a String at compile time (perhaps even doing the concatenation right then, too?).      

4 In later semesters, when writing GUIs, it's okay to import java.swingx.*, because there are commonly 30-40 classes used from that package (JFrame, JTextArea, JMenu, JList, JButton, ButtonGroup, etc.). Note how many (but not all) are named starting with a “J”, a good way to remind readers that these classes are all from javax.swing even if an import statement would otherwise obscure that fact.      

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs


©2008, Ian Barland, Radford University
Last modified 2008.Jan.24 (Thu)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme