Approach Java (2)

Free Online Courses With Personalized Certificate
[Him. Uni. Friends] Approach Java – 5.4 Adding power to language (Conditional constructs, loops and more) – Ternary Operator
From:
“Varun Chopra” <varunspace@yahoo.com>
To:
hpumca@yahoogroups.com, hpufriends@googlegroups.com
| Java Ternary OperatorIf you are a man/woman of few words, you will like this operator. It gives you a weapon to shorten lengthy if-else syntax and express that in a single statement. Its syntax is:
operand1 ? operand2 : operand3; You see there are 3 operands hence ?: is called a ternary operator in Java. operand1 in this case has to be a boolean literal or a boolean expression. operand2 and operand3 can be of any primitive or object type, but they have to belong to same set of data (or class heirarchy). In case operand1 is true, operand2 is returned as result of above statement otherwise operand3 is returned. Hence this is equivalent to if (operand1) { return operand2; } else { return operand3; } Enough theory, some examples follow (read comments to understand if any doubt): int x = true? 1:2;//since operand1 is true so 1 is returned int y = 5>6? 1:2;//since 5 is not >6 hence 2 is returned boolean result = 45/9 == 30/6 ? true:false; StringBuilder strB = true && (false || true) ? new StringBuilder(“Yey”):null;//null can be assigned to an object float f = new String(“xyz”).equals(“XyZ”) ? 0.5:”test”;//compilation error – operand 1 and 2 do not belong to same data set float f1 = new String(“xyz”).equalsIgnoreCase(“XyZ”) ? 0.5:15;//wrong – cannot convert from double to float List list = 1 & 1 ? new ArrayList(10):new LinkedList(10);//both ArrayList and LinkedList are subclasses of List, hence code is fine Here’s running example: package approach.java.lesson5; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class TernaryOperatorExamples { public static void main(String [] args) { int x = true? 1:2;//since operand1 is true so 1 is returned print(“x = “+x);
int y = 5>6? 1:2;//since 5 is not >6 hence 2 is returned print(“y = “+y); boolean result = (45/9 == 30/6) ? true:false; print(“result = “+result); StringBuilder strB = true && (false || true) ? new StringBuilder(“Yey”):null;//null can be assigned to an object print(“strB = “+strB); float f = new String(“xyz”).equals(“XyZ”) ? 0.5f:0f;//compilation error – operand 1 and 2 do not belong to same data set print(“f = “+f); float f1 = new String(“xyz”).equalsIgnoreCase(“XyZ”) ? 0.5f:15;//this is fine print(“f1 = “+f1); List list = (null == new String()) ? new ArrayList(10):new LinkedList();//both ArrayList and LinkedList are subclasses of List, hence code is fine print(“list class = “+list.getClass().getCanonicalName()); } private static void print(Object x) { System.out.println(x); } } compile and run: javac approach/java/lesson5/TernaryOperatorExamples.java java approach.java.lesson5.TernaryOperatorExamples x = 1 y = 2 result = true strB = Yey f = 0.0 f1 = 0.5 list class = java.util.LinkedList That’s it for now, we will keep making progress. Questions are welcome. regards Varun
|
Approach Java – 5.5 Adding power to language (Conditional constructs, loops and more) – For Statement
From:
“Varun Chopra” <varunspace@yahoo.com>
To:
hpumca@yahoogroups.com, hpufriends@googlegroups.com
| Loop ConstructsSeveral times we need to repetitively execute a piece of code with same/different set of data. Loop constructs in Java give us the facility to meet such requirements. Let’s start with for statement, probably the most used looping statement in Java.
for statement Syntax of for statement is: for (initialization;check-condition;update) //single statement for (initialization;check-condition;update) { //statements } “initialization” represents a single or “a set of statements”, which are executed on once during loop execution. “check-condition” represents a single boolean expression that is executed at the beginning of loop and after every iteration. Loop will continue until check-condition returns false. “update” represents a single or “a set of statements”, which are executed after every iteration (not at the beginning of loop). e.g. //loop below runs 10 times – for i=0 to 9, prints value of i everytime. for (int i=0; i<10; i++) { System.out.println(i); } Let’s take a look at several more examples, do read comments to understand code. /** * */ package approach.java.lesson5; /** * @author Varun * */ public class ForLoopTest { /** * @param args */ public static void main(String[] args) { testSingleStatementInBody(); testMultipleStatementsInBody(); testMultipleInitializers(); testMultipleUpdaters(); testMultipleInitializersAndUpdaters(); testOnlyCheckerStatement(); testNestedLoop(); testNonNumericStatements(); testNoStatement(); } private static void testSingleStatementInBody() { print(“\n ——- testSingleStatementInBody() starts ——-”); //simple for that prints numbers 0 to 4, single statement under for statement so no { } required for (int numberCounter = 0; numberCounter<5; numberCounter++) print(“numberCounter:”+numberCounter); print(“——- testSingleStatementInBody() ends ——-”); } private static void testMultipleStatementsInBody() { print(“\n ——- testMultipleStatementsInBody() starts ——-”); //for that doubles each number from 0 to 4 and prints it, multiple statement under for statement so { } required for (int numberCounter = 0; numberCounter<5; numberCounter++) { int doubleValue = numberCounter * 2; print(“doubleValue:”+doubleValue); } print(“——- testMultipleStatementsInBody() ends ——-”); } private static void testMultipleInitializers() { print(“\n ——- testMultipleInitializers() starts ——-”); //we can have multiple , separated statements in initializer part, this example illustrates that, but all initializer variables must be of same datatype //later we will see we can have multiple update statements as well for (int numberCounter = 0, secondInitializer = 5; numberCounter<5; numberCounter++) { int calculatedValue = numberCounter * 2 + secondInitializer; print(“calculatedValue:”+calculatedValue); } print(“——- testMultipleInitializers() ends ——-”); }
private static void testMultipleUpdaters() { print(“\n ——- testMultipleUpdaters() starts ——-”); //we can have multiple , separated statements in update part, this example illustrates that int secondUpdater = 5; for (int numberCounter = 0; numberCounter<5; numberCounter++, secondUpdater–) { int calculatedValue = numberCounter * 2 + secondUpdater; print(“calculatedValue:”+calculatedValue); } print(“——- testMultipleUpdaters() ends ——-”); }
private static void testMultipleInitializersAndUpdaters() { print(“\n ——- testMultipleInitializersAndUpdaters() starts ——-”); //we can have multiple , separated statements in initializer and update parts, this example illustrates that for (int numberCounter = 0, secondNumberCounter=5; numberCounter<5; numberCounter++, secondNumberCounter–) { print(“numberCounter:”+numberCounter); print(“secondNumberCounter:”+secondNumberCounter);//there can be more as well } print(“——- testMultipleInitializersAndUpdaters() ends ——-”); }
private static void testOnlyCheckerStatement() { print(“\n ——- testOnlyCheckerStatement() starts ——-”); //we can leave initializer and updater parts blank, check this example int numberCounter = 0; for (; numberCounter<5; ) { print(“numberCounter:”+numberCounter); numberCounter++; } print(“——- testOnlyCheckerStatement() ends ——-”); }
private static void testNestedLoop() { print(“\n ——- testNestedLoop() starts ——-”); //for loops can be nested for (int numberCounter = 0; numberCounter<5; numberCounter++ ) { print(“numberCounter:”+numberCounter); for (int numberCounter2 = 0; numberCounter2<3; numberCounter2++ ) { print(“nested loop numberCounter2:”+numberCounter2); } } print(“——- testNestedLoop() ends ——-”); }
private static void testNonNumericStatements() { print(“\n ——- testNonNumericStatements() starts ——-”); //we can loop with non-numeric statements as well char c; for (String str = “hello”; !str.equalsIgnoreCase(“helloAA”); str+=c) { c = ‘A’; print(“str = “+str); } print(“——- testNonNumericStatements() ends ——-”); } private static void testNoStatement() { print(“\n ——- testNoStatement() starts ——-”); //we can loop with no statement – but this is infinite loop, we need break statement to quit for (;;) { print(“infinite loop, quitting with the help of break “); //we need break statement to quit break; } print(“——- testNoStatement() ends ——-”); }
private static void print(Object msg) { System.out.println(msg); } } Compile and run. Output is: ——- testSingleStatementInBody() starts ——- numberCounter:0 numberCounter:1 numberCounter:2 numberCounter:3 numberCounter:4 ——- testSingleStatementInBody() ends ——- ——- testMultipleStatementsInBody() starts ——- doubleValue:0 doubleValue:2 doubleValue:4 doubleValue:6 doubleValue:8 ——- testMultipleStatementsInBody() ends ——- ——- testMultipleInitializers() starts ——- calculatedValue:5 calculatedValue:7 calculatedValue:9 calculatedValue:11 calculatedValue:13 ——- testMultipleInitializers() ends ——- ——- testMultipleUpdaters() starts ——- calculatedValue:5 calculatedValue:6 calculatedValue:7 calculatedValue:8 calculatedValue:9 ——- testMultipleUpdaters() ends ——- ——- testMultipleInitializersAndUpdaters() starts ——- numberCounter:0 secondNumberCounter:5 numberCounter:1 secondNumberCounter:4 numberCounter:2 secondNumberCounter:3 numberCounter:3 secondNumberCounter:2 numberCounter:4 secondNumberCounter:1 ——- testMultipleInitializersAndUpdaters() ends ——- ——- testOnlyCheckerStatement() starts ——- numberCounter:0 numberCounter:1 numberCounter:2 numberCounter:3 numberCounter:4 ——- testOnlyCheckerStatement() ends ——- ——- testNestedLoop() starts ——- numberCounter:0 nested loop numberCounter2:0 nested loop numberCounter2:1 nested loop numberCounter2:2 numberCounter:1 nested loop numberCounter2:0 nested loop numberCounter2:1 nested loop numberCounter2:2 numberCounter:2 nested loop numberCounter2:0 nested loop numberCounter2:1 nested loop numberCounter2:2 numberCounter:3 nested loop numberCounter2:0 nested loop numberCounter2:1 nested loop numberCounter2:2 numberCounter:4 nested loop numberCounter2:0 nested loop numberCounter2:1 nested loop numberCounter2:2 ——- testNestedLoop() ends ——- ——- testNonNumericStatements() starts ——- str = hello str = helloA ——- testNonNumericStatements() ends ——- ——- testNoStatement() starts ——- infinite loop, quitting with the help of break ——- testNoStatement() ends ——- I hope above examples clarify everything about for loop statement. Do go through all comments and run the code. We will cover another version of for loop, called as for-each, introduced in jdk 1.5 in next lesson. Questions are welcome. regards Varun
|
Approach Java – 5.6 Adding power to language (Conditional constructs, loops and more) – For-Each Statement
From:
“Varun Chopra” <varunspace@yahoo.com>
To:
hpumca@yahoogroups.com, hpufriends@googlegroups.com
| for-eachJdk 1.5 introduced a new form of for loop. It makes it much more convenient to traverse a list of items stored in collection (we will go through collections in next chapter) or an array. Its syntax is:
for (Type item : itemList) { //any code; } Here Type is the datatype of items stored in itemList. Read item : itemList as “item in itemList”; Let’s go through an example. package approach.java.lesson5; public class ForEachLoopTest { static String[] items = new String[10]; static { for (int i = 0; i < items.length; i++) { items[i] = “I am “+ i; } } public static void main(String[] args) { listItems(); } private static void listItems() { print(“\n ——- listItems() starts ——-”); for (String item : items) print(item); print(“——- listItems() ends ——-”); }
private static void print(Object msg) { System.out.println(msg); } } Compile and run above code, and we get following output: ——- listItems() starts ——- I am 0 I am 1 I am 2 I am 3 I am 4 I am 5 I am 6 I am 7 I am 8 I am 9 ——- listItems() ends ——- Few important things: 1. You can have only one iteration variable in for-each (remember you can have multiple iteration variable in standard for-loop statement, all of same datatype though). For e.g. following is not possible: for (Type item, item1 : itemList) { //any code; } 2. For each loop can be used to iterate over all collection object that implements java.lang.Iterable iterface or an array. So you can iterate objects of your own class if either they are stored in an array or your class implements java.lang.Iterable interface. See example below: package approach.java.lesson5; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ForEachLoopTest { public static void main(String[] args) { listDummyItems(); } private static void listDummyItems() { print(“\n ——- listDummyItems() starts ——-”); MyOwnList myList = new MyOwnList(); for (Dummy dummyItem : myList) print(dummyItem.getSalary()); print(“——- listDummyItems() ends ——-”); }
private static void print(Object msg) { System.out.println(msg); } } class MyOwnList implements Iterable<Dummy> { static List<Dummy> dummyList = new ArrayList<Dummy>(10); static { for (int i = 0; i < 10; i++) { dummyList.add(new Dummy(100+i)); } }
public Iterator<Dummy> iterator() { return dummyList.iterator(); } } class Dummy { private float salary; public Dummy(float salary) { super(); this.salary = salary; } /** * @return the salary */ public float getSalary() { return salary; } } Compile and run above code, you should get following output: ——- listDummyItems() starts ——- 100.0 101.0 102.0 103.0 104.0 105.0 106.0 107.0 108.0 109.0 ——- listDummyItems() ends ——- Since MyOwnList implements Iterable interface (Iterable<Dummy> means Iterator of Dummy class objects), so we can use for-each loop on its object. That’s what following statement in listDummyItems method does: for (Dummy dummyItem : myList) Now internally Dummy dummyItem : myList statement invokes iterator method of MyOwnList class. Note that for implementing Iterable interface, iterator() method must be implemented (which in this case returns dummyList.iterator() object). Once iterator on Dummy objects is available, for-each can do its job. Let me know if you have any question. We will continue with other loop statements java provides in next lesson. regards Varun
|
Approach Java – 5.7 Adding power to language – Do While, While, Continue and break
From:
“Varun Chopra” <varunspace@yahoo.com>
To:
hpumca@yahoogroups.com, hpufriends@googlegroups.com
| Under loop constructs we still have to cover following loop statements:* while loop
* do-while loop In addition, following Control statements are also pending before we move on to next chapter: * continue and labels * break and labels Let’s start. while loop Using while loop we can keep on executing a piece of code “while a boolean expression holds true”. Its syntax is: while (boolean expression) //single statement of code OR while (boolean expression) { //piece of code } If you went through last lesson on for-each loop, you would have seen following method that prints salary of each Dummy item. private static void listDummyItems() { print(“\n ——- listDummyItems() starts ——-”); MyOwnList myList = new MyOwnList(); for (Dummy dummyItem : myList) print(dummyItem.getSalary()); print(“——- listDummyItems() ends ——-”); } Let’s re-write above code with while loop. private static void listDummyItems() { print(“\n ——- listDummyItems() starts ——-”); MyOwnList myList = new MyOwnList();
Iterator<Dummy> iterator = myList.iterator(); while (iterator.hasNext()) { Dummy dummyItem = iterator.next(); print(dummyItem.getSalary()); } print(“——- listDummyItems() ends ——-”); } As with any other loop, you can have a complex boolean expression as well: while (a==b && (c>d || !x) ) { //code } do-while loop do-while loop is also for similar purpose, except that here condition validity is checked at the end of loop (after executing loop body). This is an important point, because this means loop body is executed once even if the condition was false! Its syntax is: do //single statement of code while (boolean expression); OR do { //piece of code } while (boolean expression); Let’s re-write same code with do-while loop now: private static void listDummyItems() { print(“\n ——- listDummyItems() starts ——-”); MyOwnList myList = new MyOwnList();
Iterator<Dummy> iterator = myList.iterator(); do { Dummy dummyItem = iterator.next(); print(dummyItem.getSalary()); } while (iterator.hasNext()); print(“——- listDummyItems() ends ——-”); } One problem with above code is, if there are no items in myList then it will fail. This is because code is trying to use the item object before checking for its existence. continue statement Sometimes, in a loop, we want to skip a piece of code for some iterations. continue statement gives us a very easy way to skip code-segments for irrelevant iterations. Its syntax is: continue; here’s a simple example: for (int i=1; i < 10; i++ ) { if (i % 2 != 0) continue; System.out.println(i+” is even”); } continue; statement can be used in any loop construct explained earlier. Let’s take another example, while going through the salary of employees, if we see a salary greater than 100000, we want to print that as VERY HIGH SALARY, deduct 5% of salary as charity amount from it and print the charity and remaining salary, otherwise we want to skip printing. Here’s how to do this using continue: package approach.java.lesson5; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ContinueTest { private final static float VERY_HIGH_SALARY = 10000.0f;
public static void main(String[] args) { processEmployeeRecords(); } private static void processEmployeeRecords() { print(“\n ——- processDummyItems() starts ——-”); MyOwnListLocal myList = new MyOwnListLocal(); if (myList.getItemCount() == 0) print(“No items in list”); else { Iterator<Employee> iterator = myList.iterator(); do { Employee employee = iterator.next(); if (employee.getSalary() <= VERY_HIGH_SALARY ) continue;
processSalary(employee.getSalary()); } while (iterator.hasNext()); } print(“——- processDummyItems() ends ——-”); }
private static void processSalary(float salary) { float charity = calculateCharity(salary); float remainingSalary = salary – charity; print(“Total Salary – “+salary); print(“Charity – “+ charity); print(“Remaining Salary – “+remainingSalary); print(“\n\n”); }
private static float calculateCharity(float salary) { return salary * .05f; } private static void print(Object msg) { System.out.println(msg); } } class MyOwnListLocal implements Iterable<Employee> { static List<Employee> dummyList = new ArrayList<Employee>(10); static { for (int i = 0; i < 10; i++) { dummyList.add(new Employee(9998+i)); } }
public Iterator<Employee> iterator() { return dummyList.iterator(); } public int getItemCount() { return dummyList.size(); } } class Employee { private float salary; public Employee(float salary) { super(); this.salary = salary; } /** * @return the salary */ public float getSalary() { return salary; } } Compile and run, following should be the output: ——- processDummyItems() starts ——- Total Salary – 10001.0 Charity – 500.05002 Remaining Salary – 9500.95 Total Salary - 10002.0 Charity – 500.1 Remaining Salary – 9501.9 Total Salary - 10003.0 Charity – 500.15 Remaining Salary – 9502.85 Total Salary - 10004.0 Charity – 500.2 Remaining Salary – 9503.8 Total Salary - 10005.0 Charity – 500.25 Remaining Salary – 9504.75 Total Salary - 10006.0 Charity – 500.30002 Remaining Salary – 9505.7 Total Salary - 10007.0 Charity – 500.35 Remaining Salary – 9506.65 ——- processDummyItems() ends ——- Labeled continue A statement in java can be preceded with a label like below: label: statement label: {code block} Here label is to be replaced with a text. label can be any identifier, even same as class name or package name or any other variable used in same program. It does not create conflicts. Labeled continue statement attempts to continue next iteration of enclosing loop with label attached. Its syntax is: continue label; Here’s an example of continue with label: package approach.java.lesson5; public class LabeledStatementContinueTest { public static void main(String[] args) { OUTER: for (int j=77; j < 99; j++ ) { INNER: for (int i=4567+j; i < 5545; i++ ) { if (i % 77 == 0) { System.out.println(“first multiple of 77 found, this is “+i); continue;//continue inner } if (i % 87 == 0) { System.out.println(“first multiple of 87 found, this is “+i); continue OUTER;//continue OUTER } } } System.out.println(“END”); } } In above code continue; statement without label continues with next iteration of inner loop. But continue OUTER; continues with next iteration of outer loop. Without label, if you want to continue with OUTER loop, you would need 2 continue; statements (inside inner and outer loop blocks). break statement There are situations when we want control to come out of a loop without processing remaining iterations. In that case we can use break; statement. Its syntax is: break; here’s a simple example: package approach.java.lesson5; public class BreakTest { public static void main(String[] args) { for (int i=4567; i < 5545; i++ ) { if (i % 77 == 0) { System.out.println(“first multiple of 77 found, this is “+i); break; } } } } On running we get: first multiple of 77 found, this is 4620 Labeled break; We can use labeled break statement to come out of an enclosing block or several nested loops. We need to perpend label with the target statement from which we want to jump OUT. Example: package approach.java.lesson5; public class BreakLabelTest { public static void main(String[] args) { OUTER: for (int j=77; j < 99; j++ ) { INNER: for (int i=4567+j; i < 5545; i++ ) { if (i % 77 == 0) { System.out.println(“first multiple of 77 found, this is “+i); break;//break from inner } if (i % 87 == 0) { System.out.println(“first multiple of 87 found, this is “+i); break OUTER;//break from OUTER } } } System.out.println(“END”); } } In above code break; statement without label breaks control out of inner loop. break OUTER; breaks control out of outer loop. Without label, if you want to break out of OUTER loop, you would need 2 break; statements (inside inner and outer loop blocks). Note that following will not compile: TESTLABEL1:System.out.println(“Test Label 1″); break TESTLABEL1; But following will TESTLABEL1: { System.out.println(“Test Label 1″); break TESTLABEL1; } This is again because break label; statement can be used to break out of enclosing block, it cannot be used to jump to a statement. Don’t compare it with goto statement. With this we are done with chapter 5. We will start with chapter 6 lessons from next time. Questions are welcome. Here’s a question for you: Q - Give an example in which “do-while loop” is better suited than “while loop” regards Varun
|
Approach Java – 6.1 Java Generics
From:
“Varun Chopra” <varunspace@yahoo.com>
To:
hpumca@yahoogroups.com, hpufriends@googlegroups.com
| Here’s Update TOC, we are at Chapter 6 now:
1. Introduction to OOPs
2. Java Overview (P/F independence, versions, JRE, JDK) 3. Java programming basics (class structure, compiling & executing programs, member variables, methods, constructors, creating objects, data types) 4. Introduction to Packages and scope identifiers (import statement as well) 5. Adding power to language (Conditional constructs, loops and more) 6. Data Structures (Collections) – Generics and Enums 7. Exception Handling 8. File Handling 9. JDBC 10. Closing and ForwardLet’s start with first lesson in Chapter 6. Java Generics Before we delve into collections framework in Java, it will be necessary for us to go via Generics, which was a new feature added in Java 1.5. Those familiar with C++ templates may find it similar in nature. Generics is a vast topic and there are whole books dedicated to it. Our focus in this lesson will be short and precise, to understand Generics and explore some possibilities with it using few examples. For more detailed study of Java Generics, some references will be provided at the end. What are Generics List is an interface in java to store a collection of elements of any type (extending Object class). ArrayList is a concrete class that extends List interface. Suppose want to have a List type variable that stores only int type values. Look at code below: List l = new ArrayList(); l.add(5); l.add(10); l.add(15); l.add(“Hi, I am a String but still going into int list”);//works – no problem As you can see, we cannot prevent a String to enter into a List variable. This is because List can hold any type of data. We are not able to restrict List to int type data only. Generics allow us to have type-strict structures and classes. Here’s same code using Generics: List<Integer> l = new ArrayList<Integer>(); l.add(5); l.add(10); l.add(15); l.add(“Hi, I am a String but still going into int list”);//will not compile We changed List to List<Integer> and ArrayList to ArrayList<Integer> to explicitly state that variable can hold only Integer data. Now we can be assured that last statement to add text data in this list will not compile. This shows a glimpse of power of Generics. Generics give us a syntax to specify parameterized types, so as to be more type-strict while writing code and improve quality of our code by catching a lot of datatype mismatch errors at compile time. This is one aspect of Generics. Another aspect is to write a method to be used for multiple type of arguments. Suppose we want to write a method to return the argument back if the argument extends Serializable and Comparable interfaces. One option is to use Object as datatype of argument as below: package approach.java.lesson6; import java.io.Serializable; public class GenericsPower { public static void main(String[] args) { Integer i = (Integer)getObjectBack1(new Integer(1));//line 1 Double d = (Double)getObjectBack1(new Double(1.2));//line 2 StringBuilder s = (StringBuilder)getObjectBack1(new StringBuilder(1));//line 3 } public static Object getObjectBack1(Object n1) { boolean ins = n1 instanceof Serializable; if (!ins) { throw new RuntimeException(“Not Serializable”); }
ins = n1 instanceof Comparable; if (!ins) { throw new RuntimeException(“Not Comparable”); }
System.out.println(“Test Passed, sending object of type:”+n1.getClass().getName()+ ” back”); return n1; } } On running above code, you should get following output: Test Passed, sending object of type:java.lang.Integer back Test Passed, sending object of type:java.lang.Double back Exception in thread “main” java.lang.RuntimeException: Not Comparable at approach.java.lesson6.GenericsPower.getObjectBack1(GenericsPower.java:25) at approach.java.lesson6.GenericsPower.main(GenericsPower.java:11) The advantage of using Object as argument type is we can call getObjectBack1() method using any type of argument. But there are few problems as well: 1. We need to explicitly cast the result back from Object to required type (check line 1,2 and 3) 2. We can pass illegal type of arguments which do not extend Serializable/Comparable interface (line 3 above). A better option is to use parameterized types, like below: package approach.java.lesson6; import java.io.Serializable; public class GenericsPower { public static void main(String[] args) { Integer i = getObjectBack2(new Integer(1));//line 1 Double d = getObjectBack2(new Double(1.2));//line 2 StringBuilder s = getObjectBack2(new StringBuilder(1));//line 3 -WILL NOT COMPILE } public static <T extends Serializable & Comparable> T getObjectBack2(T n1) { System.out.println(“Test Passed, sending object of type:”+n1.getClass().getName()+ ” back”); return n1; } } Look at the signature of getObjectBack2 method. It takes an argument of type T, where T is just a placeholder of actual class name. But this syntax explicitly states that T must be a class/interface that extends/implements Serializable and Comparable interfaces. T is also the return type of method (since we want to return the same object back). With this syntax above 2 problems are solved – no explicit casts and compile time check of passing illegal arguments. Isn’t Generics good!! We have just scratched the surface of what Generics can do for us. We will go little further into its features and behind the scenes processing of generics before moving on to Collections. Let me know if you have any generics question or you want to share an example showing possibilities with Generics. Have a good time Varun
|
Approach Java – 6.2 Java Generics
From:
“Varun Chopra” <varunspace@yahoo.com>
To:
hpumca@yahoogroups.com, hpufriends@googlegroups.com
| Let’s look at few more aspects of Generics before moving onto Collections framework.Generics and Subtypes
Integer is a subtype of Number class. But List<Integer> is not a subclass of List<Number>. To understand why, check code below: List<Number> numberList = new ArrayList<Number>();//line 1 List<Integer> integerList = new ArrayList<Integer>();//line 2 integerList.add(10);//line 3
integerList.add(10.0);//line 4 – NOT VALID numberList.add(10.0);//line 5 – VALID numberList = integerList;//line 6 – NOT VALID – COMPILATION ERROR Line 4 is not valid above because we cannot add a double value to integerList. But line 5 is valid, because we certainly can add a double value to numberList. Since different rules apply to these lists, hence integerList cannot be assigned to numberList even though Integer is a subclass of Number. A compilation error will result on line 6. Wildcard character As said earlier, inheritance relation between classes does not imply their parameterized structures are compatible to each other. Suppose we want to write a method that emails every element of Number lists. This means that method should work for Integer as well as Double (or any other subclass of Number) elements. Here’s how we attempt it first: private static void emailList(List<Number> l) { for (Number n : l) { //email(n); } } Here’s how we try to call it for Integer list: List<Integer> integerList = new ArrayList<Integer>(); integerList.add(10); emailList(integerList);//COMPILATION ERROR Not surprisingly, this won’t work. Why? Because emailList expects an argument of List<Number> which integerList is not. What do we do now? Try wildcard, change List<Number> to List<?>: private static void emailList(List<?> l) { for (Number n : l) { //email(n); } } Now the client code works: List<Integer> integerList = new ArrayList<Integer>(); integerList.add(10); emailList(integerList);//Works ? is a wildcard character, which should be read as “Any Type”. This means that emailList() method can accept list of any type of elements. So we can use this method to process List<Integer> as well as List<Double> (and List<String>). But how can a code be so generic? A method that can work on any kind of list, isn’t that strange? How does that method know what kind of operations can be performed on list of data passed? After all, method calls on list of integers may be significantly different from method calls on string or custom object list. What if wildcard method attempts to add another element to the list which does not conform to datatype of passed parameter, something like below: private static void emailList(List<?> l) { //I am adding my own element l.add(“Text Element”);//line 1 >> WRONG for (Number n : l) { //email(n); } } If we pass an Integer list to emailList, line 1 above will add an incorrect value to our list. We don’t want that, right? Well you will be happy (and may be down) to know that using wildcard comes with a lot of restrictions from Java language. Several methods cannot be called on arguments passed, especially those which cannot work without adhering to exact datatype of arguments. add() method under List is such a method hence that cannot be called and will result in compilation error (line 1 above) Wildcard bounds If you recall, we wanted a method that can process only List<Number>. List<?> is too generic that can take lists of all types. We can bound type of arguments a method can take by using bounds. * List<? extends Number> – Here Number is the upper bound for ?. This will ensure only lists of type Number or one of its subclass can be passed * List<? super Integer> - Here Integer is the lower bound for ?. This will ensure only lists of type Integer or one of its superclass (base class – like Number, Object) can be passed Wildcard Capture When we use an argument of type List<?>, compiler internally assumes a datatype for ?. This type is ‘unknown’ and is called as wildcard capture. This is why when we try to add a specific type of element (suppose String type) to List<?> compiler complains. Any specific is considered incompatible to wildcard capture (or unknown type). Behind the scenes (Type Erasure) One very important thing to understand is all parameterized types are limited up to compilation phase. There is no implications of them at runtime. You must have noticed in this and last lesson that any attempt to use generic types in wrong way is reported at compile time itself. That is natural because that is one major benefit of using generic types. It strengthens compile time checking. At compile time all parameterized types are removed and are converted to generic (base) classes. That means List<String> is converted to List. This process is called “Type Erasure”. This is done to make sure old pieces of code (written without generics) continue to work. You can assume that after type erasure, your parameterized code looks just like you used to write code without parameterized types. Here’s an example: Suppose you have to traverse an integer list. Code without Parameterized types will look like this: List intList = getList(); for (Object o : intList) { Integer i = Integer(o); process(i); } Code with parameterized type (before erasure) will be like this: List<Integer> intList = getList(); for (Integer i : intList) { process(i); } Code after erasure will look like this: List intList = getList(); for (Object i : intList) { Integer i = Integer(o); process(i); } You can see, code after erasure is similar to what we write without Parameterized types. Type Erasure ensures any code written before parameterized types will continue to work with new JVMs. And parameterized types give us much more type safely and less ClassCastExceptions. This was all we had to cover on Java Generics. This is a vast topic and various possibilities and intricacies exist in using them. You are encouraged to read more on them on net. I am providing some References below: Java Generics FAQ by Angelika Langer – http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html O’Reilly Book Excerpts: Java in a Nutshell, 5th Edition, Part 1 – http://www.onjava.com/pub/a/onjava/excerpt/javaian5_chap04/index.html O’Reilly Book Excerpts: Java in a Nutshell, 5th Edition, Part 2 – http://www.onjava.com/pub/a/onjava/excerpt/javaian5_chap04/index1.html regards Varun
|
[Him. Uni. Friends] Approach Java – 6.3 Java Arrays
From:
“Varun Chopra” <varunspace@yahoo.com>
To:
hpumca@yahoogroups.com, hpufriends@googlegroups.com
| ArraysIf you notice we have not covered Java arrays so far.
Since we do not have a separate chapter for arrays, I will cover them here before jumping over to collections (I know more delay, but we are making progress Arrays in Java An array is a collection of elements of same datatype. Java supports arrays of primitive as well as object types, single as well as multi-dimensional. Here’s how to declare a one-dimensional array in Java: type[] arrayName = new type[length]; OR type arrayName[] = new type[length]; length is the number of elements in array. Number of elements is fixed but since Java arrays are allocated space at runtime, length can be a variable as well as we will see below. for e.g. int[] intArray = new int[10];//total 10 elements, index starts from 0 String[] strArray = new String[5];//total 5 elements String strArray1[] = new String[5];//total 5 elements String[][] strArray2D = new String[5][5];//total 5*5 elements String[][] strArray2DVariable = new String[5][];//total elements unknown String[] strArrayUnknown = new String[getNumberOfElements()];//call a function to get number of elements As you can see above, while declaring arrays of multiple dimensions, size of only first dimension is required to be specified. For second dimension you can have different number of elements per first dimension element, like below: String[][] strArray2DVariable = new String[5][];//total elements unknown strArray2DVariable[0] = new String[6];//6 second dem. elements for first element, note that index 0 gives first element strArray2DVariable[1] = new String[10];//10 second dem. elements for second element, note that index 1 gives second element Each array variable in Java is considered a reference type element (like objects). Index of first element is 0. Assigning values to arrays By default each array element is assigned a value by JVM. All object type elements are assigned null and primitives are assigned 0. Explicit assignment of values to array elements can be done in 2 ways: a) bulk assignment – Bulk assignment assigns value to each array element at the time of initialization. It also calculates number of elements by itself looking at number of values provided. Few examples: String[] strAry = new String[]{“element 0″, “element 1″, “element 2″, “element 3″}; String strAry1[] = {“element 0″, “element 1″, “element 2″, “element 3″}; int[] intAry1 = new int[]{1, 2, 3, 4}; int[] intAry2 = {1, 2, 3, 4}; b) individual assignment String[] strArray = new String[5]; strArray[0] = “element 1″; strArray[1] = “element 2″; strArray[2] = “element 3″; strArray[3] = “element 4″; strArray[4] = “element 5″; Traversing arrays Arrays can be traversed serially or a random element can be accessed using its index. for-each loops makes it very easy to traverse single or multi-dimensional arrays. Check this code and send me any question you have on this: package approach.java.lesson6; public class Arrays { public static void main(String[] args) {
System.out.println(“**** Single dim array demo ****”); oneDimArrayDemo();
System.out.println(“**** Multi dim array demo ****”); twoDimArrayDemo();
oneDimArrayDemoBulkAssignment();
} private static void oneDimArrayDemo() { String[] strAry = new String[getNumberOfElements()]; System.out.println(“strAry array size >> “+strAry.length); //assign values individually for (int counter=0; counter < strAry.length; counter++) { strAry[counter] = “element “+(counter+1); } // traverse and display array elements serially using for-each loop for (String element : strAry) { System.out.println(element); } } private static void twoDimArrayDemo() { String[][] strAry = new String[2][]; System.out.println(“strAry array size >> “+strAry.length); //assign values individually for (int counter=0; counter < strAry.length; counter++) { strAry[counter] = new String[counter+1]; for (int innercounter=0; innercounter < strAry[counter].length; innercounter++) { strAry[counter][innercounter] = “element “+counter+” ,”+innercounter; } } // traverse and display array elements serially using for-each loop for (String[] outerElement : strAry) { for (String innerElement : outerElement) { System.out.println(innerElement); } } }
private static int getNumberOfElements() { return 10;//you can get it from database or a file } private static void oneDimArrayDemoBulkAssignment() { String[] strAry = new String[]{“element 0″, “element 1″, “element 2″, “element 3″}; String strAry1[] = {“element 0″, “element 1″, “element 2″, “element 3″}; int[] intAry1 = new int[]{1, 2, 3, 4}; int[] intAry2 = {1, 2, 3, 4}; } } compile and run, following output should be displayed: **** Single dim array demo **** strAry array size >> 10 element 1 element 2 element 3 element 4 element 5 element 6 element 7 element 8 element 9 element 10 **** Multi dim array demo **** strAry array size >> 2 element 0 ,0 element 1 ,0 element 1 ,1 Array garbage collection If you assign null to an array variable, all its values are gone and it can be garbage collected by jvm. int[] intAry2 = {1, 2, 3, 4}; intAry2 = null;//can be garbage collected We have covered most of what is necessary of arrays in Java. If you have anything specific to ask do email me or to the group. We can start with collections now from next lesson onwards. regards Varun From: Varun Chopra <varunspace@yahoo.com> To: hpufriends@googlegroups.com; hpumca@yahoogroups.com Sent: Wednesday, April 22, 2009 6:09:10 PM Subject: [Him. Uni. Friends] Approach Java – 6.4 Java Collections Framework
I know I am late in writing this lesson, but as usual I was stuck in too many things. Let’s start friends. So we are to start with collections in java. Collections in java are also known as “Collections Framework” because this is a thoughtfully designed inter-related set of interfaces and classes to support flexible usage and extensions thereof. If that sounds complex then skip it and move on with me. Collections framework provides several structures (remember data structures?) to store multiple data values. Multiple data values may be a list of values or key-value pairs. Values here refer to primitive as well as reference types. We read about java arrays in a recent lesson. You may be thinking that an array is also a collection so why do we need another structure to store a list. There are several reasons, most important of which are: a) Arrays cannot be dynamically extended, their size, once set, is fixed b) Arrays can store only one type of elements, we may need to mix different types of data in a list c) Arrays are not strongly typed (they cannot be parameterized) d) We can not avoid duplicate elements in arrays, sometimes we may need to Hence we need more than an array. Collections framework provides us several options as we will see later. Secondly, we may not have a list of data always. Sometimes there are key-value pairs. For e.g. if we want to store marks obtained by students in a subject, we cannot store them in a list. Because then we will not be able to track which student has how many marks. We need something like this: student1 > 43 (Here student1 is the key and 43 is value.) student2 > 45 student3 > 55 and so on…. For such values we need a structure to support mapping of key to the value. Collections provide us great power in that by providing several map structures to pick the one that fits our need. Let me give you an overview in brief of what all is there in Collections that we will cover in coming lessons. Collections framework provides following interfaces: Collection Set (extends Collection) List (extends Collection) Queue (extends Collection) SortedSet (extends Set) Map SortedMap (extends Map) Collection is the basic interface for structures that support storing list of values. Set (unique value list), List (duplicates allowed), Queue (First In First Out list, duplicates allowed), SortedSet (a Set that keep values ordered) are interfaces that extend Collection interface. Since all list type structures have several things in common (like adding/removing single value, adding/removing in bulk, iterating values) so it makes sense to have a parent interface to them, which precisely Collection is. On the other hand, to store key value pairs same interface won’t work because structure is different. Therefore there is a separate interface called Map for that. Map declares basic operations similar to Collection interface but for key-value pairs. Operations to store key-value pair(s), delete pairs, get maps size are some examples of operations common to any type of map structure. SortedMap extends Map interface to have a specialized interface for maps that keep data sorted according to key. Note that in a map structure value can be duplicate but key will never. That’s a short lesson to start with collections, in next lesson I will explain more about List based interfaces and their classes. Jul 27, 2009 Lists We will try to cover Lists under Collections chapter today. In Java, there are 2 types of lists – ArrayList and LinkedList. If you have gone through Data Structures in your studies, these names will sound familiar to you. ArrayLists are extendable arrays, elements are stored sequentially and new elements are added to the end of the list by default. LinkedList is also extendable and elements in it are also added to the end by default but some operations are more efficient in LinkedLists than in ArrayLists because of the way they are implemented. Operations like insertion/deletion from the middle of the list are very slow in ArrayList because all elements following the affected position need to be moved in this case. While in case of LinkedLists, insertion/deletion in the middle is efficient because it just needs re-pointing the pointers (go through Linked Lists concept online if you need to know what they are!). Let’s now look at actual classes/interfaces in Java to support ArrayList and LinkedList. List<T> is an interface in Java that extends Collection<T> interface. T is a placeholder for data type (remember Parametrized types?). ArrayList<T> is a class that implements List<T> interface. Similarly LinkedList<T> class implements List<T> interface. List<T> interface gets following important methods inherited from Collection<T> interface: add(T o) – Adds T to the list object add(int index, T element) – Adds element at position index in the list ArrayList class adds following important methods of its own to inherited list: ensureCapacity(int minCapacity) – Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements LinkedList class adds following important methods of its own to the inherited list to make it more convenient to work with linkedlists: addFirst(T o) – inserts the given element at the beginning of this list. offer(T o) – Adds the specified element as the tail (last element) of this list. Last 4 methods offer, element, peek and poll are from Queue<T> interface, which is another interface in Collections framework. To not to confuse you will too many things, I will leave it up to you to go through Queue concept and interface whenever you have time. For now just remember that LinkedList class also implements Queue interface hence its methods. Examples: Ok now let’s go through some examples of ArrayLists and LinkedLists. As usual, par attention to comments to understand code. ArrayList example: Class below creates and manipulates a list of names. Various arraylist operations are invoked to give you an idea of what they do. Go through main() method statement by statement to understand operations: package pkg1; Going through the code should be simple, you will see different methods being called and their impact on the list. Here’s the output when I run above class at my end: here’s How the list looks after adding names : LinkedList Example One remarkable thing about interfaces (or inheritance) is that with small change we can get entirely different implementation of same operations. In above class if we change just one statement List<String> names = new ArrayList<String>(); to following: List<String> names = new LinkedList<String>(); we will get linkedlist implementation of same methods. Hence above class will work without any change. I have done the same. But I added one more method testLinkedListSpecificOperations() to give example of linked list class’s own methods. Note that we need to case to LinkedList class before we can call linked list specific methods. Here’s the code: package pkg1; And here’s the output on running LinkedList class: here’s How the list looks after adding names : I am leaving now, will be back with next topic under collections soon. Jul 29, 2009 In last lesson we went through ArrayList and LinkedList. In this lesson we will cover Queue. Queue Java 1.5 added Queue interface to Java api. It contains following methods: element() – Retrieves, but does not remove, the head of this queue. We already went through LinkedList which implements Queue interface and we also went through code examples of Queue methods. So you should be comfortable with Queues in general (remember Queue concept from data structure world – FIFO). In this lesson we will look at concept and code example of a special type of queue known as Priority Queue. Priority Queue is a topic you must be familiar with if you have studied Data Structures subject. Still I will give brief introduction to Priority Queues here. Priority queue is also a queue but each element has a priority associated to it. Element having highest priority is considered at the front of the queue and that with lowest priority is at the rear. In Java, PriorityQueue class is an implementation of this concept. PriorityQueue implements Queue interface. Now coming back to priority, by default priority is ascending order of queue elements (also called as natural ordering of elements). Suppose I add 12, 13, 2, 7, 6 to a PriorityQueue. By default 2 will be the element at the front and 13 at rear. So if I peek(), I should get 2 (element with least value has highest priority) – let’s test this right now, go through code below: package pkg1; When I run it I get: Front Element = 2 Note that PriorityQueue is not FIFO, so all queues do not behave in FIFO way although fundamental queue concept is based on FIFO. Another important point is although 2 is the least value but it has highest priority. This means in priority queue, element with least value is returned at the front as highest priority element. Custom Priority What about ordering on the basis of our own logic. As an example, suppose student admission to MCA is going on. If 2 students have same number of marks then logic is to compare their age. Younger one is given preference over older student. In this case we need to have more complex logic to set priorities. This logic is a part of a class called Comparator. Comparator contains the logic we want to base priorities upon and is passed to PriorityQueue constructor while creating its object. Here’s the constructor signature: PriorityQueue(int initialCapacity, Comparator<? super T> comparator) – Creates a PriorityQueue with the specified initial capacity that orders its elements according to the specified comparator. This constructor takes 2 arguments. First is initial capacity (i.e. initial estimate of how many elements will be stored in queue. Remember that queue is extendable so this initial value does not restrict us from adding more than specified number of elements.) Second is object of type Comparator<? super T>. Comparator<T> is an interface provided by java with a single method compare(T o1, T o2). We extend this interface and implement compare method according to our logic (so compare is the method where we will put our student comparison logic for admission). compare() method must return 0 if objects are equal, -ve value (generally -1) if o1 has less priority than o2 and +ve value (generally 1) if o2 has higher priority than o1. Going back to student example, suppose we have data of following students: Ankit- marks 70.2, age 18.5 years If you carefully go through data above, Arti has highest marks so irrespective of her age she gets preference over other students. Second is Dora with 70.21 marks. Thirdly Ankit, Camy and Eesha have same marks, hence logic will compare their age which gives Camy > Eesha > Ankit. Finally Bunty comes to last place with minimum marks. But as I said earlier, in priority queue, element with least value is returned at the front. Therefore if we run the code with above logic we will get results in reverse order, i.e. Bunty package pkg1; When I run it I get following output: Bunty Exactly that we anticipated. If we want results in reverse order just change -1 to +1 and +1 to -1 in compare() method as below: private static Comparator<Student> studentComparator = new Comparator<Student>() Now if we run, we get following output: Arti That’s all we have to cover on PriorityQueue. In next lesson we will go through Set and SortedSet.
|

