Java Idioms

Java Idioms

Parsing text file using StreamTokenizer



    BufferedReader br = new BufferedReader(new FileReader("file"));
    StreamTokenizer st = new StreamTokenizer(br);
    st.resetSyntax();
    // set the syntax to read -9.0123E+5 as a single token
    st.whitespaceChars((int)'\u0000',(int)'\u0020');
    st.wordChars((int)'.',(int)'.');
    st.wordChars((int)'-',(int)'-');
    st.wordChars((int)'+',(int)'+');
    st.wordChars((int)'0',(int)'9');
    st.wordChars((int)'E',(int)'E');

    int stn = st.nextToken(); zliberror.assert(stn == StreamTokenizer.TT_WORD);
    stn = st.nextToken();
    while(stn != StreamTokenizer.TT_EOF)
    {
        String tag = st.sval;
	stn = st.nextToken();
	
	float val = (float)Double.parseDouble(st.sval);
	stn = st.nextToken();
	...
    }

    br.close();

Write text file



      // filewriter is the basic text output class
      // passing through a bufferedwriter buffers requests, faster
      // printwriter adds ability to print by lines
      PrintWriter fout =
	new PrintWriter(new BufferedWriter(new FileWriter("filename")));

      fout.print("abc");
      fout.println("...");

      fout.close();


Write binary data using ObjectStream



ObjectStream reads/writes binary data in the java-standard order,
so you can write a binary file on e.g. Sun or Mac and read on Intel
without byteswapping in your program.

Example adapted from
http://java.sun.com/j2se/1.4/docs/api/java/io/ObjectInputStream.html

	FileOutputStream ostream = new FileOutputStream("t.tmp");
	// faster:
	//   BufferedOutputStream ostream 
	//    = new BufferedOutputStream(new FileOutputStream("t.tmp"));
	ObjectOutputStream p = new ObjectOutputStream(ostream);

	p.writeInt(12345);
	p.writeDouble(3.33);
	p.writeObject("Today");
	p.writeObject(new Date());

	p.flush();
	ostream.close();

---------------- 

	FileInputStream istream = new FileInputStream("t.tmp");
	ObjectInputStream p = new ObjectInputStream(istream);

	int i = p.readInt();
	double d = p.readDouble();
	String today = (String)p.readObject();
	Date date = (Date)p.readObject();

	istream.close();


Read/Write raw binary data using DataInputStream.



This should not be needed except for special purposes,
ObjectInput/OutputStream is easier.

  DataInputStream di =
    new DataInputStream(new BufferedInputStream(new FileInputStream("in.dat")));
  DataOutputStream do =
    new DataOutputStream(new BufferedOutputStream(new FileOutputStream("out.dat")));

  public static int readIntIntel(DataInputStream di)
    throws IOException
  {
    byte a = di.readByte();
    byte b = di.readByte();
    byte c = di.readByte();
    byte d = di.readByte();

    return ( ((d&0xff) << 24) | ((c&0xff) << 16) |
	     ((b&0xff) << 8 ) | (a&0xff) );
  }

  public static void writeIntIntel(DataOutputStream dos, int i)
    throws IOException
  {
    byte a = (byte)(i & 0xff);
    byte b = (byte)((i >>> 8) & 0xff);
    byte c = (byte)((i >>> 16) & 0xff);
    byte d = (byte)((i >>> 24) & 0xff);

    dos.write(a);
    dos.write(b);
    dos.write(c);
    dos.write(d);
  }

Use buffered I/O for speed in writing large files
(this is like the difference between read, fread in C):

 InputStream f = new BufferedInputStream(new FileInputStream("c:xx.pic"));
  ObjectInputStream f
   = new ObjectInputStream(new BufferedInputStream(new FileInputStream(...)));
  Reader f = new BufferedInputReader(new FileReader("..."));

  same for fileoutput:
    OutputStream f = new BufferedOutputStream(new FileOutputStream(...

 

Serialization


There is a commandline program 'serialver' that is part of the jdk,
run this on a serialized class and it prints out a magic number.
Example, Nurb.class is serializable,

   serialver Nurb
prints
   Nurb:    static final long serialVersionUID = -5821547843414617226L;

then add this variable to the java file and the serial version
will remain the same.  I expect that you can pick any number
rather than running the serialver program.  And of course
you should change the serialver if class members are added or
changed.


Reflection

Print the type of an object:
  Class c = x.getClass();
  String n = c.getName();


Matrix



Two free matrix libraries (that include e.g. svd) are Jama and JNL.  
Jama provides source, but I found it to be slower than JNL,
because it uses an abstraction rather than java arrays for the matrix
accessing.

JNL routines are in the package VisualNumerics.math.*.
JNL has been superceeded by a commercial product, 
but the original version is available for download at 
http://www.vni.com/products/imsl/jnl/download/

The JNL docs are on the web in various places e.g.,
http://www.physics.orst.edu/~rubin/COURSES/Handouts/JNL/api/Package-VisualNumerics.math.html



idioms


  public double[] getPivot() { return new double[]{_pivotX,_pivotY} };

import java.text.NumberFormat;

  static NumberFormat _nf;
  static {
    _nf = NumberFormat.getInstance();
    _nf.setMinimumFractionDigits(3);
    _nf.setMaximumFractionDigits(3);
    _nf.setMinimumIntegerDigits(3);
    _nf.setMaximumIntegerDigits(3);
  }
  System.out.println(_nf.format(d) + " "); ...



bufferedimage


      BufferedImage image = ImageIO.read(new File(cmdline[0]));
      int xres = image.getWidth();
      int yres = image.getHeight();
      printInfo(image);

      // or create a new image from scratch:
      //BufferedImage image
      //    = new BufferedImage(xres, yres, BufferedImage.TYPE_INT_ARGB);

      // per-pixel access (slowest)
      int xloc = xres/2;
      int yloc = yres/2;
      {
	int pv = image.getRGB(xloc, yloc);
	int r = (pv >> 16) & 0xff;
	int g = (pv >> 8) & 0xff;
	int b = pv & 0xff;
	r = 0;	// zero the r
	pv = (255<<24)|(r<<16)|(g<<8)|b;	// ARGB is default
	image.setRGB(xloc, yloc, pv);
      }

      // medium speed: go through the WritableRaster api 
      WritableRaster wr = image.getRaster();
      // make a red line going right from the center
      for( int i = 1; i < 5; i++ ) 
	wr.setSample(xloc+i, yloc, 0, 255);

      // fastest: access the pixels directly
      DataBuffer db = (DataBuffer)wr.getDataBuffer();
      if (db.getDataType() == DataBuffer.TYPE_INT) {
	DataBufferInt dbi = (DataBufferInt)db;
	int[] pixels = dbi.getData();
	if (pixels.length != (xres*yres*3))  error("data is not rgb");

	for( int iy = 0; iy < yres; iy++ ) {
	  for( int ix = 0; ix < xres; ix++ ) {
	    int off = iy*xres + ix;
	    int pixel = pixels[off];
	    int r = (pixel>>16) & 0xff;
	    int g = (pixel>>8) & 0xff;
	    int b = pixel & 0xff;
	    int avg = (r+g+b)/3;
	    pixel = (0xff<<24)|(r<<16)|(g<<8)|b;
	    pixels[off] = (byte)pixel;
	  }
	}
      }

      // data accessed as array of unsigned bytes,
      // but java byte type is always signed, so some fussy conversion here
      else if (db.getDataType() == DataBuffer.TYPE_BYTE) {
	DataBufferByte dbi = (DataBufferByte)db;
	byte[] pixels = dbi.getData();
	if (pixels.length != (xres*yres*3))  error("data is not rgb");

	if (image.getType() == TYPE_3BYTE_BGR) {
	  for( int iy = 0; iy < yres; iy++ ) {
	    for( int ix = 0; ix < xres; ix++ ) {
	      int off = 3*(iy*xres + ix);
	      int b = pixels[off+0];  if (b < 0) b += 255;
	      int g = pixels[off+1];  if (g < 0) g += 255;
	      int r = pixels[off+1];  if (r < 0) r += 255;  // fix signed issue
	      r = (r+g+b)/3;		// r,g to luminance, zero blue
	      g = r;
	      b = 0;
	      //r = 0;
	      pixels[off+0] = (byte)((b > 127) ? (b - 256) : b);
	      pixels[off+1] = (byte)((g > 127) ? (g - 256) : g);
	      pixels[off+2]   = (byte)((r > 127) ? (r - 256) : r);
	    }
	  }
	}
	else {
	  error("cannot handle this image type");
	}
      }


      Graphics2D g = (Graphics2D)image.getGraphics();


      ImageIO.write( image, "jpg", new File( "output.jpg" ) );
      System.exit(0);


Package java program into a single file:



    jar cvf demo.jar *.class

to put all the class files into a single .jar.  Then can run
  java -jar demo.jar MyProgram ...

Also you can make the program run by double-clicking with the mouse
like a regular mac/windows program if it has no necessary 
commandline arguments.
To do this, make a file 'manif' that has these two lines:
        Manifest-Version: 1.0
        Main-Class: MyProgram
(replace 'MyProgram' with the name of the main class).  
Then do
   jar cmvf manif demo.jar *.class
    
and the .jar can be double-clicked.


IBM JDK Download:



1.3.0 for windows
http://www7b.boulder.ibm.com/wsdd/wspvtdevkit-info.html
1.3.1 for linux
https://www6.software.ibm.com/dl/lxdk/lxdk-p