Copy Link
Add to Bookmark
Report

Java Newsletter by Glen McCluskey - Issue 9

eZine's profile picture
Published in 
Java Newsletter
 · 2 years ago

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:

        <html> 

<head>

<title>Interface to Text Applet</title>

</head>

<body>

<applet code="text1.class" width=350 height=125></applet>

</body>

</html>


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

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT