Header Ads Widget

Responsive Advertisement

Ticker

6/recent/ticker-posts

Java

Access Modifiers:


abstract 

This applies to classes and methods.

A class must be declared abstract if any of the following conditions is true :
  • The class has any abstract methods.
  • The class inherits any abstract methods but does not implement them.
  • The class declares that it implements an interface but does not implement all of its methods.
In a way, abstract is the opposite to final. A final class cannot be sub-classed but an abstract class must be sub-classed. An abstract class can have non-abstract methods.

When applied to a method, it means that it has not been implemented in its class. Any other class extending this class must either implement the inherited abstract method or itself be declared abstract.

final

This applies to classes, methods and variables.

A variable can be declared as final. Doing so prevents its contents being changed. This means a final variable must be initialized when it is declared. It is common coding convention to choose all uppercase identifiers for ‘final’ variables. Final variables do not occupy memory on a per-instance basis. Thus, it is essentially a constant. If a final variable is a reference to an object, it is the reference that must stay the same, not the object. It means that the reference cannot be assigned to some other object, but data of the object can be changed.

final class cannot be sub-classed.

final method cannot be overridden.

static

This can be applied to variables, methods and initializer blocks.

When applied to a variable, the variable belongs to the class itself and not to its objects. All the objects of the class share the variable. If you modify the value of a static variable in one object, the value gets changed for all the objects of the class since there is only one variable being shared among all the objects.

static initializer block is executed when the class is loaded.

Methods declared static have several restrictions:
  • They can only call other static methods.
  • They must only access static data.
  • They cannot refer to ‘this’ or ‘super’ in anyway.
  • static method cannot be overridden to be non static.

native

It can be applied to methods only.
It indicates that the method body is to be found elsewhere i.e. outside the JVM, in a library. Native code is written in a non java language and compiled for a single target machine type.

transient

It applies only to variables. A transient variable is not stored as part of its object’s persistent state. Many objects, especially those implementing Serializable or Externalizable interfaces, can have their states serialized and written to some destination outside the JVM. This is done by passing the object to the writeObject() method of the ObjectOutputStream class. If the stream is chained to a file output stream, then the object’s state is written to a file. If the stream is chained to a socket’s output stream then the object’s state is written to the network. In both cases, the object can be reconstituted by reading from an object input stream.

There will be times when an object will contain extremely sensitive data. Once an object is written to a  destination outside JVM, none of the Java’s elaborate security mechanisms is in effect. If you declare a variable transient, it’s value will not be written out during serialization.

volatile

It is applied only to variables. It indicates that such variables might be modified asynchronously, so the compiler takes special precautions. Volatile variables are of interest in multi-processor environments.

public

A class, method or variable declared public can be accessed by any other code in a program.

private

This member can only be accessed by other members of its class.

default

when a member does not have an explicit access specification, it is visible to subclass as well as to other classes in the same package.

protected

This allows access from everywhere but except for different package non-subclass.

Note: You cannot combine some of these modifiers together. Some of the cases are:
  • No two access modifiers can be combined. Such as public privateprotected public or private protected.
  • abstract and final.
  • Native methods cannot be abstract, or strictfp.
  • An abstract method cannot be staticfinalsynchronizednativeprivate, or strictfp.
For a given class, determine if a default constructor will be created, and if so, state the prototype of that constructor.

If there are no constructors defined in a class, Java provides a default constructor. This constructor is a no-args constructor and it simply sets all the fields of the object to their default values. So, all numeric data contained in the fields would be zeroed out, all boolean values would be set to false, and all reference variables set to null.

If there is even a single constructor defined in a class, Java will not create the default constructor. The signature of this default constructor is like this:
public ClassName () { }

where ClassName is the name of the class for which this constructor has been provided.

Write code using if and switch statements and identify legal argument types for these statements.

he if statement
The legal argument type for if statements is a boolean value i.e. true, false or any expression which evaluates to these values. In Java true and false are not represented by integers like in C or C++.
Only one statement can appear after if or else. If you want to include more statements, you will need to create a block using {}. You can also include the curly braces when using the if, even if there is only one statement in each clause. This makes it easy to add another statement at a later time, and you do not have to worry about forgetting the braces.
Nested if statements
When you nest if statements, the main thing to remember is that an else statement always refers to the nearest if statement that is within the same block as the else and that is not already associated with an else.
The if-else-if ladder
The if statements are executed from the top down. As soon as one of the conditions controlling the if is true, the statement associated with that if is executed, and the rest of the ladder is bypassed. If none of the conditions is true, then the final else statement will be executed. The final else acts as a default condition; that is, if all other conditional tests fail, then the last else statement is performed. If there is no final else and all other conditions are false, then no action will be taken.
The switch statement
It is Java’s multi-way branch statement. It provides an easy way to dispatch execution to different parts of your code based on the value of an expression. As such, it often provides a better alternative than a large series of if-else-if statements.
The switch expression must be of type byteshortint, or char; each of the values specified in the case statements must be of a type compatible with or assignable to the expression. Each case value must be a constant, not a variable. Duplicate case values are not allowed. A break statement is used inside the switch to terminate a statement sequence. When a break statement is encountered, execution branches to the first line of code that follows the entire switch statement. This has the effect of jumping out of the switch.
The break statement is optional. If it is omitted, execution will continue on into the next case. It is sometimes desirable to have multiple cases without break statements between them.
Nested switch statements
You can use a switch as part of the statement sequence of an outer switch. Since a switch statement defines its own block, no conflicts arise between the case constants in the  inner switch and those in the outer switch.
The important features of switch statement:
  • The switch differs from the if in that switch can test for equality, whereas if can evaluate any type of boolean expression.
  • No two case constants in the same switch can have identical values. Of course, a switch statement enclosed by an outer switch can have case constants in common.
  • switch statement is usually more efficient than a set of nested ifs.


Write code that makes proper use of exceptions and exception handling clauses (try, catch, finally) and declares methods and overriding methods that throw exceptions.

An exception is an abnormal condition that arises in a code-sequence at runtime. A Java exception is an object that describes an exceptional condition that has occurred in a piece of code. When an exceptional condition arises, an object representing that exception is created and thrown in the method that caused the error. That method may choose to handle the exception itself, or pass it on. Either way, at some time, the exception is caught and processed. Exceptions thrown by the java runtime system relate to fundamental errors that violate the rules of Java language or the constraints of the Java execution environment. Manually generated exceptions are typically used to report some error condition to the caller of the method.
Program statements that are monitored for exceptions are contained within a ‘try’ block. An exception thrown from the ‘try’ block is caught, using ‘catch’ block and handled in some rational way. System generated exceptions are automatically thrown by the Java runtime system. To manually throw an exception, use the keyword ‘throw’. Any exception that is thrown out of a method must be specified as such by a ‘throws’ clause. Any code that absolutely must be executed before a method returns is put in a ‘finally’ block.
Exception handling provides a powerful mechanism for controlling complex programs that have many dynamic runtime characteristics. It is important to think of trycatch and throw as clean ways to handle errors and unusual boundary conditions in your program’s logic. Whenever a method can fail, have it throw an exception.
Java’s exception handling statements should not be considered a general mechanism for non-local branching. If you do so, it will only confuse your code and make it hard to maintain.
Types of Exception :
All exception types are subclasses of the class Throwable. Immediately below Throwable are two subclasses that partition exceptions into two distinct branches. One branch is headed by Exception. This class is used for exceptional conditions that user programs should catch. This is also the class that you will subclass to create your own custom exception types. There is an important subclass of Exception, called RuntimeException. Exceptions of this type are automatically defined for the programs that you write, and include things such as division by zero and invalid array indexing.
The other branch is topped by Error, which defines exceptions that are not expected to be caught under normal circumstances by your programs. Exceptions of type Error are used by Java runtime system to indicate errors having to do with the runtime environment itself. Stack overflow is an example of such an error.
Uncaught exceptions:
Whenever an exception object is created and thrown by the runtime system, execution of the program stops, because once an exception has been thrown, it must be caught by an exception handler and dealt with immediately. If you do not supply any exception handlers, the exception is caught by the default handler provided by the Java runtime system.
The default handler displays a string describing the exception, prints a stack-trace from the point at which the exception has occurred, and terminates the program. The stack trace will always show the sequence of method invocations that led up to the error.
Effect on a thread
If an exception is thrown and it is not handled, the execution jumps to the end of the current method. The exception then appears in the caller of that method, and execution jumps to the end of the calling method. This continues until execution reaches  the top of the affected thread, at which point the thread dies.
try’ and ‘catch’
The default exception handler in JVM is useful for debugging. It is best to handle the exceptions yourself. Doing so provides two benefits. First, it allows you to fix the error. Second, it prevents the program from automatically terminating.
Once an exception is thrown, the program control transfers out of the ‘try’ block into the ‘catch’ block. Catch block is not called, so execution never returns to the try block from catch. Once the catch statement has executed, program control continues with the next line in the program following the entire try/catch block.
try and its catch statement form a unit. The scope of catch clause is restricted to those statements specified by the immediately preceding try block. A catch statement cannot catch an exception thrown by another trystatement (except in the case of nested try statements). The statements that are protected by ‘try’, must be enclosed within curly braces. That is they must be within a block. You cannot use try on a single statement.
The goal of most well constructed catch blocks should be to resolve the exceptional condition and then continue as if the error had never happened.
Multiple catch clauses:
In some cases, more than one exception could be raised by a single piece of code. To handle this type of situation, you can specify two or more catch blocks, each catching a different type of exception. When an exception is thrown, each catch statement is inspected in order, and the first one whose type matches that of the exception is executed. After one catch statement executes, the others are bypassed, and execution continues after thetry/catch block.
When you use multiple catch blocks, it is important to remember that exception subclasses must come before any of their superclasses. This is because a catch statement that uses a superclass will catch exceptions of that type plus any of its subclasses. Thus a subclass would never be reached if it came after its superclass. Further, in Java, unreachable code is an error.
Nested try statements:
Each time a try statement is entered, the context of that exception is pushed on the stack. If an inner try statement does not have a catch handler for a particular exception, the stack is unwound and the next try statement’scatch handlers are inspected for a match. This continues until one of the catch statements succeeds, or until all of the nested try statements are exhausted. If no catch statement matches, then the Java runtime system will handle the exception.
Nesting of try statements can occur in less obvious ways when method calls are involved. You can enclose a call to a method within a try block. Inside that method is another try statement. In this case, the try statement within the method is still nested inside the outer try block, which calls the method.
Displaying a description of an exception
Throwable overrides the toString() so that it returns a string containing a description of the exception. You can display this description in a println() statement by simply passing the exception as an argument.
finally
when exceptions are thrown, execution in a method takes a rather abrupt, non-linear path that alters the normal flow through the method. Depending upon how the method is coded, it is even possible for an exception to cause the method to return prematurely. This could be a problem in some methods. For example, if a method opens a file upon entry and closes it upon exit, you will not want the code that closes the file to be bypassed by the exception-handling mechanism. The ‘finally’ clause creates a block of code that will be executed whether or not an exception is thrown. If an exception is thrown, the finally block will execute even if no catch statement matches the exception. Any time a method is about to return to the caller from inside a try/catch block, via an uncaught exception or an explicit return statement, the ‘finally’ clause is also executed just before the method returns. This can be useful for closing file handles and freeing up any other resources that might have been allocated at the beginning of a method with the intent of disposing them before returning. The ‘finally’ clause is optional. However, each trystatement requires at least one catch or a finally clause.
If an exception arises with a matching catch block, then the finally block is executed after the catch block. If no exception arises, the finally block is executed after the try block. If an exception arises for which there is no catchblock, then the finally block is executed after the try block.
The circumstances that can prevent execution of finally block are :
  • The  death of the thread.
  • The use of System.exit()
  • Interruption of power supply to the CPU.
  • An exception arising in the finally block itself.
