RU beehive logo ITEC Department logo
ITEC 120
2007spring
ibarland,
jpittges

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs

lect10b
Lists and for-each
lect10b

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()


/* 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 >"


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

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.)

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.

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 classes1

optional:

Consider the statement “System.err.println("uh-oh")”. This is not a package name. Instead, System is a class (inside the package java.lang), err is a (static) field inside that class of type java.io.PrintStream and println is a PrintStream method. (Note: We haven't discussed static fields yet.)

So Java actually has three distinct meanings for “.”: “java.lang.System.err.println("uh-oh")” actually involves a (full) class name, accessing a (static) field in the class, and a method-call. All three of these have something to do with hierarchical organization, but for a language which often spells out its long names, it's odd that these concepts all use the same one-character operator. (Some languages might use different names for these three different concepts, and/or enforce the use of a getter for the field err.)

Reading: The book's Chapter 4 is a class which is a thin wrapper around java.util.ArrayList. The usual terminology is that the book's address book delegates (most of) its work to the underlying List. In fact, the only way in which the book's class is at all different from the underlying List is that it checks for valid indices when adding or removing.

prof-todo:Ian: double-check if there are any other differences.

Wherever the book uses ArrayList, we'll LinkedList instead.

heads-up: ArrayList is a list. It is not an array (a different data structure which we'll talk about in upcoming weeks).
(These two classes have exactly the same methods -- they only differ in terms of their performance, because they happen to have different underlying implementations. These performance differences only come into play when using lists with millions of items, or making tens of thousands accesses on lists containing hundreds of items. Until you aren't meeting those criteria, you don't need to worry about the performance differences.)
heads-up: Next semester, in Data Structures (ITEC220), you'll examine the differences between the implementations. You might even write your own version of one or both of these classes. Confusingly, they might use the same name as the standard Java class. In that case, don't confuse LinkedList in the package java.util with the LinkedList you'll be writing in your own project/package.


1 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.      

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs


©2007, Ian Barland, Radford University
Last modified 2007.Aug.27 (Mon)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme