Showing posts with label collection. Show all posts
Showing posts with label collection. Show all posts

Wednesday, March 21, 2012

Java Introspection and Using Collections without Generics

In my prior article on Generics we looked at how to use Generics to associate at type with data stored in a Collection.

You might wonder why would anyone want to store information in a Collection without its type being preserved. Well, it's possible that you'd want to store many Objects of different types in one collection. In that case, the only parent those types might have in common is java.lang.Object. So using a Generic won't do you any good.

But, once you pull that data back out of the Collection, how do you find out what it was?

Fortunately, the object itself has that information stored with it.

There are two easy ways to find out what it is. instanceof can test if it is a specific type of Object:

if (anObject instanceof String) { aString = (String)anObject); }


You can also have an Object tell you its type:

Class myClass = anObject.getClass();

or

String myClassName = anObject.getClass().getName();


A look at the documentation for Object and Class gives all sorts of useful methods for dealing with classes of data objects in Java.

Here's some sample code:

import java.util.*;

public class NoGenerics2{
// This is an example of using introspection
// to determine types of Objects stored in a
// Collection without a Generic declaration.

public static void main(String[] arg){
ArrayList myList = new ArrayList(); // No Generic declaration.
String myString="Boss Moss";
String yourString="Snorkledorf";

// put the strings into the List
myList.add(myString);
myList.add(yourString);

for (Object anObject: myList){
System.out.println(anObject.getClass().getName());
if (anObject instanceof String){
String aString = (String)anObject;
}
else{
System.out.println("Not a String, Sheriff!");
}
}
}
}
StumbleUpon

Wednesday, March 7, 2012

Generics in Java

Generics are an oddly-named thing in Java that associate objects stored in a Collection with a particular type. Let's take a look at a piece of code that uses a Collection to store some Strings. It uses an ArrayList. Here's the code:


import java.util.*;
public class NoGenerics{
// This is an example of what happens
// when you don't declare a class
// for a Collection using Generics.
// It won't compile!

public static void main(String[] arg){
// No Generic declaration.
ArrayList myList = new ArrayList();
String myString="Boss Moss";
String yourString="Snorkledorf";

// put the strings into the ArrayList
myList.add(myString);
myList.add(yourString);

for (String aString: myList){
// We can't do String methods on the items from myList.
if (aString.startsWith("Boss")){
System.out.println(aString + ":");
System.out.println("Make sure you spell it right!");
}
else{
System.out.println(aString + ":");
System.out.println("I am so pretty!");
}
}
}
}

What happens here to upset javac is that once the String is placed in the ArrayList, its type is lost, and it is known only as an Object. To be treated as a String again, it would have to be cast as a String. If any errors are made in casting the data, the program will fail at runtime, not when it is being compiled--when the programmer has it in their hands to fix it.

Feel free to take the above code and try to compile it to see the error you'll get. It is instructive.



The Fix for Lost Types

In Java version 1.5 "Generics" were added to fix this. Now Collections like the ArrayList can associate a type with the data put in them, and the compiler can do type checking. Here's the above code, with the Generic declaration added:


import java.util.*;

public class Generics{
// This is an example of what happens
// when you declare a data class
// for a Collection using Generics.

public static void main(String[] arg){
// Generic declaration.
ArrayList myList = new ArrayList();
String myString="Boss Moss";
String yourString="Snorkledorf";

// put the strings into the ArrayList
myList.add(myString);
myList.add(yourString);

for (String aString: myList){
// Now when we can do String methods on the List items.
if (aString.startsWith("Boss")){
System.out.println(aString + ":");
System.out.println("Make sure you spell it right!");
}
else{
System.out.println(aString + ":");
System.out.println("I am so pretty!");
}
}
}
}

Generics = Typed Collections
So if you are going to use a collection on Objects all of a specific type (rather than mixing and matching), put on a Generic declaration.
StumbleUpon

Friday, May 13, 2011

A Java CSV File Reader