Any exception arising in the finally block can be handled via a try-catch. If no catch is found then control jumps out of the method from the point at which the exception is raised, perhaps leaving the finally block incompletely executed.
Catching multiple exceptions
catch block handles exceptions of the class specified in its definition, as well as exceptions that are subclasses of the one specified. If you wish to catch multiple exceptions which are related to each other by super class/ sub class relation, then the following points should be kept in mind :
  • The catch block specifying super class must come after the catch block which intends to catch the sub class.
  • Out of many catch blocks, you might have defined, only one catch block, which is the first applicable one, will be executed.
If exceptions are not related by super-sub relation then the order of catch blocks is not important. 
The throw statement
It is possible for a program to throw an exception explicitly using the ‘throw’ statement (e.g. throw object;). The object to be thrown must of type Throwable or a subclass of it. Simple types such as int or char as well as non-Throwable classes, such as String or Object, cannot be used as exceptions. There are two ways you can obtain a Throwable object: using a parameter into a catch clause or creating one with the ‘new’ operator.
The flow of execution stops immediately after the ‘throw’ statement; any subsequent statements are not executed. The nearest enclosing ‘try’ statement is inspected to see if it has a catch statement that matches the type of the exception. If it does find a match, control is transferred to that statement. If not, the next enclosing try statement is inspected and so on. If no matching catch block is found, then default exception handler halts the program and prints the stack trace.
All of Java’s built in runtime exceptions have two constructors: one with no parameters and one that takes a String parameter. When the second form is used, the argument specifies a string that describes the exception. This string is displayed when the object is used as an argument to print() or println(). It can also be obtained by a call to getMessage(), which is defined by Throwable.
throw statement should be conditional in some way so that it has a way to complete successfully.
The throws statement
If a method is capable of causing an exception that it does not handle itself, it must specify this behavior so that the callers of the method can guard themselves against that exception. It can be done by including a ‘throws’ clause in the method’s declaration. A throws clause lists the types of exceptions that a method might throw. This is necessary for all exceptions, except those of type Error or RuntimeException, or any of their subclasses. All other exceptions that a method can throw must be declared in the ‘throws’ clause. If they are not, a compile time error will result. If  a method declares that it throws more than one exception, class hierarchy of exceptions is important in the declaration - subclass coming before a super class.
Checked exceptions
The checked exceptions are problems that can arise in a correct program. These are concerned with difficulties with the environment such as user mistakes or I/O problems. Since these conditions can arise at anytime, a program must be able to handle and recover from them. The compiler checks whether a program has defined what is to be done when such conditions arise.
Exceptions and Overriding 
A method which overrides a method in a super class can only be declared to throw checked exceptions of classes which were either declared to be thrown by the method in super class or which are subclasses of those exceptions declared in the method of super class.
This restriction is because Java allows use of super class references as references to objects of subclass. If an overriding method were allowed to throw exceptions of super class of those declared for the overridden method, then overriding methods would be able to bypass the enforced checks for checked exceptions.
Java’s built in exceptions:
Inside the standard package java.lang, Java defines several exception classes. The most general of these are subclasses of RuntimeException. Since, java.lang is implicitly imported to all Java programs, most exceptions derived from RuntimeException are automatically available. They need not be included in any method’s throws list. They are called unchecked exceptions because the compiler does not check to see if a method handles, or throws these exceptions. Checked exceptions are those defined by java.lang that must be included in a method’s throws list if that method can generate one of these exceptions and does not handle it itself.
RuntimeException subclasses (unchecked):
  • ArithmeticException
  • ArrayIndexOutOfBoundsException
  • ArrayStoreException
  • ClassCastException
  • IllegalArgumentException
  • IllegalMonitorStateException
  • IllegalStateException
  • IllegalThreadStateException
  • IndexOutOfBoundsException
  • NegativeArraySizeException
  • NullPointerException
  • NumberFormatException
  • SecurityException
  • StringIndexOutOfBoundsException
  • UnsupportedOperationException
Checked Exceptions defined in java.lang:
  • ClassNotFoundException
  • CloneNotSupportedException
  • IllegalAccessException
  • InstantiationException
  • InterruptedException
  • NoSuchfieldException
  • NoSuchMethodException
Creating new Exception subclasses:
Although Java’s built-in exceptions handle most common errors, you may want to create your own exception types to handle situations specific to your applications. To do this, just define a subclass of Exception. Your subclasses do not need to implement anything actually – it is their existence in the type system that allows you to use them as exceptions.
The Exception class does not define any methods of its own. It does inherit those methods provided by Throwable. Thus all exceptions, including those that you create, have the methods defined by Throwable available to them. You may also wish to override one or more of these methods in exception classes that you create.
Methods defined in Throwable:
  • Throwable fillInStackTrace ()
  • String getLocalizedMessage ()
  • String getMessage ()
  • void printStackTrace ()
  • void printStackTrace (PrintStream stream)
  • void printStackTrace (Printwriter stream)
  • String toString ()
Section 4 : Language Fundamentals:
  • Identify correctly constructed source files, package declarations, import statements, class declarations (of all forms including inner classes), interface declarations and implementations (for java.lang.Runnable or other interface described in the test), method declarations (including the main method that is used to start execution of a class), variable declarations and identifiers.
Source Files
A source file should generally contain at most one top level public class definition. If a public class is present, the class name should match the unextended file name. A source file may contain an unlimited number of non public class definitions.
This is not a language requirement, but an implementation requirement of many compilers including the reference compilers from sun. It is therefore unwise to ignore this convention since doing so limits the portability of your source files ( but not, of course, your object files).
There are 3 top level elements that may or may not appear in a file. If they are present then the order must be
  • package declaration
  • import statements
  • class definitions
White spaces and comments may appear before or after any of these elements. 
Keywords and Identifiers 
Keywords and reserved words may not be used as identifiers. An identifier must begin with a letter, a dollar sign ($), an underscore ( _ ) or digits. You can use embedded keywords.
main method 
This method is declared public by convention. However it is a requirement that it be static so that it may be executed without the necessity of constructing an instance of the corresponding class. Its return type must be void. These conditions are necessary because when a Java program starts running, JVM looks for this method as the code to start execution of the program is placed in this method only.
Variables and Initialization
In Java, variables have two different lifetimes :
  • A member variable of a class is created when the instance is created and is accessible from any method in the class.
  • A local variable of a method is created on entry to the method, exists only during execution of the method, and is accessible only within the method.
A member variable may be initialized in its own declaration line : when this technique is used, non-static instance variables are initialized just before the class constructor is executed. Static variables are initialized at class load time.
Local variables are not initialized by the system – every such variable must be explicitly initialized before being used.



State the correspondence between index values in the argument array passed to a main method and command line arguments. Identify all Java Programming Language keywords and correctly constructed identifiers.


Command line arguments and the main () method :

Whatever arguments are passed as command line arguments while executing a Java program are placed in the String [] array parameter of the main method. When there are no arguments, the String array is an empty array. If you pass a single argument, it is placed at the array index 0. So, args[0] corresponds to this argument. Thus the number of arguments becomes the length of the array and the arguments are accessed in the program in the usual way of accessing elements of an array.

