Friday, 24 October 2014
Here Are Java Tips & Tricks With Examples
CONTENTS
These are very essential java tips and tricks along examples:
1. Scaling an image Determining the method file name
2. Building CLASSPATH in Windows
3. Capturing an exception's stack trace
4. Merging hash tables
5. Formatting dates
6. Parsing dates
7. Handling time zones
8. File output
9. File input
10. Writing to a string
11. Getting system properties
12. Getting an object's class name
13. Using reflection to call methods
14. Sockets
15. JDBC Drivers
16. JDBC - Multiple Result Sets
17. MessageFormat
18. The equals() method
19. Cloning
20. Comparable
21. Using standard Exceptions
22. Collections
3. Capturing an exception's stack trace
4. Merging hash tables
5. Formatting dates
6. Parsing dates
7. Handling time zones
8. File output
9. File input
10. Writing to a string
11. Getting system properties
12. Getting an object's class name
13. Using reflection to call methods
14. Sockets
15. JDBC Drivers
16. JDBC - Multiple Result Sets
17. MessageFormat
18. The equals() method
19. Cloning
20. Comparable
21. Using standard Exceptions
22. Collections
Scaling an image
javaio provides lots of useful image manipulation functionality, but it's hard to find decent documentation. Here's how to scale an image, at least:
Image image = ...;
BufferedImage scaled =
new BufferedImage((int) (w * scale), (int) (h * scale), image.getType());
AffineTransform at = AffineTransform.getScaleInstance(scale, scale);
Graphics2D g2d = (Graphics2D) scaled.getGraphics();
g2d.drawImage(image,
new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR), 0, 0);
image = scaled;
Determining the method file name
This is useful in log messages to output the name of the current method. Note that it only works in Java 5.
String getCurrentMethodName() {
return Thread.currentThread().getStackTrace()[3].getMethodName();
}
int myMethod() {
System.err.println( getCurrentMethodName() + ": message"); // prints "myMethod: message"
}
Building CLASSPATH in Windows
If all the jars for your application are in a single directory, then the following technique using batch files can be used to dynamically build the CLASSPATH. This beats typing them out by hand!
Suppose that the jars in the "lib" directory, and that you have a batch file that launches your application from the sister "bin" directory. Create one batch file, called "addjar.bat", with contents:
@set CLASSPATH=%CLASSPATH%;%1
and a second file, called "setcp.bat", containing:
@set CLASSPATH=
@FOR %%f in (..\lib\*.*) do call addjar %%f
Put both these batch files in the bin directory, and call setcp from your launch script before starting the application. The CLASSPATH variable will be set up by setcp, and does not need to be set on the line where the JVM is started.
Capturing an exception's stack trace
import java.io.*;
Exception e = ...;
java.io.StringWriter sw = new java.io.StringWriter();
e.printStackTrace(new java.io.PrintWriter(sw));
String trace = sw.getBuffer().toString();
Merging hash tables
import java.util.*;
Map m1 = ...;
Map m2 = ...;
m2.putAll(m1); // adds all elements of m1 to m2
Formatting dates
import java.io.*;
import java.util.*;
import java.text.*;
SimpleDateFormat formatter = new SimpleDateFormat ("yyyy.MM.dd H:mm");
Date now = new Date();
System.out.println(formatter.format(now)); // 2001.3.19 13:21
formatter.applyPattern("dd MMM yyyy");
System.out.println(formatter.format(now)); // 19 Mar 2001
The usable codes are:
pattern | meaning | example |
d | day in month | 4 |
dd | day in month | 04 |
D | day in year | 216 |
F | day of week in month | 2 (e.g. 2nd Wednesday) |
E | day in week | Tues |
EEEE | day in week | Tuesday |
w | week in year | 27 |
W | week in month | 2 |
MM | month | 04 |
MMM | month | Jul |
MMMM | month | July |
yy | year | 01 |
yyyy | year | 2001 |
G | era | AD |
K | hour 0-11 | 10 |
hh | hour 0-23 | 19 |
k | hour in day 1-24 | 24 |
H | hour in day 0-23 | 0 |
m | minute in hour | 59 |
s | second in minute | 59 |
S | millisecond | 879 |
a | AM/PM | PM |
z | timezone | PST |
zzzz | timezone | Pacific Standard Time |
Parsing dates
import java.io.*;
import java.util.*;
import java.text.*;
String s = "2001/09/23 14:39";
SimpleDateFormat formatter = new SimpleDateFormat ("yyyy/MM/dd H:mm");
Date d = formatter.parse(s, new ParsePosition(0));
Handling time zones
The TimeZone class provides all of the necessary functionality here, and even handles daylight savings time. The general idea is to determine the appropriate time zone id from the list supplied by the static method:
Once the time zone id is used, the following methods can be used to convert between a Date object (which is always relative to UTC (similar to GMT - Greenwich Mean Time)), and a date/time string epxressed relative to a particular location, taking into account the offset and the daylight saving time rules for that location:
public static String GMTDateToLocalString(Date d, String tzid) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
sdf.setTimeZone(TimeZone.getTimeZone(tzid));
return sdf.format(d);
}
public static Date LocalStringToGMTDate(String s, String tzid) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
sdf.setTimeZone(TimeZone.getTimeZone(tzid));
try {
return sdf.parse(s);
} catch (Exception e) {
return null;
}
}
These methods can be stuck in a utility class somewhere. Note: resist the temptation to re-use the SimpleDateFormat object - I found that that technique doesn't work too well, though I may just be stupid.
The code shown is pretty simple; you might like to improve on it by using locales, or by implementing a better error handling technique when parsing a date/time string.
File output
import java.io.*;
String filename = "/tmp/xxx.html";
try {
PrintWriter out = new PrintWriter(new FileWriter(filename));
out.print(new Date());
out.println(new Date());
out.println(5);
out.println(5L);
out.close();
} catch (IOException e) {
// handle the exception
}
File input
import java.io.*;
String filename = "/tmp/xxx.html";
try {
BufferedReader in = new BufferedReader(new FileReader(filename));
String line;
while ((line = in.readLine()) != null) {
// use the line
}
in.close();
} catch (IOException e) {
// handle the exception
}
Writing to a string
import java.io.*;
StringWriter out = new StringWriter();
out.write("A string");
out.write('c');
String s = out.toString();
// out.close() does nothing
Getting system properties
Many system properties are available by default:
- java.class.path
- os.name
- os.arch
- os.version
- file.separator
- path.separator
- line.separator
- user.name
- user.home
- user.dir
Other system properties may be created via command line arguments, as in:
java -Dprop=val class
Example:
String prop = "myproperty";
String default = "0";
String val = System.getProperty(prop);
String val = System.getProperty(prop, default);
String sep = System.getProperty("line.separator");
Getting an object's class name
Object o = ...;
String className = o.getClass().getName();
also note...
Class c1 = String.class;
Class c2 = java.util.Vector.class;
Class c3 = int.class;
Class c4 = int[].class;
Class c5 = int[][].class;
Class c6 = String[].class;
and...
Class c7 = Class.forName("java.lang.String");
Using reflection to call methods
import java.lang.reflect.*;
Class c = ...; // see above
Method[] methods = c.getMethods();
Method m = methods[i];
String s = m.getName();
Class r = m.getReturnType(); // returns void.class if void
Class[] p = m.getParameterTypes();
// to invoke a method, use:
Object invoke(Object o, Object[] args);
Sockets
This ridiculous example implements a server which returns the double of a double. Here's the client code:
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws IOException {
int n = Integer.parseInt(args[0]);
Socket sock = null;
PrintWriter out = null;
BufferedReader in = null;
try {
sock = new Socket("localhost", 4444);
out = new PrintWriter(sock.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
}
catch (UnknownHostException e) {
System.err.println("Don't know about host: localhost.");
System.exit(1);
}
catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: localhost.");
System.exit(1);
}
for (double d = 0; d < n; d++) {
out.println(d);
String s = in.readLine();
}
out.close();
in.close();
sock.close();
}
}
and here's the server:
import java.net.*;
import java.io.*;
import java.math.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
try {
double d = Double.parseDouble(line);
out.println(d * d);
}
catch (NumberFormatException e) {
out.println("Error on input: " + line);
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
JDBC Drivers
Personally, I can never remember the class names for drivers or the formats for the URLs, so just for the sake of reference, here's a few that I've used:
Oracle | oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@server:1521:dbinstance |
MySQL | org.gjt.mm.mysql.Driver jdbc:mysql://localhost/database?user=user&password=password |
Interbase | interbase.interclient.Driver jdbc:interbase://localhost/c:/dir/dir/dir/file.gdb |
Postgres | org.postgresql.Driver jdbc:postgresql://server[:port]/database[?user=user&password=password] |
Sybase | com.sybase.jdbc.SybDriver or com.sybase.jdbc3.jdbc.SybDriver jdbc:sybase:[protocol]:[server]:[port]/[database] |
JDBC - Multiple Result Sets
It's a bit tricking handling multiple result sets... you have to request the result sets and the status values in the correct sequence.
import java.sql.*;
import java.text.*;
import java.util.*;
public class Demo {
private static String DRIVER = "driver class";
private static String URL = "db url";
private static String USER = "user";
private static String PASSWORD = "password";
public static void main(String[] args) {
try {
test();
} catch (SQLException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private static void test() throws Exception {
Class.forName(DRIVER);
Properties prop = new Properties();
prop.setProperty("user", USER);
prop.setProperty("password", PASSWORD);
Connection conn = DriverManager.getConnection(URL, prop);
CallableStatement cs = conn.prepareCall("{ ? = call stored_procedure }");
cs.registerOutParameter(1, Types.INTEGER);
boolean hasMoreResultSets = cs.execute();
int rowsAffected = 0;
do {
if (hasMoreResultSets) {
ResultSet rs = cs.getResultSet();
printResultSet(rs);
}
else {
rowsAffected = cs.getUpdateCount();
}
hasMoreResultSets = cs.getMoreResults();
} while (hasMoreResultSets || (rowsAffected != 1));
int retVal = cs.getInt(1);
System.out.println("Return value was " + retVal);
}
private static void printResultSet(ResultSet rs) throws Exception {
ResultSetMetaData md = rs.getMetaData();
int n = md.getColumnCount();
for (int i = 0; i < n; i++) {
System.out.print(md.getColumnLabel(i+1));
}
System.out.println();
while (rs.next()) {
for (int i = 0; i < n; i++) {
System.out.print(rs.getString(i+1));
}
System.out.println();
}
}
}
MessageFormat
The MessageFormat class can be used quite nicely to compose messages. For example, the following:
import java.text.*;
public class Test {
public static void main(String[] args) {
String message = "The opposite of {0} is {1}.";
Object values[] = { "yes", "no" };
String s = MessageFormat.format(message, values);
System.out.println(s);
}
}
prints:
The opposite of yes is no.
Note that {, } or ' characters that are part of the plain text must be quoted, as '{', '}' and '', respectively. For example:
import java.text.*;
public class Test {
public static void main(String[] args) {
String message = "Here''s your choices: '{'{0}, {1}'}'.";
Object values[] = { "yes", "no" };
String s = MessageFormat.format(message, values);
System.out.println(s);
}
}
produces:
Here's your choices: {yes, no}.
The equals() method
Should do the following:
- Test for equality
- Test for type
- Do the cast
- Test significant fields, avoiding null pointer exceptions
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof TheType)) {
return false;
}
TheType that = (TheType) o;
if (field1 != that.field2) {
// for primitives
return false;
}
if ((field2 != that.field2)
&& ((field2 == null) || !field2.equals(that.field2))) {
// for references
return false;
}
...
return true;
}
This version tests for object identity both at the calling level, and for member of reference type.
Also: always override hashCode() when overriding equals().
Cloning
If a class implements Cloneable, then the default implementation of clone() in Object will return an object of the same runtime class, containing a field-by-field copy of the object. No constructor for the class is used.
If one calls a constructor from the clone() method, then subclasses will not be able to use super.clone() to initialize superclass fields. Consequently, one should always use super.clone().
The normal approach, therefore, is to call super.clone(), and then to adjust the contents appropriately. This would involve cloning member fields which are mutable objects, for example. However, this fails if any of the member fields are final!
Comparable
The compareTo() method return a negative, zero or positive value according as the object in question should compare before, equal to or after the argument passed in. It's not necessary to return -1 or 1; any negative or positive value is acceptable.
The compareTo() method should throw a ClassCastException if the argument passed in is not of the appropriate type, and it should throw NullPointerException if the argument passed in is null. Consequently, it's not necessary to test for these conditions!
public class Person implements Comparable {
int age;
...
public int compareTo(Object o) {
return age - ((Person) o).age;
}
}
Using standard Exceptions
In general, it's best to use exceptions from the standard library to indicate problems in one's own code, if the semantics match up. Here are some exceptions that can commonly be used in this way:
IllegalArgumentException | Signals an invalid value for a method parameter |
IllegalStateException | Signals that the object is not in a valid state when a method is called |
NullPointerException | Signals that a parameter is null when it is not allowed to be so |
IndexOutOfBoundsException | An index parameter is out of bounds |
Collections
The following are defined in the Collection interface:
boolean containsAll(Collection<?> c) | Check if the collection contains all members of another collection |
boolean addAll(Collection<? extends E>) | Adds all elements of the provided collection |
boolean removeAll(Collection<?>) | Removes all elements that are in the given collection |
boolean retainAll(Collection<?>) | Removes all elements which are not in the given collection |
void clear() | Empties the collection |
addAll(), removeAll() and retainAll() return true if the collection was modified.
The following removes all occurrences of a particular element e from a Collection c:
c.removeAll(Collections.singleton(e));
Sets come in three varieties:
HashSet | implemented as a hash table, most efficient |
TreeSet | implemented as a tree, iterator provides elements in sorted order |
LinkedHashSet | implemented as a hash table, iterator provides elements in order of insertion |
The following removes all duplicates from a Collection c:
Collection<T> c1 = new HashSet<T>(c);
For sets, addAll() performs a union, removeAll() performs a difference, retainAll() peforms intersction, and containsAll() checks the subset relationship.
List supports the subList(i, j) method, which gives a view onto the list, using the same backing store. It can be useful, for example, to remove part of a list:
list.subList(from, to).clear(); // clears elements from, from+1, ..., to-1
The Collections class provides various additional fuctionality.
Synchronized wrapper classes:
Collection<E> sc = Collections.synchronizedCollection(Collection<E> c);
Set<E> ss = Collections.synchronizedSet(Set<E> s);
List<E> sl = Collections.synchronizedList(List<E> l);
Map<K, V> sm = Collections.synchronizedMap(Map<K, V> m);
Unmodifiable wrapper classes:
Collection<E> sc = Collections.unmodifiableCollection(Collection<E> c);
Set<E> ss = Collections.unmodifiableSet(Set<E> s);
List<E> sl = Collections.unmodifiableList(List<E> l);
Map<K, V> sm = Collections.unmodifiableMap(Map<K, V> m);
Immutable list containing multiple copies of an element:
List<T> list = new ArrayList<T>(Collections.nCopies(500, t));
Immutable singleton:
Collection<T> c = Collections.singleton(t);
Empty collections:
Set<T> s = Collections.emptySet();
List<T> l = Collections.emptyList();
Map<T> m = Collections.emptyMap();
Source: http://goo.gl/yGXAWd
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment