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

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:
patternmeaningexample
dday in month4
ddday in month04
Dday in year216
Fday of week in month2 (e.g. 2nd Wednesday)
Eday in weekTues
EEEEday in weekTuesday
wweek in year27
Wweek in month2
MMmonth04
MMMmonthJul
MMMMmonthJuly
yyyear01
yyyyyear2001
GeraAD
Khour 0-1110
hhhour 0-2319
khour in day 1-2424
Hhour in day 0-230
mminute in hour59
ssecond in minute59
Smillisecond879
aAM/PMPM
ztimezonePST
zzzztimezonePacific 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:
String[] tzids = TimeZone.getAvailableIDs(); This list includes the standard timezones (e.g. "EST", "PST"), and also includes specialized ids for regions where the daylight savings time rules are unusual in some respect (e.g. "America/Montreal").
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:
Oracleoracle.jdbc.driver.OracleDriver
jdbc:oracle:thin:@server:1521:dbinstance
MySQLorg.gjt.mm.mysql.Driver
jdbc:mysql://localhost/database?user=user&password=password
Interbaseinterbase.interclient.Driver
jdbc:interbase://localhost/c:/dir/dir/dir/file.gdb
Postgresorg.postgresql.Driver
jdbc:postgresql://server[:port]/database[?user=user&password=password]
Sybasecom.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:
IllegalArgumentExceptionSignals an invalid value for a method parameter
IllegalStateExceptionSignals that the object is not in a valid state when a method is called
NullPointerExceptionSignals that a parameter is null when it is not allowed to be so
IndexOutOfBoundsExceptionAn 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:
HashSetimplemented as a hash table, most efficient
TreeSetimplemented as a tree, iterator provides elements in sorted order
LinkedHashSetimplemented 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();

No comments:

Post a Comment

Download

Subscribe