Java keywords :


abstract
double
int
strictfp
boolean
else
interface
super
break
extends
long
switch
byte
final
native
synchronized
case
finally
new
this
catch
float
package
throw
char
for
private
throws
class
goto
protected
transient
const
if
public
try
continue
implements
return
void
default
import
short
volatile
do
instanceOf
static
while

Apart from these 48 keywords, there are three more words : nulltrue and false. Many authors list these words as keywords too. But, Java Language Specification says that these are not keywords but literals.


State the effect of using a variable or array element of any kind when no explicit assignment has been made to it.

All the instance and static variables of a class are automatically initialized to their default values before use even if there has not been explicit assignment to them. This is, however, not true for local variables ( variables declared inside a method ). As a result of this, when you try to use a variable without initializing it first, you get their default value. For example, an int variable will be initialized to zero, float will be initialized to 0.0, a boolean will be initialized to false and so on. A reference variable gets initialized to null by default. In case of a local variable, however, your code will not compile if you do not initialize the variable before trying to use it.
All the elements of an array get initialized to their default values, whether the array is an instance or static member of a class, or a local variable of a method. If you try to use an array before initializing it, the compiler will not complain. But you will get a NullPointerException at the runtime, as the array itself will get initialized to null value automatically. If you do initialize the array by using new operator, you will not get this exception at runtime. However, if you have not initialized its elements, all you will get is the default values of its elements.

State the range of all primitive data types and declare literal values for String and all primitive types using all permitted formats, bases, and representations.

Primitive data types
The char type ( 16 bit ) is integral but unsigned. If the most significant nine bits of a char are all zero, then the encoding is same as seven bit ASCII. 
Range of primitive types
Data Type WidthMin. Value Max. Value
byte8-128127
short16-32,76832767
int32-2,147,483,6482,147,483,647
long64-9,223,372,036,854,775,8089,223,372,036,854,775,807
char160x0 (Unicode value)0xffff (Unicode value)
float321.4012984643248170e-453.40282346638528860e+38
double644.94065645841246544e-3241.79769313486231570e+308

Literals 
char literals : A literal representing a character is placed in single quotes e.g. 'c'.
Integer literals : Any integer literal defaults to int. To represent a long value, the numerical expression must contain either L or l as suffix.
Floating point literals : In order to be interpreted as a floating point literal a numerical expression must contain one of the following :
  • A decimal point.
  • The letter E or e : 55.21 E
  • The suffix F or f for float
  • The suffix D or d for double
A floating point literal with no F or D suffix defaults to a 64 bit double literal. 
String Literals

String literals are represented in double quotes e.g. " Java ".
 Overloading, Overriding, Runtime Type, and Object Orientation
State the benefits of encapsulation in object oriented design and write code that implements tightly encapsulated classes and the relationships "is a" and "has a".

Benefits of Object oriented implementation 

These benefits accrue from two particular features. The first of these and perhaps the most important is the notion of abstract data type. The second of these is the extensibility provided by inheritance. 

Abstract data type 

An abstract data type simply means a well encapsulated aggregate of data and behavior. The primitive data types defined in any programming language are in fact abstract data types, albeit not user defined. The state of an object should be represented only with variables of private accessibility. All behavior should be accessed only via methods. By insisting that the variables inside an object are not accessible outside the object, you ensure that the nature of those variables is irrelevant outside the object. This in turn means that you can change the nature of the storage, for maintenance purposes, for performance improvement, or for any other reason freely. This freedom is one of the greatest benefits of encapsulation.
Inheritance:  For this please see the next section on overloading and overriding.
"is a" and "has a"
An object can perform many functions and may contain different types of data. The source of these data and behavior may come from two sources. The first source is from inheritance from its parent classes and the other source is any object it may contain as its state.
Each class in Java, except Object class, is a subclass of another. In any class hierarchy, any class can be called by the name of any class which is above it in the hierarchy. Let us consider a class called Vehicle. One of its subclasses can be called Car. Cars can of different models like Ford or Mercedes. Now any Ford can be called a Car. It is also a vehicle. This relationship is known as "is a" relationship.
A car has many components, each of which can belong to a different hierarchy of classes. For example, let us consider brakes. Brakes can be of different types (classes). There can be a whole hierarchy of brakes. Since a car has brakes, this relationship is known as "has a" relationship.

Write code to invoke overridden or overloaded methods and parental or overloaded constructors; and describe the effect of invoking these methods.

