Академический Документы
Профессиональный Документы
Культура Документы
T E C H
T I P S
TIPS, TECHNIQUES, AND SAMPLE CODE
}
The demo initializes an array of integers, and then calls
Arrays.sort to sort the array in ascending order.
In a similar way, you can do binary searching on a sorted array:
import java.util.Arrays;
public class ArrayDemo2 {
public static void main(String args[]) {
int vec[] = {-5, 19, 23, 37, 47, 56};
int slot = Arrays.binarySearch(vec, 35);
slot = -(slot + 1);
System.out.println("insertion point = " + slot);
}
}
There's one tricky aspect of this particular program. If the
binary search fails to find the requested element in the array,
it returns:
-(insertion point) - 1
The demo program calls the search method with an argument of 35,
which is not in the array. The method returns a value of -4. If
the value -4 is incremented and then negated, the result is 3;
this is the point at which 35 would be inserted into the array.
In other words, the values -5, 19, and 23 occupy locations 0, 1,
and 2 in the array. The value 35 therefore belongs at index 3,
with the values 37, 47, and 56 pushed down. The search method
does not actually insert 35 into the array, but just indicates
where it should go.
Beyond sorting and searching, what else can you do with
primitive arrays? Another useful technique is to take an array
of primitive type and turn it into an equivalent Object array.
Here each corresponding element is a wrapped version of the
primitive element. So, for example, a value 37 in the primitive
array becomes Integer(37) in the wrapped array.
Here's how you can do this:
import java.util.Arrays;
import java.lang.reflect.Array;
public class ArrayDemo3 {
// if input is a single-dimension primitive array,
// return a new array consisting of wrapped elements,
// else just return input argument
public static Object toArray(Object vec) {
// if null, return
if (vec == null) {
return vec;
}
import java.util.List;
public class ArrayDemo4 {
public static void main(String args[]) {
Object vec[] = {new Integer(37), new Integer(47)};
List lst = Arrays.asList(vec);
lst.set(1, new Integer(57));
for (int i = 0; i < vec.length; i++) {
System.out.println(vec[i]);
}
}
}
In this program, vec is an Object array containing Integer(37)
and Integer(47) objects. Then Arrays.asList is called. It returns
a collection (of interface type List), with the array as the
backing storage for the collection. In other words, a collection
like ArrayList has within it some type of storage to store
collection elements. In this example, the storage that is used is
the passed-in array argument to Arrays.asList. This means that
changes made by collection methods (such as set), are reflected
in the underlying array.
Changing the element at index 1 in the collection causes the
underlying array to change, and the output of running the program
is:
37
57
So if you have an Object array, you can use collection features
with it; the array itself serves as the underlying storage.
It's also possible to take a collection and convert it to an
Object array, by saying:
Object vec[] = lst.toArray();
For further information, see sections 11.2.9 Arrays, 16.6 List,
and 16.9 The Arrays Utility Class in "The Java Programming
Language Third Edition" by Arnold, Gosling, and Holmes
(http://java.sun.com/docs/books/javaprog/thirdedition/).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JAVA I/O REDIRECTION
If you've worked with UNIX or Windows shells (command processors)
very much, you've probably used I/O redirection operators such as
this:
$ command >outfile
This usage says to run a command, and direct its standard output
(such as that written by System.out.println) to the specified file
instead of to the console or screen.
This feature is quite useful. However it's possible to achieve the
same objective inside of a Java application, without relying on
a shell. Typically, if you're using a programming style that relies
on standard input and output (as the UNIX shell and utility programs
do), you don't need or want to redirect I/O from inside a program.
But sometimes there are exceptions to this rule. Let's look at a
couple of examples.
The first example redirects standard output to a file:
import java.io.*;
public class RedirectDemo1 {
public static void main(String args[]) throws IOException {
// set up a PrintStream pointing at a file
FileOutputStream fos =
new FileOutputStream("out.txt");
BufferedOutputStream bos =
new BufferedOutputStream(fos, 1024);
PrintStream ps =
new PrintStream(bos, false);
// redirect System.out to it
System.setOut(ps);
// do some output
System.out.println("This is a test\u4321");
int n = 37;
System.out.println("The square of " + n +
" is " + (n * n));
ps.close();
}
}
Standard output (System.out) is a reference to an object of type
PrintStream. To redirect output, an object of this type is
created, representing a file or other output stream (such as
a network connection). Then System.setOut is called to change
the System.out reference.
As a point of interest, the JDK 1.3 implementation of
java.lang.System has internal code of this form:
FileOutputStream fdOut =
new FileOutputStream(FileDescriptor.out);
setOut0(new PrintStream(
new BufferedOutputStream(fdOut, 128), true));
This code is used to initialize System.out. So, by default,
System.out is a PrintStream. The PrintStream represents a special
FileOutputStream file created from FileDescriptor.out, with
a 128-byte buffer, and with autoflush set to true. Autoflush means
that output is flushed on new line characters and when byte
vectors are written. When output is redirected as in the example
above, System.out is changed to reference the new PrintStream
object that was created and passed to System.setOut.
There are a couple of issues related to the RedirectDemo1 program.
One is that PrintStream converts characters to bytes using the
bw.close();
// read back the string and check
FileInputStream fis =
new FileInputStream("out.txt");
InputStreamReader isr =
new InputStreamReader(fis, "UTF-8");
BufferedReader br =
new BufferedReader(isr);
String s1 = br.readLine();
String s2 = br.readLine();
br.close();
String linesep = System.getProperty("line.separator");
if (!str.equals(s1 + linesep + s2 + linesep))
System.err.println("equals check failed");
}
}
The first part of the example sets up a PrintWriter object layered
on top of a StringWriter. PrintWriter is similar to PrintStream,
but operates on characters instead of byte streams. StringWriter
is used to accumulate characters into a dynamic internal buffer
for later retrieval into a String or StringBuffer.
After the output is written to the StringWriter, the accumulated
string is retrieved. The string is then written to a file using
OutputStreamWriter and the UTF-8 encoding. This encoding is
supported in all Java implementations. It encodes Java characters
in the range '\u0001' through '\u007f' as one byte; other
characters are encoded as two or three bytes.
Finally, the string is read back from the file, again using the
UTF-8 encoding. The string is then compared to the original string.
The original string had two line separators in it, and so it is
read back as two strings. The line separators are added to build up
one string for comparison.
Note that you can also redirect input from a file or string, using
classes such as StringReader.
Further reading: sections 9.7.1 Character Encoding, 15.4.7
String Character Streams, 15.4.8 Print Streams, and 18.1.1
Standard I/O Streams in "The Java Programming Language Third
Edition" by Arnold, Gosling, and Holmes
(http://java.sun.com/docs/books/javaprog/thirdedition/).
. . . . . . . . . . . . . . . . . . . . . . .
- NOTE
The names on the JDC mailing lists are used for internal Sun
Microsystems(tm) purposes only. To remove your name from a JDC
mailing list, see Subscribe/Unsubscribe below.
- FEEDBACK
Comments? Send your feedback on the JDC Tech Tips to:
jdc-webmaster@sun.com
- SUBSCRIBE/UNSUBSCRIBE
The JDC Tech Tips are sent to you because you elected to subscribe.
To unsubscribe from this and any other JDC Email, select
"Subscribe to free JDC newsletters" on the JDC front page. This
displays the Subscriptions page, where you can change the current
selections.
You need to be a JDC member to subscribe to the Tech Tips. To
become a JDC member, go to:
http://java.sun.com/jdc/
To subscribe to the Tech Tips and other JDC Email, select
"Subscribe to free JDC newsletters" on the JDC front page.
- ARCHIVES
You'll find the JDC Tech Tips archives at:
http://developer.java.sun.com/developer/TechTips/index.html
- COPYRIGHT
Copyright 2000 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.
This document is protected by copyright. For more information, see:
http://developer.java.sun.com/developer/copyright.html
This issue of the JDC Tech Tips is written by Glen McCluskey.
JDC Tech Tips
August 15, 2000