Issue #009
September, 1996
Contents:
Comparing C/C++ and Java Part 9 - Operators
Introduction to Applet Programming Part 5 - Text Input
Performance - Fast I/O For Text Lines
COMPARING C/C++ AND JAVA PART 9 - OPERATORS
If you know C or C++, many of the operators found in Java will be
familiar. But there are also some differences worth noting.
1. Java has no unsigned data types, and so the operator >>> has been
added to support unsigned right shifting. That is, a right shift
using >> will propagate the sign, whereas a shift using >>> will zero
fill the high bits. >>>= also has been added.
The operator "instanceof" can be used to determine whether an object
is an instance of a given class, as in:
if (s instanceof String)
// do something
2. Java does not have any of the following C/C++ operators:
,
->
.*
->*
::
3. In Java "*" and "&" have no meaning for doing pointer arithmetic
or addressing, because Java has no user-visible pointers.
4. Java has no operator overloading, for example overloading [] to
provide a "smart" vector type of some sort.
5. In Java "+" can be used for String concatenation.
6. Finally, as a quick summary of Java operators, here is a table of
operators and their precedences, highest to lowest. This table is
taken from Arnold & Gosling's "The Java Programming Language", page
300:
postfix [] . (params) expr++ expr--
unary ++expr --expr +expr -expr ~ !
creation/cast new (type)expr
multiplicative * / %
additive + -
shift << >> >>>
relational < > >= <= instanceof
equality == !=
bitwise AND &
bitwise exclusive OR ^
bitwise inclusive OR |
logical AND &&
logical OR ||
conditional ?:
assignment = += -= *= /= %=
>>= <<= >>>= &= ^= |=
INTRODUCTION TO APPLET PROGRAMMING PART 5 - TEXT INPUT
In the last issue we talked about button input, where the user clicks
on a button. In this issue we'll continue our discussion of input and
discuss text input a bit, starting with low-level character input. To
illustrate what such input looks like, here is a simple applet:
import java.applet.*;
import java.awt.*;
public class text1 extends Applet {
int x = 40;
int y = 40;
public boolean keyUp(Event e, int key)
{
if ((e.modifiers & Event.CTRL_MASK) != 0) {
char buf[] = new char[2];
buf[0] = '^';
key += 0x40;
buf[1] = (char)key;
getGraphics().drawChars(buf, 0, 2, x, y);
x += getFontMetrics(getFont()).charWidth('^');
x += getFontMetrics(getFont()).charWidth(key);
x += 2;
}
else {
char buf[] = new char[1];
buf[0] = (char)key;
getGraphics().drawChars(buf, 0, 1, x, y);
x += getFontMetrics(getFont()).charWidth(key);
x++;
}
return true;
}
}
and the HTML that drives it:
Interface to Text Applet
keyUp() is a method called in response to a keyboard event. Once
inside keyUp(), we go through some machinations to determine what sort
of a key was pressed, for example whether a control key was hit. The
code in this example is incomplete but illustrative of the technique.
Once we have a key, we want to echo it in the applet window. We use
drawChars() for this. Then we need to update the X position in the
window for drawing the next character, and to do that, we use the
FontMetrics class with the current font, to determine the width of a
character that's just been drawn.
In other words, this applet simply echoes its input to the window, and
throws in a "^" in front of control characters.
There are higher-level methods for entering text, which we will look
at in future issues.
PERFORMANCE - FAST I/O FOR TEXT LINES
In issue #002 we traced through the steps involved in doing Java
character output. The Java I/O system offers flexibility in
structuring various sorts of I/O, with the possibility of adding
filtering layers and so on.
But this flexibility has a performance cost, caused in part by the
layers themselves and in part by the method call overhead. As we've
said previously, Java is a young language and it's not totally clear
how various pieces will shake out. But it's worth considering how
some common types of I/O might be speeded up.
As an example, consider text lines. These are lines of characters
ending in \n while being manipulated in a program, and ending in \r\n
or \n when residing in a disk file. \r\n is used with Microsoft
system software on PCs, while \n is used on UNIX systems.
Suppose that we wish to read and write sets of text lines
sequentially, for example, reading all the lines in a file, one after
another, or writing to a file in a similar way.
One way to do this is illustrated in the following example. We set up
our own file output buffer, and move characters from a passed-in
String object directly to the buffer. We use the low-level
FileOutputStream class to actually do the I/O; it has a write() method
that takes a vector of bytes and outputs them to a file or to standard
output.
We determine whether \r\n or just \n is needed on output, by looking
at the system properties list. JDK 1.0 running on Windows NT has an
anomaly or feature in the way that standard output is treated with
respect to line delimiters, and so if output is to standard out it's
treated differently.
This particular example, with the driver program below, runs about 5X
faster than the equivalent using System.out.print(). The code for
doing input of text lines is analogous.
import java.io.*;
class StdioOutput {
private static final int BUFSIZ = 4096;
private FileOutputStream fos;
private byte buf[] = new byte[BUFSIZ];
private int left;
private int pos;
private static boolean need_cr = false;
// figure out whether we have \r or \r\n
static {
String s = System.getProperty("line.separator");
need_cr = (s.length() >= 1 && s.charAt(0) == '\r');
}
// open a file
public StdioOutput(String fn) throws IOException
{
fos = new FileOutputStream(fn);
left = BUFSIZ;
pos = 0;
}
// open standard output
public StdioOutput() throws IOException
{
fos = new FileOutputStream(FileDescriptor.out);
left = BUFSIZ;
pos = 0;
need_cr = false;
}
// close a file
public synchronized void close() throws IOException
{
flush();
fos.close();
fos = null;
}
// flush output
public synchronized void flush() throws IOException
{
if (pos > 0)
fos.write(buf, 0, pos);
left = BUFSIZ;
pos = 0;
}
// output a character
public synchronized void putc(int c) throws IOException
{
// flush output buffer if needed
if (left <= 0)
flush();
// handle simple case
if (c != '\n' || !need_cr) {
left--;
buf[pos++] = (byte)c;
}
// handle \r\n
else {
left--;
buf[pos++] = '\r';
if (left <= 0)
flush();
left--;
buf[pos++] = '\n';
}
}
// output a line
public synchronized void putline(String s) throws IOException
{
int len = (s == null ? 0 : s.length());
// empty string
if (len < 1)
return;
// whole string will fit in buffer
if (len + 1 <= left) {
if (len >= 2) {
s.getBytes(0, len - 1, buf, pos);
pos += len - 1;
left -= len - 1;
}
putc(s.charAt(len - 1));
}
// whole string won't fit, do a character at a time
else {
for (int i = 0; i < len; i++)
putc(s.charAt(i));
}
}
}
public class testio2 {
public static void main(String args[])
{
StdioOutput fout = null;
String s;
try {
fout = new StdioOutput();
}
catch (Throwable e) {
System.err.println("* file opening error *");
}
try {
int N = 10000;
for (int i = 1; i <= N; i++)
// System.out.print("xxxxxxxxxxxxxxx\n");
fout.putline("xxxxxxxxxxxxxxx\n");
}
catch (Throwable e) {
System.err.println("*** file I/O error ***");
}
try {
fout.close();
}
catch (Throwable e) {
System.err.println("* file closing error *");
}
}
}
ACKNOWLEDGEMENTS
Thanks to Thierry Ciot, Irv Kanode, Mike Paluka, and Alan Saldanha for
help with proofreading.
SUBSCRIPTION INFORMATION / BACK ISSUES
To subscribe to the newsletter, send mail to majordomo@world.std.com
with this line as its message body:
subscribe java_letter
Back issues are available via FTP from:
rmii.com /pub2/glenm/javalett
or on the Web at:
http://www.rmii.com/~glenm
There is also a C++ newsletter. To subscribe to it, say:
subscribe c_plus_plus
using the same majordomo@world.std.com address.
-------------------------
Copyright (c) 1996 Glen McCluskey. All Rights Reserved.
This newsletter may be further distributed provided that it is copied
in its entirety, including the newsletter number at the top and the
copyright and contact information at the bottom.
Glen McCluskey & Associates
Professional Computer Consulting
Internet: glenm@glenmccl.com
Phone: (800) 722-1613 or (970) 490-2462
Fax: (970) 490-2463
FTP: rmii.com /pub2/glenm/javalett (for back issues)
Web: http://www.rmii.com/~glenm