Overloading
Method overloading is one of the ways that java implements polymorphism. When an overloaded method is called, java uses the type and/or number of arguments to decide which version of the overloaded method to actually call. Overloaded methods may or may not have different return types. When java encounters a call to an overloaded method, it simply executes the version of the method whose parameters match the arguments used in the call.
However, this match need not always be exact. In some cases java’s automatic type conversions can play a role in overload resolution. Java will employ its automatic type conversion only if no exact match is found.
The important points to note:
  • A difference in return type only is not sufficient to constitute an overload and is illegal.
  • You should restrict your use of overloaded method names to situations where the methods really are performing the same basic function with different data.
  • The language treats methods with overloaded names as totally different methods and as such they can have different return types. However, since overloaded methods perform the same job with different data sets, they should produce same return type normally. There is one particular condition, however, under which it is sensible to define different return types. This is the situation where the return type is derived from the argument type and is exactly parallel with the arithmetic operators.
  • Overloaded methods may call one another simply by providing a normal method call with an appropriately formed argument list. 
 
Overriding 

In a class hierarchy, when a method in a subclass has the same name and type signature as a method in its superclass, then the method in the subclass is said to override the method in the superclass. When an overridden method is called from within a subclass, it will always refer to the version of that method defined by the subclass. The version in the superclass will be hidden. If you wish to access the superclass’ version of an overridden method, you can do so by using ‘super’. 

In order for any particular method to override another correctly :

  • The return type, method name, type and order of arguments must be identical to those of a method in a parent class.
  • The accessibility must not be more restrictive than original method.

The method must not throw checked exceptions of classes that are not possible for the original method.

Parental Constructors:
Whenever a subclass needs to refer to its immediate superclass, it can do so by use of the keyword ‘super’. This keyword has two general forms. The first calls the superclass constructor. The second is used to access a member of the superclass that has been hidden by a member of a subclass.  
  1. Constructor call: The call to the superclass’ constructor must always be the first statement executed inside a subclass’ constructor.
  2. The second form of ‘super’ acts like ‘this’, except that it always refers to the superclass of the subclass in which it is used (e.g. super.member). This form of super is most applicable to situations in which member names of a subclass hide members by the same name in the superclass.
In a class hierarchy, constructors are called in order of derivation from superclass to subclass. Further, since super () must be the first statement executed in a subclass’ constructor, this order is the same whether or not super () is used. If super () is not used, then the default or no-arguments constructor of each superclass will be executed. This is because a superclass has no knowledge of any subclass, any initialization it needs to perform is separate from and possibly prerequisite to any initialization performed by the subclass. Therefore it must be executed first.
Overloaded Constructors:
These behave as overloaded methods.



java.util Package



Make appropriate selection of collection classes/interfaces to suit specified behavior requirements.



Collection (Interface)

Methods

1.boolean add (Object o);  ensures that this collection contains the specified element.
2.boolean addAll (Collection c); the behavior of this operation is undefined if the specified collection is modified while the operation is in progress. This implies that the behavior of this operation is undefined if the specified collection is this collection, and this collection is non empty.
3.void clear();
4.boolean contains(Object o);
5.boolean containsAll(Collection c);
6.boolean equals(Object o);
7.boolean isEmpty();
8.boolean iterator();  There are no guarantees concerning the order in which the elements are returned unless this collection is an instance of some class that provides a guarantee.
9.boolean remove(Object o);
10.boolean removeAll(Collection c);
11.boolean retainAll(Collection c);
12.int size ();  If this collection contains more than Integer.MAX_VALUE, returns Integer.MAX_VALUE.
13.Object [] toArray();
14.Object [] toArray(Object [] a); returns an array containing all of the elements in this collection whose runtime type is that of the specified array.

Sub-interfaces  
  • List
  • Set
  • BeanContext
  • BeanContextServices

Implementing classes 
  • AbstractCollection



Set (Interface)

Allows at most one null element. Great care must be taken if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equal comparisons while the object is an element in the set. A special case of this prohibition is that it is not permissible for a set to contain itself as an element.

Implementing classes: HashSet

Methods : Inherited from Collection



List (Interface)

List is an ordered collection and allows duplicate elements. So multiple null elements are allowed too. Operations like positional access to list elements may execute in time proportional to the index value for some implementations like LinkedList. Thus, iterating over the elements in a list is typically preferable to indexing through it, if the caller does not know the implementation.

The methods provided for search for a specified object should be used with caution from a performance point of view, as they may prove to be costly linear searches. While it is permissible for lists to contain themselves as elements, extreme caution is advised: the equals() and hashCode() methods are no longer well defined on such a list. 

Methods ( Other than those inherited from Collection) 
  • void add (int index, Object element);
  • boolean addAll (int index, Collection c);
  • Object get (int index);
  • int indexOf (Object o);  returns –1 if o is not in the list.
  • int lastIndexOf (Object o);  returns –1 if o is not in the list.
  • ListIterator listIterator();
  • ListIterator listIterator(int index);  returns a list iterator of the elements in the list in proper sequence starting at the specified position in this list.
  • Object remove(int index);
  • Object set(int index, Object element);
  • List subList(int from index, int to index);  fromIndex inclusive, toIndex exclusive.



