Friday, April 16, 2010

Lists in Java: Sample Code

Here are some simple code examples of using some basic List abilities as described in The List in Java.

Comments about what the code is up to are included below.

This code is written to simply demonstrate a few things, as a reference. I chose to write it a bit "dirty" for the sake of keeping what it does demonstrate as clear as possible. For example it makes some assumptions about the nature of the data it is working with. In a real program, this may not be the right thing to do.

The code will generate a warning you can ignore: Note: Lister.java uses unchecked or unsafe operations.

This is a result of not doing complete checking to make sure that the Object types passed to System.out.println() are compatible, i.e., have a toString() method. It's one of the things I'm not worrying about for the sake of this short demo.

/* Playing around with Lists, in basic ways.
  We use the ArrayList class as an implementation of List,
  since at this point we're just using a List's features,
  rather than learning about building our own List-based
  class.

  -Mark Graybill, Apr. 2010
*/


import java.util.*; // include the package with List in it.

public class Lister{
  public static void main(String arg[]){

  // Create some Lists to play with.
    ArrayList lister = new ArrayList();
    ArrayList dave = new ArrayList();
    ArrayList kryten = new ArrayList();

  // Put some things in the lister List, manually.
    lister.add("The End");
    lister.add("Future Echoes");
    lister.add("Confidence and Paranoia");
    lister.add("Thanks for the Memories");

  // Print the current lister list.
    System.out.print(lister);
    System.out.println();

  /* Get a sublist from lister.
    This will get items at indices 1 and 2. Stops
    short of item 3. I.e., gets sublist from element
    1 up to, but not including, 3. */

    dave.addAll(lister.subList(1,3));

    System.out.print("Sublist elements 1 and 2: ");
    System.out.print(dave);
    System.out.println();

  // Put something in the kryten list.
    kryten.add("The Rimmer Experience");
    kryten.add("Ace");

  // See if kryten is in the lister list.
    if (lister.containsAll(kryten)){
      System.out.println("All of kryten is in lister.");
    }
    else {
      System.out.println("Items in kryten aren't in lister.");
    }

  // Do the same thing with the dave list.
    if (lister.containsAll(dave)){
      System.out.println("Items in dave are all in lister.");
    }
    else {
      System.out.println("Items in dave aren't in lister.");
    }

  // Step through the list with a for-each
    System.out.println(); // Get a blank line.
    System.out.println("Items in Lister:"); // Title the list.
    for (Object epname: lister){ // Print the list.
      System.out.println(epname);
    }

  /* Note: the above code is a little bit "dirty", in that we're counting on
    the objects we get from lister to be printable. Since we've had tight
    control over what goes in, we can get away with this. If you make a List
    that lets anything in, make sure they've all got toString() methods, or
    otherwise take care of object types. Generics are a partial solution to
    this problem (though they're less than perfect.)
  */


  // Get an iterator and use it.
    ListIterator iter = lister.listIterator();

  // Iterator starts out with the first element in List as its "next()"
    System.out.println();
    System.out.println(iter.next());

  // Doing next() has advaned our iterator in the list,
  // so if we do it again:

    System.out.println(iter.next());
  // We see we have advanced. And we advance again.

  // We can it to go through the list, use hasNext() to watch for the end.
    System.out.println("\nGoing forward:");
    while (iter.hasNext()){
      System.out.println(iter.next());
  }

  // And we can go backward:
    System.out.println("\nGoing backward:");
    while (iter.hasPrevious()){
      System.out.println(iter.previous());
    }

  // Print the element in front of "Thanks for the Memories".
    System.out.println("\nItem before \"Thanks for the Memories\" is:");
    while (iter.hasNext()){
      if ( iter.next().toString().contentEquals("Thanks for the Memories") ){
        iter.previous(); //we found it, now move back to it.
        System.out.println(iter.previous());       // Two steps to get back.
        break; // We've done it, now get out of the loop.
      }
    }

  } // end of main()
} // end of Lister


Since I'm not using generics in this code, some of the information about what's stored in the list gets lost--everything becomes an "Object". Not using generics limits the usability of a Collection quite a lot, so it's usually best to use generics as it beats writing all the code to work around the lack of known class types for data.

For example, using Java's Generics, I can declare a type for items in the list that Java will enforce:
ArrayList<String> lister = new ArrayList<String>();

In this way, I can now treat items that come out of lister as a String, too:
if (iter.next().contentEquals("Thanks for the Memories")){ ...

Watch for more about Generics in another article.
StumbleUpon