A java blog with a collection of examples and tutorials on Java and related technologies. (Under maintenance with continuous updates) Be in touch with java jazzle or k2java.blogspot.com.
Wednesday, December 22, 2010
Getting java run time memory statistics
{
System.out.println("JVM Statistics -- Max : " + Runtime.getRuntime().maxMemory() + "; " +
"Free: " + Runtime.getRuntime().freeMemory() + "; " +
"Total: " + Runtime.getRuntime().totalMemory());
}
Tuesday, November 30, 2010
Iterate through values of Java Hashtable example
This example shows how to iterate over hash table using enumerator:
//create Hashtable object
Hashtable ht = new Hashtable();
//add key value pairs to Hashtable
ht.put("1","One");
ht.put("2","Two");
ht.put("3","Three");
//get Enumeration of values contained in Hashtable using
//Enumeration elements() method of Hashtable class
Enumeration e = ht.elements();
//iterate through Hashtable values Enumeration
while(e.hasMoreElements())
System.out.println(e.nextElement());
Monday, November 29, 2010
How do I convert String to Date object?
To convert a string of date we can use the help from java.text.SimpleDateFormat that extends java.text.DateFormat abstract class.
import
java.text.DateFormat;
import
java.text.SimpleDateFormat;
import
java.text.ParseException;
import
java.util.Date;
public
Date StringToDate
{
DateFormat df =
new
SimpleDateFormat(
"dd/MM/yyyy"
);
try
{
Date today = df.parse(
"20/12/2005"
);
System.out.println(
"Today = "
+ df.format(today));
}
catch
(ParseException e)
{
System.out.println("Cannot convert to date "+e);
}
}
Today = 20/12/2005The example starts by creating an instance of
SimpleDateFormat
with "dd/MM/yyyy" format which mean that the date string is formatted in day-month-year sequence.Finally using the
parse(String source)
method we can get the Date
instance. Because parse method can throw java.text.ParseException
exception if the supplied date is not in a valid format; we need to catch it.Here are the list of defined patterns that can be used to format the date taken from the Java class documentation.
Letter | Date / Time Component | Examples |
G | Era designator | AD |
y | Year | 1996; 96 |
M | Month in year | July; Jul; 07 |
w | Week in year | 27 |
W | Week in month | 2 |
D | Day in year | 189 |
d | Day in month | 10 |
F | Day of week in month | 2 |
E | Day in week | Tuesday; Tue |
a | Am/pm marker | PM |
H | Hour in day (0-23) | 0 |
k | Hour in day (1-24) | 24 |
K | Hour in am/pm (0-11) | 0 |
h | Hour in am/pm (1-12) | 12 |
m | Minute in hour | 30 |
s | Second in minute | 55 |
S | Millisecond | 978 |
z | Time zone | Pacific Standard Time; PST; GMT-08:00 |
Z | Time zone | -0800 |
Tuesday, November 23, 2010
Creating a delimiter separated list from list of strings
List<string> list = new List<string>() { "A" , "B", "C", "D", "E" };
string commaSeparated = String.Join(",", list.ToArray());
A,B,C,D,E
Saturday, October 30, 2010
List of interface and classes in collections
- Collection Interface
- Iterator Interface
- Set Interface
- List Interface
- ListIterator Interface
- Map Interface
- SortedSet Interface
- SortedMap Interface
- HashSet and TreeSet Classes
- ArrayList and LinkList Classes
- HashMap and TreeMap Classes
- Vector and Stack classes
Thursday, October 28, 2010
Class Objects as Type Literals
Class objects can be used as type specifications too, at runtime. For instance, you can create a generified method like this:
public static <T> T getInstance(Class<T> theClass)
throws IllegalAccessException, InstantiationException {
return theClass.newInstance();
}
Here are a few examples of calls to the getInstance()
method:
String string = getInstance(String.class);
MyClass myClass = getInstance(MyClass.class);
As you can see the return type changes depending on what class object you pass in as parameter to the method. This can be quite handy in database API's like Butterfly Persistence where you read objects from a database. Here is an example method definition:
public static <T> T read(Class<T> theClass, String sql)
throws IllegalAccessException, InstantiationException {
//execute SQL.
T o = theClass.newInstance();
//set properties via reflection.
return o;
}
Here is how you would call the read()
method:
Driver employee = read(Driver.class, "select * from drivers where id=1");
Vehicle vehicle = read(Vehicle.class, "select * from vehicles where id=1");
Upper Bounded Wildcards in generics
It is possible to set the upper bound of the wildcard like this:
List<? extends Vehicle> vehicles = new ArrayList<? extends Vehicle>();
In this example I have specified the upper bound to be the class
Vehicle
. I can now define the printElements()
method like this:public void printElements(List<? extends Vehicle> elements){ for(Vehicle o : elements){ System.out.println(o); } }
As you can see it is now safe to cast each element in the list to a
Vehicle
, as it is done by the new for loop inside the method. Furthermore, it is now safe to call the method using a
List<Car>
instance, provided that Car
extends Vehicle
. Here is an example: List<Car> elements = new ArrayList<Car> // ... add Car elements to the list. printElements(elements);
But, even when using a wildcard with an upper bound it is not safe to write to the
List
. After all, a Car
is always a Vehicle
, but a Vehicle
is not always a Car
.The type parameterization <? extends E> is called an "upper bounded wildcard" because it defines a type that could be any type so long as it is bounded by the superclass E. It provides covariant relationship such that the referenced object's (eg. Car ) type parameter is a subclass ofVehicle's type parameter
Wildcards in Generics
Suppose we have to write a generic method which takes list of elements and prints elements onto screen. Element can be String, Integer,Object...So one can think of using object as type parameter. But this will be a mistake. See here for this.
So solution is wildcards.
Wildcards
The wildcard operator is a solution to the problem explained above.The character
'?'
is a wild-card character and it stands for any Java type. It can be java.lang.Object
type or some other type. It is just a place-holder that tells that it can be assigned with any type. Considering this case, the following are now valid syntaxes. List<?> anyObjects = null; List<Integer> integers = new ArrayList<Integer>(); anyObjects = integers; List<Double> doubles = new ArrayList<Double>(); anyObjects = doubles;
Here is how you write a generic
List
using the wildcard operator:List<?> listOfUnknown = new ArrayList<?>();
Generic method using wildcards
We can now define the
printElements()
method like this:public void printElements(List<?> elements){ for(Object o : elements){ System.out.println(o); } }
You can call the
printElements()
with any generified List
instance. For instance: List<String> elements = new ArrayList<String>
// ... add String elements to the list.
printElements(elements);
When you upcast a
List<String>
to a List<?>
you can now read all elements of the List<?>
safely as Object
instances. But you still cannot insert elements into the List<?>
. The ? could represent any type, and thus it would be possible to insert types that did not match the original definition of the List
. Generics and Subtyping
Let’s test our understanding of generics. Is the following code snippet legal?
List<String> ls = new ArrayList<String>(); //1List<Object> lo = ls; //2
Line 1 is certainly legal. The trickier part of the question is line 2. This boils down
to the question: is a List of String a List of Object. Most people’s instinct is to answer:
“sure!”.
Well, take a look at the next few lines:
lo.add(new Object()); // 3String s = ls.get(0); // 4: attempts to assign an Object to a String!
Here we’ve aliased ls and lo. Accessing ls, a list of String, through the alias lo, we
can insert arbitrary objects into it. As a result ls does not hold just Strings anymore,
and when we try and get something out of it, we get a rude surprise.
The Java compiler will prevent this from happening of course. Line 2 will cause a
compile time error.
In general, if Foo is a subtype (subclass or subinterface) of Bar, and G is some
generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>.
This is probably the hardest thing you need to learn about generics, because it goes
against our deeply held intuitions.
So we had list of String not subtype of list of Objects.
The problem with that intuition is that it assumes that collections don’t change.
Our instinct takes these things to be immutable.
For example, if the department of motor vehicles supplies a list of drivers to the census
bureau, this seems reasonable. We think that a List<Driver> is a List<Person>,
assuming that Driver is a subtype of Person. In fact, what is being passed is a copy
of the registry of drivers. Otherwise, the census bureau could add new people who are
not drivers into the list, corrupting the DMV’s records.
In order to cope with this sort of situation, it’s useful to consider more flexible
generic types. The rules we’ve seen so far are quite restrictive.
Generic classes in java vs templates in C++
java.util: public interface List<E> { void add(E x); Iterator<E> iterator(); } public interface Iterator<E> { E next(); boolean hasNext(); }
This should all be familiar, except for the stuff in angle brackets. Those are the
declarations of the formal type parameters of the interfaces List and Iterator.
Type parameters can be used throughout the generic declaration, pretty much where
you would use ordinary types (though there are some important restrictions.
In the introduction, we saw invocations of the generic type declaration List, such
as List<Integer>. In the invocation (usually called a parameterized type), all occurrences of the formal type parameter (E in this case) are replaced by the actual type argument (in this case, Integer).
You might imagine that List<Integer> stands for a version of List where E has been uniformly replaced by Integer:
public interface IntegerList { void add(Integer x); Iterator<Integer> iterator(); }
This intuition can be helpful, but it’s also misleading.
It is helpful, because the parameterized type List<Integer> does indeed have methods that look just like this expansion.
It is misleading, because the declaration of a generic is never actually expanded in this way. There aren’t multiple copies of the code: not in source, not in binary, not on disk and not in memory. If you are a C++ programmer, you’ll understand that this is very different than a C++ template.
A generic type declaration is compiled once and for all, and turned into a single class file, just like an ordinary class or interface declaration. Type parameters are analogous to the ordinary parameters used in methods or constructors. Much like a method has formal value parameters that describe the kinds of values it operates on, a generic declaration has formal type parameters. When a method is invoked, actual arguments are substituted for the formal parameters, and the method body is evaluated.
When a generic declaration is invoked, the actual type arguments are substituted for the formal type parameters.
The Motivation for Generics : dealing with casting of objects
List myIntList = new LinkedList(); // line no. 1 myIntList.add(new Integer(0)); // line no. 2 Integer x = (Integer) myIntList.iterator().next(); //line no. 3
The cast on line 3 is slightly annoying. Typically, the programmer knows what kind of data has been placed into a particular list. However, the cast is essential. The compiler can only guarantee that an Object will be returned by the iterator.
To ensure the assignment to a variable of type Integer is type safe, the cast is required.
Of course, the cast not only introduces clutter, it also introduces the possibility of a run time error, since the programmer might be mistaken.
Removing the cast
What if programmers could actually express their intent, and mark a list as being restricted to contain a particular data type?
This is the core idea behind generics.
Here is a version of the program fragment given above using generics:
List<Integer> myIntList = new LinkedList<Integer>(); // 1’ //OR List<Integer> myIntList = new LinkedList(); // 1’ myIntList.add(new Integer(0)); //2’ Integer x = myIntList.iterator().next(); // 3’
Now, you might think that all we’ve accomplished is to move the clutter around.
Instead of a cast to Integer on line 3, we have Integer as a type parameter on line 1’. However, there is a very big difference here. The compiler can now check the type correctness of the program at compile-time. When we say that myIntList is declared with type List<Integer>, this tells us something about the variable myIntList, which holds true wherever and whenever it is used, and the compiler will guarantee it. In contrast, the cast tells us something the programmer thinks is true at a single point in the code.
The net effect, especially in large programs, is improved readability and robustness.
A big big note on Generics
Generics provides a sort of a syntactic sugar that might spare you some casting operation. But behind the scenes, after compilation the byte code is same. See Type Erasure with Generics to see how.
Pattern and Matcher
In addition to the regular expression methods that are available in the String class (see String Regular Expressions), there are two classes that are specifically user for regular expression matching.
java.util.regex.Pattern
precompiles regular expressions so they can be executed more efficiently. It also has a few utility functions. This same pattern can be reused by manyMatcher
objects.Pattern pat = Pattern.compile(regexString);
java.util.regex.Matcher
objects are created from a Pattern object and a subject string to scan. This class provides a full set of methods to do the sacnning.Matcher m = pat.matcher(subject);
Common methods
The following variables represent elements of their declared type in the prototypes below.
import java.util.regex.*;
. . .
boolean b; // may be used in if statement.
int i; // index or character position.
int g; // group number
int n; // number of groups
CharSequence cs; // effectively either String or StringBuffer
String s; // Subject string.
String regex; // Regular expression string.
StringBuffer sb; // Used to build up string from repeated scans.
Pattern p = Pattern.compile(regex); // Compiles regular expression into Pattern.
Matcher m = p.matcher(s); // Creates Matcher with subject s and Pattern p.
Result
Method
Description
Creating a Pattern
p =
Pattern.compile(regex);
Creates Pattern based on regex. May throw PatternSyntaxException
.
p =
Pattern.compile(regex, f);
As above. Flag f can be Pattern.CASE_INSENSITIVE
, ....
Finding pattern matches
b =
m.find();
True if pattern can be found in the subject string. First call starts trying at beginning of string. Subsequent calls start after last character previously matched, which makes it good for a while loop.
b =
m.find(i);
True if pattern can match somewhere at or after position i.
b =
m.matches();
True if pattern matches entire subject string.
b =
Pattern.matches(regex, s);
As above, but less efficient if regex used more than once.
b =
m.lookingAt();
True if pattern matches starting at first char.
Getting results of last pattern match. Corresponds to group 0, then entire match.
s =
m.group();
String which was matched.
i =
m.start();
Index of first character of match.
i =
m.end();
Index of last character plus 1 of match.
Getting group results of last match
s =
m.group(g);
String which was matched by group g
.
i =
m.start(g);
Index of first character of group g.
i =
m.end(g);
Index of last character plus 1 of group g.
n =
m.groupCount();
Number of groups that were matched.
Misc
m =
m.reset();
Resets Matcher m
so that next find starts at beginning.
m =
m.reset(cs);
Resets Matcher m
to match subject cs
.
Replacing text
s =
m.replaceFirst(rep);
Returns string which is subject with first match replaced by rep
.
s =
m.replaceAll(rep);
Returns string with all matches replaced by rep
.
Building replacement in a StringBuffer
m =
m.appendReplacement(sb, s);
When it matches, (1) everything skipped before the match is appended to the StringBuffer sb, then (2) it appends s, with "$n" replaced by group n.
sb =
m.appendTail(sb);
Appends last part that m didn't match to StringBuffer. Useful after loop calling appendReplacement()
to finish.
Other Resources
Regular Expression in Java
Regular expressions are the most common programming technique to search for patterns in strings, extracting, and replacing substrings. They are an essential part of many languages, editors, and utilities, for example, Perl, JavaScript, awk, sed, vi, ....
They are powerful and useful. Simple regexes are simple, but large regexes are extremely difficult to debug. They are often not the right solution for complex parsing problems. Two quotes illustrate some feelings about them. Despite the name, as someone said, Regular expressions are neither regular nor expressions. And Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. Regular expressions form a quirky, error-prone, terse, but useful, programming language for pattern matching.
Java, as of version 1.4, has extensive support for regular expressions in two areas.
- additional String methods. See String Regex Methods.
- Additional classes,
java.util.Pattern
andjava.util.Matcher
, allow use of precompiled regular expressions as well as providing many additional functions. See Pattern and Matcher.
Regular expressions provide more general mechanisms for parsing input strings than, eg, StringTokenizer
.
Programming language. Regular expressions (often refereed to as regex) are essentially a programming language of their own.
Other Resources
- Regular Expression Tutorial (http://www.regular-expressions.info/tutorial.html) covers a lot of introductory regular expression material.
- Mastering Regular Expressions by Jeffrey Friedl is an excellent book covering regular expressions from introduction to advanced usage. Covers all major regular expression implementations, not just Java.
- Regular Expressions and the Java Programming Language (http://java.sun.com/developer/technicalArticles/releases/1.4regex) is a Sun article summarizing Java's regular expressions. This is useful if you are already familiar with Java and the idea of regular expressions.
- JRegexpTester - jregexptester.sourceforge.net/ - Another free Java program to test regexes.
- RegExLib.com - www.regxlib.com/ - Has blog discussing regeexps, and a large (> 900) library of regexps of all flavors, not just Java.
- Regular Expressions in J2SE - http://www.onjava.com/pub/a/onjava/2003/11/26/regex.html - Introduction to regular expressions.
- Summary of Regular Expressions in Java and other languages - http://mindprod.com/jgloss/regex.html
- Regular Expression Test Page - www.fileformat.info/tool/regex.htm
Display Extension
This program reads in a file name and displays the extension (that last part of the name after the final dot).
import javax.swing.*;
public class FileExt {
public static void main(String[] args) {
//... Declare local variables.
String fileName; // The file name the user entered.
String extension; // The extension.
//... Input a file name and remove whitespace.
fileName = JOptionPane.showInputDialog(null, "Enter file name.");
fileName = fileName.trim();
//... Find the position of the last dot. Get extension.
int dotPos = fileName.lastIndexOf(".");
extension = fileName.substring(dotPos);
//... Output extension.
JOptionPane.showMessageDialog(null, "Extension is " + extension);
}
}
Array to String
Here is a simple, but slow, program to concatenate all of the strings in an array, each separated by a specifed string separater.
//-------------------------------------------------- arrayToString()
// Convert an array of strings to one string.
// Put the 'separator' string between each element.
public static String arrayToString(String[] a, String separator) {
String result = "";
if (a.length > 0) {
result = a[0]; // start with the first element
for (int i=1; i<a.length; i++) {
result = result + separator + a[i];
}
}
return result;
}
The problem with the above program is that a new String object is created each time thru the loop, and the old String object becomes eligible for garbage collection. This constant creation and abandoning objects is terribly inefficient. A more efficient way to do this is to use a StringBuffer or the equivalent Java 5 StringBuilder, which will grow as needed, but generally only has to expand a few times to do the job.
//-------------------------------------------------- arrayToString2()
// Convert an array of strings to one string.
// Put the 'separator' string between each element.
public static String arrayToString2(String[] a, String separator) {
StringBuffer result = new StringBuffer();
if (a.length > 0) {
result.append(a[0]);
for (int i=1; i<a.length; i++) {
result.append(separator);
result.append(a[i]);
}
}
return result.toString();
}
Change Extension (string)
Problem: Change the extension of a file name
//============================================== changeExtension
// changes extension to new extension
// example: x = changeExtension("data.txt", ".java")
// will assign "data.java" to x.
static String changeExtension(String originalName, String newExtension) {
int lastDot = originalName.lastIndexOf(".");
if (lastDot != -1) {
return originalName.substring(0, lastDot) + newExtension;
} else {
return originalName + newExtension;
}
}//end changeExtension
Example - Palindrome test
//========================================================= isPalindrome
// This method returns 'true' if the parameter
// is a palindrome, a word that is spelled the
// same both forwards and backwards, eg, radar.
public static boolean isPalindrome(String word) {
int left = 0; // index of leftmost unchecked char
int right = word.length() -1; // index of the rightmost
while (left < right) {
// continue until they reach center
if (word.charAt(left) != word.charAt(right)) {
return false;// if chars are different, finished
}
left++; // move left index toward the center
right--; // move right index toward the center
}
return true; // if finished, all chars were same
}
This method uses two indexes that point to the left and right ends of the string. You could also write this with a for
loop that goes only to the middle.
Replace word
Problem: Write a method to replaces all occurences a word in a string with another word. Assume the method signature is
static String replaceWord(String original, String find, String replacement)
Note that Strings are immutable, so we must create a new String. The word "replace" is probably misleading. Also, the method is static
because it doesn't reference instance variables. This allows some optimizations by the compiler.
A simple, but incorrect, solution
This first attempt only replaces one word, but we could fix that up later with a loop -- but it's not worth the effort because it's wrong anyway.
//--------------------------------------------- replaceWord()
// BAD BAD BAD BAD BAD
static String replaceWord(String original, String find, String replacement) {
int i = original.indexOf(find);
if (i < 0) {
return original; // return original if 'find' is not in it.
}
String partBefore = original.substring(0, i);
String partAfter = original.substring(i + find.length());
return partBefore + replacement + partAfter;
}
This example method replaces the first occurrence of a one string with another. If we execute the following code,
t = "A great man";
s = replaceWord(t, "man", "woman");
the value in s will be "A great woman". Ok, but what if we changed the orginal string to contain the word "human", or anything else that contained a substring, but not a separate word, that has "man" in it.
t = "A great human";
s = replaceWord(t, "man", "woman");
Now s will contain "A great huwoman". Not what was intended.
The solution is to know about "words"
Simply finding a substring isn't sufficient. There are several ways to solve the problem.
- Check the character preceding and following the string to see if they are delimiters, and can't be part of a word, or the word boundary is at the beginning or end of the string.
- Use java.util.StringTokenizer. This is a common solution, but has been superceded by regular expressions (see below).
- Java 1.4 added Regular Expressions, which is the most common way to solve the problem in most other programming languages. [TO DO: Write solution using regular expressions.]
StringTokenizer solution
This replaces all occurences of a "word", not just the first.
static String replaceAllWords1(String original, String find, String replacement) {
String result = "";
String delimiters = "+-*/(),. ";
StringTokenizer st = new StringTokenizer(original, delimiters, true);
while (st.hasMoreTokens()) {
String w = st.nextToken();
if (w.equals(find)) {
result = result + replacement;
} else {
result = result + w;
}
}
return result;
}
This breaks the string into tokens, consisting of the text between delimiters, as well as the tokens consisting of the delimiters. The true
parameter causes the delimiters to also be returned as tokens. You might not need them if you are only interested in what comes between them. Naturally, you would choose the delimiters appropriate to your problem.
Buiding a string by sucessive concatenations is inefficient, as it creates new string as it is immutable and should be replaced by StringBuilder (or the equivalent pre-Java 5 StringBuffer) for efficiency. See below.
Using StringBuilder to build a String
Creating new strings in a loop can be inefficient because of the number of new objects that are created and discarded. It's better to use a StringBuilder
(introduced Java 5) or the slightly slower, synchronized, StringBuffer
, which has been in Java from the beginning.
static String replaceAllWords2(String original, String find, String replacement) {
StringBuilder result = new StringBuilder(original.length());
String delimiters = "+-*/(),. ";
StringTokenizer st = new StringTokenizer(original, delimiters, true);
while (st.hasMoreTokens()) {
String w = st.nextToken();
if (w.equals(find)) {
result.append(replacement);
} else {
result.append(w);
}
}
return result.toString();
}
This creates a StringBuilder with an initial capacity equal to the original string. It will expand if necessary, so this initial capacity isn't critical. Theappend(...)
method is used to add to the end of it. ThetoString()
call at the end returns a String. This is an efficient conversion.
String to "tokens"
- String
split(regex)
- Probably the easiest. java.util.Scanner
- This can "read" from strings. Very general.- The
java.util.regex.
Pattern
andMatcher
use regular expressions - The most powerful solution. java.util.StringTokenizer
- This has been superceded by regular expressions, Scanner, and split().
Easy - String split(...) method
The easiest way to split a string into separate "tokens" is to use thesplit(...)
method. For example,String test = "It's the number 1 way."; String[] tokens = test.split(" "); // Single blank is the separator. System.out.println(Arrays.toString(tokens));Produces the following output:
[It's, the, number, 1, way.]
Good - Scanner
Scanner can be used to "read" strings. Here's the previous example using Scanner, but because it doesn't produce arrays, the results are added to an ArrayList.String test = "It's the number 1 way."; ArrayList<String> tokens = new ArrayList<String>(); Scanner tokenize = new Scanner(test); while (tokenize.hasNext()) { tokens.add(tokenize.next()); } System.out.println(tokens);
[It's, the, number, 1, way.]It doesn't care about what makes up a "token", only that they must be separated by single blanks. To allow one or more blanks as a separator, use " +", which means one or more blanks.
Scanner has numerous methods for working more generally with regular expressions to identify the token you want to read or the delimiters you want to skip.
Numbers. One advantage of using a Scanner is that you can easily switch back and forth between reading strings and numbers.
Converting Strings to Numbers
String s; int i; long l; float f; double d;
type | Example statement |
int | i = Integer.parseInt(s); |
long | l = Long.parseLong(s); |
float | f = Float.parseFloat(s); |
double | d = Double.parseDouble(s); |
NumberFormatException
. See below. Handling NumberFormatExceptions
Put number conversions inside atry . . . catch
statement so that you can do something if bad input is entered. The conversion method will throw a NumberFormatException when there is bad input. Catch the NumberFormatException, and do something to handle this error condition. Put your conversion in the try
clause, and the error handling in the catch
clause. Here is an example of the kind of utility function you might write to do this checking. //--- Utility function to get int using a dialog. public static int getInt(String mess) { int val; while (true) { // loop until we get a valid int String s = JOptionPane.showInputDialog(null, mess); try { val = Integer.parseInt(s); break; // exit loop with valid int >>>>>>>>>>>>>>>>>>>>>> }catch (NumberFormatException nx) { JOptionPane.showMessageDialog(null, "Enter valid integer"); } } return val; }//end getInt
Non-decimal Integers
Convert integers with some base (radix) other than 10 by using these two methods. Typically these will be hexadecimal (base 16) or binary (base 2) numbers.type | Example statement |
int | i = Integer.parseInt(s, radix); |
long | l = Long.parseLong(s, radix); |
i = Integer.parseInt("F7", 16)
Related data structure classes: EnumSet and EnumMap
java.util.EnumMap provides an efficient implementation of a map for enums based on an array.
They provide a compact and efficient implementation for enum types. These collections are not synchronized and when used in multi-threaded environment, applications should take care of synchronizing the operations on the collection. EnumMap and EnumSet are homogenous collections of the same enum type. They cannot be used to operate on different enum types at the same time.
public enum Color {
//
RED, BLUE, YELLOW, GREEN, ORANGE, PURPLE;
public static EnumSet<Color> getPrimaryColors() {
return EnumSet.of(RED, BLUE, YELLOW);
}
public static EnumSet<Color> getSecondaryColors() {
return EnumSet.complementOf(getPrimaryColors());
}
public static void main(String[] args) {
System.out.println("Primary Colors: "+Color.getPrimaryColors());
System.out.println("Secondary Colors: "+Color.getSecondaryColors());
System.out.println("Universe: "+EnumSet.allOf(Color.class));
}
}
Convert string to enum
public enum Shape { RECTANGLE, CIRCLE, LINE }The
valueOf()
method can be used to convert a string value to an enum value. Here is an example of reading in a Shape value from a Scanner object in. drawing = Shape.valueOf(in.next());
or
drawing = Shape.valueOf("RECTANGLE")We can have custom methods to deal with this, if we dont want to have some extra customization.
eg. If the text is not the same to the enumeration value:
public enum Blah {
A("text1"),
B("text2"),
C("text3"),
D("text4");
private String text;
Blah(String text) {
this.text = text;
}
public String getText() {
return this.text;
}
public static Blah fromString(String text) {
if (text != null) {
for (Blah b : Blah.values()) {
if (text.equalsIgnoreCase(b.text)) {
return b;
}
}
return null;
}
}
toString() for Enums
public enum Shape { RECTANGLE, CIRCLE, LINE }
Shape drawing = Shape.RECTANGLE; // Only a Shape value can be assigned.
System.out.println(drawing); // Prints RECTANGLE
Override toString method for All Enums
A semicolon after the last element is required to be able to compile it. More details on overriding enum toString method can be found.
public enum Color { WHITE, BLACK, RED, YELLOW, BLUE; //; is required here. @Override public String toString() { //only capitalize the first letter String s = super.toString(); return s.substring(0, 1) + s.substring(1).toLowerCase(); } }
Override toString method element by element
The default string value for java enum is its face value, or the element name. However, you can customize the string value by overriding toString() method. For example,
public enum MyType {
ONE {
public String toString() {
return "this is one";
}
},
TWO {
public String toString() {
return "this is two";
}
}
}
Running the following test code will produce this:public class EnumTest {
public static void main(String[] args) {
System.out.println(MyType.ONE);
System.out.println(MyType.TWO);
}
}
-------------
this is one
this is two
Another interesting fact is, once you override toString() method, you in effect turn each element into an anonymous inner class. So after compiling the above enum class, you will see a long list of class files:MyType.class
MyType$1.class
MyType$2.class
Enum and their super-class
java.lang.Enum
. Since java doesn't allow multiple inheritance, enum types can't have superclass. They can't even extend from java.lang.Enum
, nor java.lang.Object
. It also means enum A can't inherit or extend enum B.For example, the following is an invalid enum declaration:
public enum MyType extends Object {
ONE, TWO
}
Compiler error:MyType.java:3: '{' expected
public enum MyType extends Object {
MyType.java:6: expected
2 errors
The correct form should be:
public enum MyType {
ONE, TWO
}
Enum that implements interfaces
java.io.Serializable
, and java.lang.Comparable
.public enum Color implements Runnable { WHITE, BLACK, RED, YELLOW, BLUE; public void run() { System.out.println("name()=" + name() + ", toString()=" + toString()); } }A sample test program to invoke this run() method:
for(Color c : Color.values()) { c.run(); }Or,
for(Runnable r : Color.values()) {
r.run();
}
Enum with additional fields and custom constructor
public enum Color { //Color is of type enum
WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25); private int code; private Color(int c) { code = c; } public int getCode() { return code; }
Switch statement on enums
public enum Shape { RECTANGLE, CIRCLE, LINE }
The
switch
statement was enhanced to allow a convenient use of enums. Note that the case values don't have to be qualified with the enum class name, which can be determined from the switch
control value. switch (drawing) { case RECTANGLE: g.drawRect(x, y, width, height); break; case CIRCLE : g.drawOval(x, y, width, height); break; case LINE : g.drawLine(x, y, x + width, y + height); break; }
Formatted conversion to String
Format conversion
You can use a format, a string which tells how you want values converted to string.
Formatting numbers with %d (integers) and %f (floating point)
The basic support is in the java.util.Formatter
class, where a Formatter
object is created and it's format
method is called. However, it's more common to use one of these convenience methods:
String.format(format, values...)
System.out.printf(format, values...)
orSystem.err.print.
Basic format structure for three types
- Formatting most values
%[argument_index$][flags][width][.precision]conversion
- Formating Calendar values
%[argument_index$][flags][width][.precision]conversion
- Non-argument values
%[flags][width]conversion
Like C's printf. If you are familiar with C's printf
formats, you will be very comfortable with Java's formats, although they are slightly different.
Full description of formatting
Sun's Java documentation has a full description of the formatting codes. You should download the latest version of the API documentation. Here is a link to Java version 5 documentation: java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html .
String Related types and classes
String
The basic class for strings. String objects can NOT be changed.
char
Primitive type for 16-bit Unicode characters.
Character
Primarily useful for its utility functions for working with characters.
StringBuffer
StringBuffers are used to build or change strings. Conversion between String and StringBuffer is easy.
StringBuilder
StringBuilder was added in Java 5. It is the same as StringBuilder, but slightly faster because it's unsynchronized.
StringTokenizer
Used to break a String into tokens (words).
BufferedReader
BufferedWriter
Useful for reading and writing text files.
Pattern, Matcher
JDK 1.4 added java.util.Pattern and Matcher to do regular expression matching.
Wednesday, October 27, 2010
Collections Class
The java.util.Collections
class contains static utility methods for manipulating collections.
Some useful Collections methods
Assume the following declarations have been made, where T
is a class or interface type.
int i;
List<T> listC; // List of the Comparable objects.
List<T> list; // Any kind of list. Need not be Comparable.
Comparator<T> comp;
T key;
T t;
Collection<T> coll; // Any kind of Collection (List, Set, Deque).
Collection<T> collC; // Any kind of Collection implementing Comparable.
Rearranging - Sorting, Shuffling, . . .
Collections.sort(listC)
Sorts listC
. Elements must be Comparable<T>. Stable, O(N log N).
Collections.sort(list, comp)
Sorts list
using a comparator.
Collections.shuffle(list)
Puts the elements of list
in random order.
Collections.reverse(list)
Reverses the elements of list
.
Searching
i =
Collections.binarySearch(listC, key)
Searches list
for key
. Returns index of element or negative value if not found. See Binary Search.
i =
Collections.binarySearch(list, key, comp)
Searches in list
for key
using Comparator comp.
t =
Collections.max(collC)
Returns maximum valued Comparable object in collC
.
t =
Collections.max(coll, comp)
Maximum valued object in coll
using Comparator comp
.
t =
Collections.min(collC)
Returns minimum valued Comparable object in collC
.
t =
Collections.min(coll, comp)
Minimum valued object in coll
using Comparator comp
.
There are many additional methods in Collections, but the above are a good start.
Searching may also be implemented in data structure classes
All List and Set classes implement the contains()
method, which performes a linear search on lists (O(N)), a binary search for TreeSets (O(log N)), and a hashed search for HashSets (O(1)).
Maps define get()
to search for the key. For HashMaps the search is O(1), and for TreeMaps the search is O(log N).
Sorting may be implicit in a data structure class
TreeSet data and TreeMap keys are sorted at all times. They are implemented as binary trees, so insertion and search are both O(log N). An iterator can be used to get retrieve the data (TreeSets) or keys (TreeMaps) in sorted order. Either the element class must be Comparable, or a Comparator must be supplied.
Bitwise Operators - Uses
- Efficient storage.
- Status bits. Eg, Mouse event key mask.
- Eg, representing Connect-Four board.
- Packing or unpacking values into a single int/long.
A common use of the bitwise operators (shifts with ands to extract values and ors to add values) is to work with multiple values that have been encoded in one int. Bit-fields are another way to do this. For example, let's say you have the following integer variables: age (range 0-127), gender (range 0-1), height (range 0-128). These can be packed and unpacked into/from one short (two-byte integer) like this (or many similar variations).//define the variables
int age, gender, height;
short packed_info;
. . .
// packing
packed_info = (((age << 1) | gender) << 7) | height;
. . .
// unpacking
height = packed_info & 0x7f;
gender = (packed_info >>> 7) & 1;
age = (packed_info >>> 8); - Setting flag bits
Some library functions take an int that contains bits, each of which represents a true/false (boolean) value. This saves a lot of space and can be fast to process.
- Efficient computation
- On some (esp old) machines, shifting is faster than multiplying or dividing by powers of two.
y = x << 3; // Assigns 8*x to y.
y = (x << 2) + x; // Assigns 5*x to y. - Flipping between on and off with xor
Sometimes xor is used to flip between 1 and 0.x = x ^ 1; // Or the more cryptic x ^= 1;
In a loop that will change x alternately between 0 and 1. - On some (esp old) machines, shifting is faster than multiplying or dividing by powers of two.
- Problems
- How could you use bit operations to test whether a number is odd?
- How would you multiply by 256?
- How would you swap 2 integers, without using temporary variable?
- How could you use bit operations to test whether a number is odd?
Bitwise Operators Summary
(a & b)
- Result is 1 in every bit position where both operands have a 1. (a | b)
- Result is 1 only in positions where one or both operands have a 1. (a ^ b)
- Result is 1 in positions where the two corresponding bits are different. (~a)
- Unary operator. Result is each bit of operand inverted. (a << n)
- Shifts bits n positions left. Zeros added on right. (a >> n)
- Shifts bits n positions right. High-order bit inserted on left. (a >>> n)
- Shifts bits n positions right. Zeros inserted at left.Operator Precedence
Precedence determines order of evaluation
Mathematical tradition, which programming languages generally try to match, dictates that some operations are done before others (for example, multiplication and division are done before addition and subtraction).
a+b*c
is the same as a+(b*c)
, not (a+b)*c
.
Ever operator has a precedence (a number) associated with it. The precedence determines which operations will be performed first. Multiplication has higher precedence than addition, as illustrated in the previous example..
Equal precedence operations generally performed left-to-right
In addition to the precedence of each operator, the compiler also knows whether equal-precedence operators should be performed left-to-right (almost all) or right-to-left (basically only assignment).
Parentheses can be used to control the order of evaluation
If you have any doubt about the order of evaluation, or have a potentially confusing expression, use parentheses. Remember that one of your goals should be to make your programs as readable as possible. Use parentheses when it makes an expression easier to read, not must when they are absolutely required. Few programmers know the precedence of all operators, so it's common for extra parentheses to be used.
Unary (one operand) versus binary (two operand) operators
Unary operators have only one operand, for example, in
a = -b;
The "-" operator is the unary (one operand) operator which changes the sign of its operand.
a = b - c
The "-" operator is a binary (two operand) operator which subtracts c from b.
Most unary operators are performed before binary operators (exceptions "." (qualification), "[]" (subscription), and "()" (method call).
Example - Parentheses
When you can work out the precedence, it's often useful to use parentheses to figure out the order of evaluation. For example, let's say you're evaluating the following expression.
1 + 2 - 3 * 4 / 5
Addition and subtraction are equal in precedence and lower than multiplication and division, which are equal. Form the parenthesized form and work out the values in steps.
1 + 2 - 3 * 4 / 5
= (1 + 2) - ((3 * 4) / 5)
= 3 - (12/5)
= 3 - 2
The result of the integer division, 12/5, is 2 .= 1
Precedence table
This table gives the precedence of all operators. You may not be familiar with all operators, but take the advice on the right side and only learn a few precedences.
Operator Precedence
. [] (args) post ++ --
! ~ unary + - pre ++ --
(type) new
* / %
+ -
<< >> >>>
< <= > >= instanceof
== !=
&
^
|
&&
||
?:
= += -= etc
Remember only
- unary operators
- * / %
- + -
- comparisons
- && ||
- = assignments
Alternative notation - Dataflow diagram
Let's look at the expression x = a+b-c*d/e
, which can be parenthesized as x = ((a+b) - ((c*d)/e))
. Instead of parentheses, we can draw a diagram.
This dataflow diagram shows another way to think about expression evaluation.
Boxes represent values in memory, ovals represent operations, and arrows show the direction of data flow. The assignment operator ("=") is treated as an operator with low precedence by the compiler, but from a dataflow point of view it only moves data so it's represented as an arrow, not an operation.
Dataflow diagrams show which operations must necessarily be performed before others, but doesn't show which are actually performed first. Java performs most operations left-to-right, so the addition would, in principle, be performed before the multiplication. I believe reordering of operations that can have no side effects is allowed, however.
Alternative notation - Postfix - RPN
Postfix. Altho it's not directly relevant to learning Java, there are other systems for writing expressions that don't need parentheses or precedence. Normal mathematical notation is called infix notation because the operators occur in between the operands. A common alternative is called postfix notation where the operator is written after its two operands.
Example. For example, a+b
would be written as ab+
, and x = a+b-c*d/e
would be written as xab+cd*e/-=
.
RPN. This is often called Reverse Polish Notation in honor of the Polish mathematician Jan Lukasiewicz.
Postfix notation is used in the following, among others.
- Hewlett-Packard makes RPN calculators.
- The Postscript printer control language is postfix.
- The Forth programming language is RPN.
- Java source code is translated into postfix notation!
Bitwise Operators
It helps to know how integers are represented in binary. For example the decimal number 3 is represented as 11 in binary and the decimal number 5 is represented as 101 in binary.
Negative integers are store in two's complement form. For example, -4 is 1111 1111 1111 1111 1111 1111 1111 1100.
Bitwise operators can fall under 2 categories.>>,>>>,<< operators are called shift operators, which is covered in this post. Other operators are ~,&,| and ^ operators.
~ | Not operator |
^ | Xor or Exclusive OR |
| | OR |
& | And operator |
>> | Right shift |
>>> | Unsigned right shift |
<< | left shift |
Note that operands for Bitwise operators must be numeric datatypes(char, short, int, or long).
Examples - The bitwise operators
Operator | Usage | Example | Result | Reason |
& or and Operator | a & b | 3 & 5 | 1 | 1 if both bits are 1. |
| OR operator | a | b | 3 | 5 | 7 | 1 if either bit is 1. |
^ or xor operator | a ^ b | 3 ^ 5 | 6 | 1 if both bits are different. |
~ or not operator | ~a | ~3 | 4 | Inverts the bits. |
Left shift | n << p | 3 <<< 2 | 12 | Shifts the bits of n left p positions. Zero bits are shifted into the low-order positions. |
Right shift | n >> p | 5 >> 2 | 1 | Shifts the bits of n right p positions. If n is a 2's complement signed number, the sign bit is shifted into the high-order positions. |
Unsigned right shift | n >>> p | -4 >>> 28 | 15 | Shifts the bits of n right p positions. Zeros are shifted into the high-order positions. |
Tuesday, October 26, 2010
==, .equals(), compareTo(), and compare()
==,equals, compareTo, compare all help in comparing the object in one or other way.
Compares references, not values. The use of
==
with object references is generally limited to the following: - Comparing to see if a reference is null.
- Comparing two enum values. This works because there is only one object for each enum constant.
- You want to know if two references are to the same object
equals() method Usage : a.equals(b)
Compares values for equality. Because this method is defined in the Object class, from which all other classes are derived, it's automatically defined for every class. However, it doesn't perform an intelligent comparison for most classes unless the class overrides it. It has been defined in a meaningful way for most Java core classes. If it's not defined for a (user) class, it behaves the same as ==.
It turns out that defining equals()
isn't trivial; in fact it's moderately hard to get it right, especially in the case of subclasses. The best treatment of the issues is in Horstmann's Core Java Vol 1. See equals() method here.
Also to see == vs equals() , refer here.
compareTo() method a.compareTo(b)
is present in Comparable interface. Compares values and returns an int which tells if the values compare less than, equal, or greater than. If your class objects have a natural order, implement the Comparable<T> interface and define this method. All Java classes that have a natural ordering implement this (String, Double, BigInteger, ...).
For more on Comparable interface, refer here.
compare(a,b) method Usage : compare(a, b)
is implemented using Comparator interface. Compares values of two objects. This is implemented as part of the Comparator<T> interface, and the typical use is to define one or more small utility classes that implement this, to pass to methods such as sort()
or for use by sorting data structures such as TreeMap and TreeSet. You might want to create a Comparator object for the following.
- Multiple comparisons. To provide several different ways to sort something. For example, you might want to sort a Person class by name, ID, age, height, ... You would define a Comparator for each of these to pass to the
sort()
method.
- System class. To provide comparison methods for classes that you have no control over. For example, you could define a Comparator for Strings that compared them by length.
- Strategy pattern. To implement a strategy pattern, which is a situation where you want to represent an algorithm as an object that you can pass as a parameter, save in a data structure, etc.
For more on Comparator interface refer here.
Implementing compareTo (why we need it?)
Implementing Comparable allows
- calling Collections.sort and Collections.binarySearch
- calling Arrays.sort and Arrays.binarySearch
- using objects as keys in a TreeMap
- using objects as elements in a TreeSet
- anticommutation : x.compareTo(y) is the opposite sign of y.compareTo(x)
- exception symmetry : x.compareTo(y) throws exactly the same exceptions as y.compareTo(x)
- transitivity : if x.compareTo(y)>0 and y.compareTo(z)>0, then x.compareTo(z)>0 (and same for less than)
- if x.compareTo(y)==0, then x.compareTo(z) has the same sign as y.compareTo(z)
- consistency with equals is highly recommended, but not required : x.compareTo(y)==0, if and only if x.equals(y) ; consistency with equals is required for ensuring sorted collections (such as TreeSet) are well-behaved.
Compare the various types of fields as follows :
- numeric primitive : use < and >. There is an exception to this rule: float and double primitives should be compared using Float.compare(float, float) and Double.compare(double, double). This avoids problems associated with special border values.
- boolean primitive : use tests of the form (x && !y)
- Object : use compareTo. (Note that possibly-null fields present a problem : while x.equals(null) returns false, x.compareTo(null) will always throw a NullPointerException)
- type-safe enumeration : use compareTo, like any Object
- collection or array : Comparable does not seem to be intended for these kinds of fields. For example, List, Map and Set do not implement Comparable. As well, some collections have no definite order of iteration, so doing an element-by-element comparison cannot be meaningful in those cases.
All primitive wrapper classes implement Comparable. Note that Boolean did not implement Comparable until version 1.5, however.
Example:
import java.util.*; import java.io.*; public final class Account implements Comparable<Account> { //Constructor enum AccountType {CASH, MARGIN, RRSP};
public Account ( String aFirstName, String aLastName, int aAccountNumber, int aBalance, boolean aIsNewAccount, AccountType aAccountType ) { //..parameter validations elided fFirstName = aFirstName; fLastName = aLastName; fAccountNumber = aAccountNumber; fBalance = aBalance; fIsNewAccount = aIsNewAccount; fAccountType = aAccountType; } /** * @param aThat is a non-null Account. * * @throws NullPointerException if aThat is null. */ public int compareTo( Account aThat ) { final int BEFORE = -1; final int EQUAL = 0; final int AFTER = 1; //this optimization is usually worthwhile, and can
//always be added if ( this == aThat ) return EQUAL; //primitive numbers follow this form if (this.fAccountNumber < aThat.fAccountNumber) return BEFORE; if (this.fAccountNumber > aThat.fAccountNumber) return AFTER; //booleans follow this form if (!this.fIsNewAccount && aThat.fIsNewAccount) return BEFORE; if (this.fIsNewAccount && !aThat.fIsNewAccount) return AFTER; //objects, including type-safe enums, follow this form //note that null objects will throw an exception here int comparison = this.fAccountType.compareTo(aThat.fAccountType); if ( comparison != EQUAL ) return comparison; comparison = this.fLastName.compareTo(aThat.fLastName); if ( comparison != EQUAL ) return comparison; comparison = this.fFirstName.compareTo(aThat.fFirstName); if ( comparison != EQUAL ) return comparison; if (this.fBalance < aThat.fBalance) return BEFORE; if (this.fBalance > aThat.fBalance) return AFTER; //all comparisons have yielded equality //verify that compareTo is consistent with equals (optional) assert this.equals(aThat) : "compareTo inconsistent with equals."; return EQUAL; } /** * Define equality of state. */ @Override public boolean equals( Object aThat ) { if ( this == aThat ) return true; if ( !(aThat instanceof Account) ) return false; Account that = (Account)aThat; return ( this.fAccountNumber == that.fAccountNumber ) && ( this.fAccountType == that.fAccountType ) && ( this.fBalance == that.fBalance ) && ( this.fIsNewAccount == that.fIsNewAccount ) && ( this.fFirstName.equals(that.fFirstName) ) && ( this.fLastName.equals(that.fLastName) ); } /** * A class that overrides equals must also override hashCode. */ @Override public int hashCode() { int result = HashCodeUtil.SEED; result = HashCodeUtil.hash( result, fAccountNumber ); result = HashCodeUtil.hash( result, fAccountType ); result = HashCodeUtil.hash( result, fBalance ); result = HashCodeUtil.hash( result, fIsNewAccount ); result = HashCodeUtil.hash( result, fFirstName ); result = HashCodeUtil.hash( result, fLastName ); return result; } //// PRIVATE /////// private String fFirstName; //non-null private String fLastName; //non-null private int fAccountNumber; private int fBalance; private boolean fIsNewAccount; /** * Type of the account, expressed as a type-safe enumeration (non-null). */ private AccountType fAccountType; /** * Exercise compareTo. */ public static void main (String[] aArguments) { //Note the difference in behaviour in equals and compareTo, for nulls: String text = "blah"; Integer number = new Integer(10); //x.equals(null) always returns false: System.out.println("false: " + text.equals(null)); System.out.println("false: " + number.equals(null) ); //x.compareTo(null) always throws NullPointerException: //System.out.println( text.compareTo(null) ); //System.out.println( number.compareTo(null) ); Account flaubert = new Account( "Gustave", "Flaubert", 1003, 0,true, AccountType.MARGIN ); //all of these other versions of "flaubert" differ from the //original in only one field Account flaubert2 = new Account( "Guy", "Flaubert", 1003, 0, true, AccountType.MARGIN ); Account flaubert3 = new Account( "Gustave", "de Maupassant", 1003, 0, true, AccountType.MARGIN ); Account flaubert4 = new Account( "Gustave", "Flaubert", 2004, 0, true, AccountType.MARGIN ); Account flaubert5 = new Account( "Gustave", "Flaubert", 1003, 1, true, AccountType.MARGIN ); Account flaubert6 = new Account( "Gustave", "Flaubert", 1003, 0, false, AccountType.MARGIN ); Account flaubert7 = new Account( "Gustave", "Flaubert", 1003, 0, true, AccountType.CASH ); System.out.println( "0: " + flaubert.compareTo(flaubert) ); System.out.println( "first name +: " + flaubert2.compareTo(flaubert) ); //Note capital letters precede small letters System.out.println( "last name +: " + flaubert3.compareTo(flaubert) ); System.out.println( "acct number +: " + flaubert4.compareTo(flaubert) ); System.out.println( "balance +: " + flaubert5.compareTo(flaubert) ); System.out.println( "is new -: " + flaubert6.compareTo(flaubert) ); System.out.println( "account type -: " + flaubert7.compareTo(flaubert) ); } }
A sample run of this class gives:
>java -cp . Account
false: false
false: false
0: 0
first name +: 6
last name +: 30
acct number +: 1
balance +: 1
is new -: -1
account type -: -1