Map (Interface)

Maps keys to values. A map cannot contain duplicate keys. Each key can map to at most one value. This interface takes the place of Dictionary class, which was a totally abstract class.

Map interface three collection views, which allow a map’s contents to be viewed as a set of keys, collection of values, and set of key-value mappings. The order of a map is defined as the order in which the iterators on the map’s collection views return their elements.

Some map implementations, like TreeMap class make specific guarantees as to their order, others, like HashMap class do not.

Great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equal comparisons while the object is a key in the map. A special case of this prohibition is that it is not permissible for a map to contain itself as a key. While it is permissible for a map to contain itself as a value, extreme caution is advised: the equals () and hashCode() methods are no longer well defined on such a map.

Methods 
  • void clear ();
  • boolean containsKey(Object key);
  • boolean containsValue(Object value);
  • Set entrySet()  returns a set view of the mappings in the map.
  • Object get(Object key);  returns the value to which this map maps the specified key.
  • boolean isEmpty();
  • Set keySet();  returns a set view of the keys in this map.
  • Object put(Object key, Object value);  returns previous value associated with this key and replaces that specified value. Returns null if there was no value associated with this key earlier.
  • void putAll(Map t);
  • Object remove(Object key); removes the mapping for this key if present.
  • int size(); returns the key-value mapping number.
  • Collection values(); returns a collection view of the values contained in this map.

All the three views returned by keySet(), values() and entrySet() are backed by the map, so changes to the map are reflected in the set, and vice-versa.
  
Sub-interfaces : SortedMap

Implementing classes :
  • AbstractMap
  • HashMap
  • HashTable
  • WeakHashMap
  • Attributes
  • RenderingHints



SortedSet and SortedMap


These interfaces extend Set and Map respectively, for implementations that sort their elements in a specific order. Objects can specify their natural order by implementing the Comparable interface, or be dictated a total order by a comparator which implements the Comparator interface.

Comparator

          int compare(Object o1, Object o2);

Since this method tests for equality, it is recommended that its implementation does not contradict the semantics of the equals() method. Specific Comparator implementations can be constructed to order elements according to some custom order, or the default comparator which uses the natural order of the elements can be used.

Comparable

          int compareTo(Object o);

A class can define the natural order of its instances by implementing this interface. Then its objects can be used 
  • As elements in a sorted set.
  • As keys in a sorted map.
  • In lists which can be sorted automatically by Collections.sort() method.

This natural order of Comparable objects can be overruled by passing a Comparator to the constructor when the sorted set or map is created.


SortedSet ( implementing class – TreeSet) 
  • SortedSet headSet(Object toElement); returns a view of a portion of this sorted set, whose elements are strictly less than the specified element.
  • SortedSet tailSet(Object fromElement); returns a view of a portion of this sorted set, whose elements are equal to or more than the specified element.
  • SortedSet subSet(Object fromElement, Object toElement); fromElement inclusive, toElement exclusive.
  • Object first();
  • Object last();
  • Comparator comparator(); this returns the comparator associated with this sorted set, or null if it uses natural ordering of its elements.

SortedMap ( implementing class – TreeMap) 
  • SortedMap headMap(Object toKey); returns a view of a portion of this sorted Map, whose Keys are strictly less than the specified Key.
  • SortedMap tailMap(Object fromKey); returns a view of a portion of this sorted Map, whose Keys are equal to or more than the specified Key.
  • SortedMap subMap(Object fromKey, Object toKey); fromKey inclusive, toKey exclusive.
  • Object firstKey ();
  • Object lastKey ();
  • Comparator comparator(); this returns the comparator associated with this sorted Map, or null if it uses natural ordering of its keys.


ArrayList


The size(), isEmpty(), get(), set(), iterator() and listIterator() operations run in constant time. The add() operation runs in amortized constant time i.e. adding n elements requires o(n) time. All other operations run in linear time.

An application can increase the capacity of an ArrayList object before adding a large number of elements using ensureCapacity(). This may reduce the amount of incremental reallocation.

The iterators returned by iterator() and listIterator() methods are fail-fast. Thus in the face of concurrent modification, the iterator() fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior later, by throwing a  ConcurrentModificationException.

ArrayList allows null elements.

Constructors: 

  • ArrayList()
  • ArrayList(Collection c)
  • ArrayList(int initialCapacity)


HashMap


Allows null values and keys. It is roughly equivalent to HashTable, except that it is unsynchronized and permits nulls. Makes no guarantee as to order of the Map. It is HashTable based implementation. Constant time performance for get() and put(). Iteration over collection views requires time proportionate to the capacity of the HashMap instance. Thus it is very important not to set the initial capacity too high, or the load factor too low if the iteration performance is important. Initial capacity and load factor affect its performance. When the number of entries exceeds the product of load factor and the current capacity, the capacity is roughly doubled. Default load factor is 0.75.