One of the most common types of data file is a CSV (Comma Separated Value) file. They can be exported by many popular applications, notable spreadsheet programs like Excel and Numbers. They are easy to read into your Java programs once you know how.

Reading the file is as simple as reading a text file. The file has to be opened, a BufferedReader object is created to read the data in a line at a time.

Once a line of data has been read, we make sure that it's not null, or empty. If it is, we've hit the end of the file and there's no more data to read. If it isn't, we then use the split() method that's a member of Java's String object. This will split a string into an array of Strings using a delimiter that we give it.

The delimiter for a CSV file is a comma, of course. Once we've split() the string, we have all the element in an Array from which our Java programs can use the data. For this example, I just use a for loop to print out the data, but I could just as well sort on the values of one of the cells, or whatever I need to do with it in my program.

The Steps

  1. Open the file with a BufferedReader object to read it a line at a time.

  2. Check to see if we've got actual data to make sure we haven't finished the file.

  3. Split the line we read into an Array of String using String.split()

  4. Use our data.


The Program
// CSVRead.java
//Reads a Comma Separated Value file and prints its contents.


import java.io.*;
import java.util.Arrays;

public class CSVRead{

public static void main(String[] arg) throws Exception {

BufferedReader CSVFile =
new BufferedReader(new FileReader("Example.csv"));

String dataRow = CSVFile.readLine(); // Read first line.
// The while checks to see if the data is null. If
// it is, we've hit the end of the file. If not,
// process the data.


while (dataRow != null){
String[] dataArray = dataRow.split(",");
for (String item:dataArray) {
System.out.print(item + "\t");
}
System.out.println(); // Print the data line.
dataRow = CSVFile.readLine(); // Read next line of data.
}
// Close the file once all data has been read.
CSVFile.close();

// End the printout with a blank line.
System.out.println();

} //main()
} // CSVRead


Downloads

This program, and an example CSV file to use it with (a section of a spreadsheed I use to keep track of my integrated circuits) are available at my code archive.

Writing to CSV Files with Java

Writing to a CSV file is as simple as writing a text file. In this case, we write a comma between each field, and a newline at the end of each record.

Give it a try, starting with TextSave.java, modify it appropriately, then see what your favorite spreadsheet program thinks of the results.
StumbleUpon

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

Tuesday, April 13, 2010

The List in Java

A Java List is a way for keeping track of things in the order you put them in. They are part of the Collections framework in Java, in other words, they are a kind on Collection. Collections all share some abilities, and can easily be converted from one kind of Collection to another.

List is an Interface, which means that it is not a Class, but a standard that you can make a class adhere to. By making a class a List, and implementing at least the required methods of a List, you have the abilities of a List, as if it were a class.
Make sure you have the right List when you look it up.
This is the one you want. The List class from the java.awt package is something different.


Lists are used to keep a list of objects. This seems obvious, but there are lots of ways of collecting up a number of objects in Java, including sets, arrays, different types of lists like linked lists, and maps. Each has its own characteristics. A List is good for sets of objects where you don't know how many objects there might be, where you want the objects kept in the order you put them in, and where you want to be able add objects to the list or remove them. Objects can be added to or removed from Lists en masse. Lists can also be tested against other collections to see if they include all the objects in that list, or none of them.
  • Lists start at zero and go up to the number of objects in them, minus one.

  • You can determine if a List is empty (true or false) using isEmpty()

  • You can get the size of a List using size()

  • You can access an item in a List by its index using get().

  • Items can be added to the end of a List with add(), or

  • You can insert an object into a particular place in a List, moving the rest "down" with add(index, element).

  • You can put one object repeatedly in a List (unlike a Set).

  • You can find the first instance of an object in a List (getting its index) with indexOf(), or

  • You can get the last instance of an object (getting its index) with lastIndexOf()

  • You can delete an object from a List with remove().

  • You can append all the members of some other Collection to a List at once with addAll().

  • You can delete all members of some other Collection from a List all at once with removeAll().

  • You can delete all members that are not in another Collection with retainAll()

  • You can see if all members of a Collection are present in a List with containsAll().

  • You can clear the list out with clear()

  • or keep a section of it with subList().