Iterators returned by all of this class’s collection-view methods are fail-fast.

Constructors : 
  • HashMap()
  • HashMap(int initialCapacity)
  • HashMap(int initialCapacity, float loadFactor)
  • HashMap(Map)


HashSet


Backed by a HashTable ( actually a HashMap instance). No guarantees as to the iteration order of the set. Offers constant time performance for basic operations like add(), remove(), contains() and size(). Rest like as in HashMap. Iterators fail fast. Default load factor is 0.75.

Constructors : 
  • HashSet()
  • HashSet (int initialCapacity)
  • HashSet (int initialCapacity, float loadFactor)
  • HashSet (Collection c)



HashTable


Extends Dictionary implements Map. It is synchronized. The iterators returned by iterator() and listIterator() of the collections returned by HashTable’s collection-view methods are fail fast. The Enumerations returned by its keys() and values() are not fail fast. Default load factor is 0.75.

Constructors : 
  • HashTable ()
  • HashTable (int initialCapacity)
  • HashTable (int initialCapacity, float loadFactor)
  • HashTable (Map m)



TreeMap


Implements SortedMap extends AbstractMap. This class guarantees that map will be in ascending-key order, sorted as per natural order for the key’s class(comparable) or by comparator provided at creation time. This implementation provides guaranteed log(n) time cost for containsKey(), get(), put() and remove() operations. Iterators are fail fast.

Constructors : 
  • TreeMap ()
  • TreeMap (Comparator c)
  • TreeMap (SortedMap sm)
  • TreeMap (Map t)



TreeSet


Implements Set, backed by a  TreeMap instance.

Constructors :
  • TreeSet ()
  • TreeSet (Comparator c)
  • TreeSet (SortedSet sm)
  • TreeSet (Collection c)



Vector


Extends AbstractList, implements List. Iterators fail fast, Enumerations are not.

Constructors :
  • Vector ()
  • Vector (Comparator c)
  • Vector (int initialCapacity)
  • Vector (int initialCapacity, int capacityIncrement)




Choosing an implementation

Lists

Type
Methods
Get
Iteration
Insert
Remove
Array
1
1
n.a.
n.a.
ArrayList
2
3
2
2
LinkedList
4
2
1
1
Vector
3
4
3
2


For random access lookups and iteration arrays are fastest. The best approach is probably to choose ArrayList as default, and to change to LinkedList if there are performance problems due to many insertions and removals from the middle of the list. While working with a fixed size group of elements array is best.

Sets

The performance of HashSet is generally superior to TreeSet for all operations, in particular addition and look up (the two most important operations). The only reason TreeSet exists is because it maintains its elements in sorted order, so you only use it when you need a sorted list.

Maps

When choosing between implementations of Map, the size of the map is what most strongly affects performance. When you are using a map your first choice should be HashMap, and only if you need a constantly sorted map will you need a TreeMap. HashTable is generally a bit slower than HashMap. TreeMap     should be used as a way to create an ordered list. The behavior of a tree is that it is always in order and does not have to be specially sorted. Once you fill a TreeMap you can call keySet() to get a set view, and then use toArray(). HashMap is designed to rapidly find things. Also, you can easily create a HashMap from a TreeMap with a single object creation.




Points to Remember

1. Some of the operations in the Collection interface are optional, meaning that a collection may choose not to provide a proper implementation of such an operation. In such a case, an UnsupportedOperationException is thrown when the optional operation is invoked.

2. The inherited method add(Object o) from Collection into the List will append the specified element to the end of the list. The inherited remove(Object o) removes the first occurrence of the Object from the list.

3. Apart from other utility methods for searching, sorting etc. Collections class’s methods can be used to customize collection implementations. The important considerations are
  • Thread safety
  • Data immutability
The Java2 collection classes, except for Vector and HashTable, are not thread safe i.e. their integrity is jeopardized by concurrent access.

  • Type synchronizedType(Type t)
  • Type unmodifiableType(Type t)

where Type is one of the following
  • Collection
  • List
  • Map
  • Set
  • SortedSet
  • SortedMap

4. Linked lists do not support fast random access. If you want to see the nth element, you have to start at the beginning and skip past the first n-1 elements first. Nevertheless, the LinkedList class supplies a get( int index), which is not very efficient. If you find yourself using it, you are probably using wrong data-structure for your problem. For every call of get(index) search begins at the beginning.

5. One should always define hashCode() for objects that one inserts in a hash table.

6. Adding an element to a tree is slower than adding it to a hash table, but it is still much faster than array or LinkedList.


Post a Comment

0 Comments