Some things you can do with a List.

See Lists in Java: Sample Code for examples of using a List.

Many programmers first encounter the List when they run into a method for something they're working with that returns a List. If you're not used to using Collections, this will seem to add an extra layer of complexity. However, it lets the method deal with giving you a group of objects as its return value, without it having to know how many things it might be returning in advance, or what the classes of those objects will be.

For example, the Greenfoot framework for Java makes copious use of the List. If you have a World in Greenfoot that contains a bunch of Robot objects, like this:
A World That Contains a Bunch of Robots

You can do something to all the Robots by calling a World method that returns a List of the Robots.

Using the List


Once you've got the List, you can then do something to all the Robots by iterating through the list and calling the appropriate method for each Robot. To do this, we use the List's ability to provide us with an iterator to move between its elements one by one once we get the List. In this case, it's done automatically by Java's for-each loop:
List<robot> robots = getWorld().getObjects(Robot.class); // get a List of Robots

for (Robot thisRobot : robots) {
thisRobot.turnLeft();
}

This goes through and calls the turnLeft() method of each robot returned in the list.

To explicitly get an iterator from a List, we can use the listIterator() method of the List:
ListIterator robotIterator = robots.listIterator();

This gives us a list iterator that starts at zero and progresses through the list as we call the iterator's next() method, after checking to see that there is a next item using hasNext(), of course. See ListIterator to see what you can do with the iterator.

We can also get an iterator that starts at a particular position in the list. For example, let's say we want to skip our way past the first 100 elements:
ListIterator robotIterator = robots.listIterator(100);


The normal use of a List is as a simple list of objects to iterate through, as shown. The use of the additional features of the List make it a far more powerful construct, however. In general, it's very useful to learn as much about Collections in Java as possible, as they are the most generally useful data structures for dealing with groups of objects.

See Lists in Java: Sample Code for examples of using a List.
StumbleUpon

Sunday, July 6, 2008

Parens and Brackets and Braces, Oh My!

If you paid attention in English class when they were discussing the use of parentheses, curly braces, square brackets and so on I'm afraid it won't do you much good in Java. Java has a specific use for each of these, and it definitely pays to get then sorted out.

Knowing the names for each of the symbols is a good starting point:

{ } are curly braces.
( ) are parentheses (one is called a parenthesis.) Parens or paren for short.
[ ] are square brackets.
< > are called angle brackets. They're the same characters as the less than and greater than signs.

The first one of any pair is called the "opening" item; opening curly brace, opening parenthesis, etc. The second of a pair is called the "closing" item; closing square bracket, closing paren, and so on.

{ }
We discussed curly braces in Code Blocks, and mentioned briefly that they are a form of divider in Java in Those Pesky Semicolons. Curly braces mark the start and end of a code block.

Hold the phone! There's another use of curly braces. They can also be used to enclose a list that is used as an array initializer. For example:
int nums[] = {1, 2, 3};
This line declares an array named nums[] and initializes its first three elements to values 1, 2, and 3.

( )
Parentheses happen a lot in Java. They mark the start and end of the parameter list of a method. This includes both constructor methods and instance methods. The parameter list contains the information that is passed to the method to let the method do its job. If the method doesn't need any information, the parens are still there, there's just nothing between them: println(). A pair of parens at the end of a name is an easy way of identifying a method.

[ ]
Square brackets are used to enclose the "indexing expression" of an array. If you see square brackets, it's an array.

< >
When <> are not playing the part of "less than" and "greater than" they enclose the indexing expression of a collection. Collections are like arrays but considerably more flexible in the things they can do. Consider them as a sort of "super array."

There you are. Now you're prepared to punctuate your Java programs with the best of them, and hopefully you'll be able to read Java programs more easily. If you get into a dispute with your English teacher over these symbols, though, you're on your own!
StumbleUpon