1. Everything in java is object. Even the java programs. 2. java objects are never placed in Static storage or any stack. On stack the object references are kept. Objects are kept on Heap. 3. Heap allocation takes more time than Stack Allocation. (i.e. when you use keyword new) 4. Constants are placed in Code area with program. 5. java provides support for light weight persistence for example: a. streamed object- objects are turned into streams of bytes b. persistent objects – objects are on disk, hold their state even when the program is terminted. 6. for primitve types, an automatic variable is created that is not reference. The variable itself holds the value and is placed on stack (not on Heap) a. objects are created on Heap while these primitve varaibles are created on Stack. So they are fast. 7. Size of primitve type is fixed. Doesn’t change from one machine to another like other languages. a. All Numeric types are signed (no unsigned data types) b. For boolean no size is defined but it is generally 1 bit. Type Size boolean 1 bit char 16 bit byte 8 bit short 16 bit int 32 bit long 64 bit float 32 bit double 64 bit Void ???? c. Use wrapper classes to create objects on Heap d. BigDecimal (arbitrary precision fixed-point numbers) and BigInteger (arbitrary precision integers) are hig-precision arithematic 8. Arrays – a. java arrays can’t be accessed outside range – this safety at cost of small memory overhead. b. These arrays are actually array of references (of objects from Heap) 9. Scoping is determining visibility and life time of an object. This done by {} braces. 10. in java, you cannot redefine same varaible in inner scope (variable hiding). (this can occur in c/C++ ). Following is invalid in java but valid in c/C++ { int x=12; { int x=13; } }
11. In java, garbage collector looks at the references of all objects that are created with new. if the reference is not used, it releases the memory. This also prevent the c++ problem of memory-leak, (problem where memory is not released from variable under use) 12. Class is keyword for defining objects of new type. It has two members: a. Fields or data members : object of any type, communicated via reference - use contructor to instantiate / initialize. - if primitive, initialized at the point of definition. - Primitive will be definitely initialized with default values. Type Default Boolean False Char ‘\u0000’ Byte 0 Short 0 Int 0 Long 0L Float 0.0f Double 0.0d ** primitive Variables in methods ( local variables ) will not be initialized to these values. This is only for class definition - Local varaibles if not initialized will throw an Error in java. b. Methods or Member functions. - determines the message the object can handle - name + arguments + return type + body - to call a method, use objectName.methodName(arglist). This is “sending messages to Object” 13. Name Clashing in java is avoided by using package names. This means that all files automatically live in their own namespaces, and each within a file must have a unique identifier. In c++, namespace is introduced to avoid that. 14. java also eliminates Forward Referencing, you can simply use the class even if the class doesn’t get defined until later in the file. 15. a package is library of classes. To use component from anyother class, import that class or package. 16. static keyword is used when : a. only one storage is required for N number of objects [N>=0] b. method needs to be called without any particular object of class. i. static means data or method is not tied to any particular instance of that class. Static methods don’t need objects to be created. ii. Since non-static members and methods are tied to a particular objects, they can’t be directly accessed via Static methods iii. A static method can create or use named objects of its type. Like main creating an object of its class type.
17. java.lang class library is default imported in all programs. It has the System class, which contains several useful class fields and methods. It cannot be instantiated. System class has the err and out static PrintStream Objects and InputStream object in. Since these are Static, you don’t create them. 18. Comments – Two types a. Mutli Line /* */ b. Single line // C++ type 19. Javadoc is utility to extract the comments. It extracts the information marked by tags , class name and method name. Output of javadoc is HTML - All javadoc comments must be in /** */ format - Comments can be for class, method or variable - Comments can be embedded HTML like /** *<pre> *Some method description */ - Comments can be using “doc tags” like @version – version Information @author – Author information, @since – version of code for particular feature, @param – parameter name and description, @return – return type of method, @throws – Exceptions thrown if method fails, @deprecated – features superseded by an imporved feature. Chapter 2 1. Since java is inherited from c++, many of the statements and operators are similar to c++ 2. Operator takes one or more arguments (operands) and produce a new value. 3. side effect : is phenomenon where an operator changes value of operand. Means instead of using the value change it. Example : ++ and – operators. 4. With Primitive Type : All Operator works 5. Object Type : =,==,!= 6. String Type : =,==, !=,+,+= 7. paraenthesis can be used to change the precedence of operators. 8. “=” is used for assignement. take value of rvalue and assign it to lvalue. a. rvalue – any constant, variable or expression that can produce a value. b. lvalue – should be a distinct named variable. c. when primitives are assigned, the values are copied. d. When objects are assigned, the references are copied. Both references will point to same object. e. If an object is passed to method and its field are manipulated within the method, the object will refer to new values even after it returns back from the method. This aliasing in methods.
9. Mathematical operators are +,-,/,* and % (modulus). They generate arithmetic results. 10. Integer division truncates the result. 11. To Generate Random Numbers, create a Random object and call different methods : nextInt(), nextLong(), nextFloat() or nextDouble() on it. 12. % (Modulus) with Random limits the result to upper bound of operator -1 13. Unary minus produces the negative of the value. 14. – (decrement) and ++ (increment) operators change value by one unit. They can be pre or post. 15. So Side effect is shown by ++, -- and assignement operators. 16. Relational Operators are <, >, <=, >=, ==, and !=. They generates boolean results. 17. <, >, <= and >= don’t work with boolean data types. (only == and != works) 18. suppose Integer a = new Integer(10); Integer b= a; If (b==a) // will always return false as the references are different. To compare the contents, use equals() method. If (b.equals(a)) will return false. • the default beahviour of equals() is comparing references. So if you writing your class which use this equals, override this method Most java libraries implements equals() to compare content rather than references. 19. Logical operators are &&, || or !. They generate boolean results. 20. Non-boolean can’t be used in logical expression. (in c/c++ they are allowed) 21. floating point comparison is very different. Even smalled difference in fraction makes the number different from other. Any number slightest above zero is Nonzero. 22. Short-Circuiting means evaluating expression till the truth or falsehood of entire expression is determined. Advantage – performance increases potentially. a. The expression evaluation stops for && once a false is intercepted 23. Bitwaise Operator are &, |, ^(XOR), ~(NOT), &=, |=, ^= allows to manipulate individual bits in primitive data types. Only ~ is unary, rest all are binary. 24. For boolean (1-bit data type), ~ (Bitwise NOT) is not possible but logical NOT is ok. 25. Shift Operator - only with primitive integeral data type (not for boolean). - Char, byte and short are promoted to int before shifiting. results are int. (only lower 5-bits are used) - long results in long but lower 6-bits are used. - << left shift, insert zero in lower order bits, equal to multiply by 2 - >> right shift (with sign), inserts zero for positive and 1’s for negative at higher order bits. Equals to divide by 2.
-
>>> right shift (without sign), inserts zero. Shift with = (like >>=, <<= etc) will give -1 (new version 0) for byte and short. Reason : since these are promoted to int , shifted, and converted back to byte or short, results are not proper. 26. The binary representation of the numbers is signed two’s complement. 27. Ternary Operator : Expression ? True Value: False Value. [used to produce unreadable code] 28. Comma Operator : Sequencing the Arguments in method calls and expression evaluation. Used in for loops. 29. String concatenation operator + : if any object is concatenated to any string, it is first converted to string and then added. 30. Pitfalls prevented by java compiler: a. Will not allow statements like while (a=b) {}. b. Will not allow & and | to be used instead of && or || 31. Casting : generally done by java compiler itself. But can be done explicitly. a. boolean doesn’t allow casting. b. Narrowing conversion gives warning while compiling for loss of precision. Casting from float or double to int always truncates. c. Widening conversion – no problems. d. Class types do not allow casting unless explicit methods are there to do so. But classes can be casted in a family (inherited classes). 32. literals – compiler use its defaults. But adding few things change the type of literals for compiler. Common literals are prefixed [Hexadecimal integers (0x, 0X), Octal (0)] or postfixed [L for long, F for float, D for double] 33. by default, Compiler takes exponential numbers as double. So float f4 = 1e-47; will give error. Taking it as double. Put f after the number Float f4 = 1e-47f; is proper. 34. To perform any mathematical or bitwise operation, the data types are promoted and results are always in the new type*. Explicitly cast the result to get back to get the required data type. 35. why no sizeof() operator in java? Because all data types are of same size on all machines. 36. Excution control include – a. if(expression) {statement} [else {statement}] : expr must give boolean result. The statements can be simple or compund. b. while(expression) {statement} : expr must give boolean result. The statements can be simple or compund. This is entry controlled loop. While(true) is infinite loop. c. do{statement}while(expression) : expr must give boolean result. The statements can be simple or compund. This is entry controlled loop. This is executed atleast once. d. for(initialization;expression;stepping) {statement} : perfom initialization, then interation and then stepping. Any of these can be empty
statement. Excute till expression is evaluated to false. Comma operator is used in initialization and stepping but must be of same type**. For(;;) is infinite loop. e. Switch (integer expression) or selection statement : Multi way selection Switch (integer expression) { Case value1 : {statement } break; Case value1 : {statement } break; .. .. default : {statement} } expression must return integer value(or be promotable to int). This value is compared and suitable case is selected and executed. Default executed if no match occurs. Break is optional but execution occur till break is encountered. For non-integral, use ifs in the cases. f. goto – it is low-level / source code level jump. Java has no goto. 37. return : is used to return value from a method and to control flow of execution. If method has no return type (void) , it simply has return followed by semi-colon. 38. break : is used to quit the loop without executing rest of the statements. 39. continue : quits current iteration and begins the next iteration from start of loop. Break and continue can use labels to jump to different loops (other than intended ones). Chapter 3 1. c++ introduces constructors which are automatically called to create objects. Java adopts that. Initialization is guaranteed. Contructor returns the object itself. 2. Java has garbage collector which release memory when no reference is there for object. 3. name of contructor is same as class because a. this prevent name clashes with any member method. b. Compiler can easily pick the constructor from class name. 4. Contructor with arguments are overloaded methods : provides parameter for the initialization of the object. 5. Contructor has no return value 6. Constructors are not inherited. 7. Overloading constructors help creating objects in more than one way. They take one or more arguments, a unique list of arguments. If there is difference in order of arguments, the calls are different (overloading). Overloading is also done by changing the return type (but can’t overload constructors that way as they don’t have return types). 8. Default constructors takes no arguments “no-arg constructors”. If not provided, compiler automatically create a default one. But if constructors are
overloaded, default constructors should be explicitly defined. The compiler will NOT create it. 9. A primitive argument is promoted from smaller type to a larger one. So a data type that is smaller than the argument in the method, the data type is promoted to make the call. 10. If the data type is wider, casting needs to be done. (narrowing conversion) 11. this – used only inside methods, produces the reference to the current object the method has been called for. It is often used with return to return the reference to the current object via this keyword. x.doSmth().doSmth().doSmth(); doSmth() should return the reference of x as this so that multiple operations can be performed on the same. 12. A constructor can call other constructors with less or equal number of arguments. this – in constructor, makes an explicit call to the constructor that matches the argument list. But look at the limitation in example below Flower(int petals) { petalCount = petals; System.out.println("Constructor with int arg only " + petalCount); } Flower(String ss) { s = ss; System.out.println("Constructor with String arg only " + ss); } Flower(String ss, int petals) { this(petals); // You can’t call this(ss) after this(petal) as this() would have already returned the current reference. So use this.s to set the member for current object. this.s = ss; System.out.println("Constructor with String and int args "); } 13. static and this – if a method is static, there is no “this” instance. Static methods are called for class itself, without any object. But this deals with objects. 14. You cannot call non-static methods from inside static method. But reverse is possible. To call non-static method from static method - pass a reference of object into static method, and now call non-static methods and access the nonstatic fields. 15. Garbage collection is not destruction of objects. Java has no destructors. But garbage collection knows only about releasing memory for allocations using new. 16. finalize() –method called to release the specially allocated memory (not using new). if defined for any object, the garbage collector calls finalize(), and one
cycle (of garbage collection) later tries to reclaim the memory. So finalize() gives ability to perform some important cleanup at the time of garbage collection. 17. finalize() is method only for memory related activities (allocation and deallocation). It is generally used to free memory from allocations by native metods (or objects formed from non-java code). for example, if the non-java code use malloc() to allocate storage, finalize() can be written with free() call to recover the memory. 18. System.gc() forces execution of garbage collection- finalization happens to all objects. It will finalize and destroy all the objects that are no longer in use upto that point of time. 19. System.runFinalization() causes programs to run all the finalizers as they exited or will cause any unfinalized objects to be finalized. 20. If JVM is not close to running out of memory, it will not waste time in recovering memory through garbage collection. 21. Death Condition and finalize() : Even if finalize() is not called in all conditions, it can be used to check whether the object is in state whereby memory can be safely released (verification of Death Condition). Ex: Checking closure of FileStreams etc before cleaning objects which created and using them. 22. Working of Garbage Collector: First Scheme – Reference Counting : Each object contains a reference counter which increases every time a reference is attached to object. Everytime a reference goes out of scope or set to null, the count is decreased. Advantage : Simple Disadvantage : Overheads in maintaining the reference list. Circular References : when object refer to each other , they can have nonzero ref counts but still they are garbage. Second Scheme – Adaptive Garbage Collection 23. If variables are not initialized in method (local variables), compile time error is thrown. 24. if primitive variable is class member [not local variable] and not initialized, the compiler initializes it with default value.[Automatic Initialization] 25. Order of initialization leads to Compile time error called- Forward referencing. class Cinit { int j = g(i); int i = f(); … } // this is a problamatic code. Compile time error. 26. Order of initialization : All the variables are initialized first before any method calls even the constructor. Class Tag { Tag(int marker) } class Card{
Tag T1 = new Tag(2); called first. New reference Card() { T3 = new Tag(33); called Third. Drops the previous objects reference i.e. of new Tag(33). The garabage collector will collect that. } Tag T3 = new Tag(3); Called second Since this is variable so this initialization will take before constructor’s T3 set to 33. .. } Here T3 reference gets initialized Twice. 27. static primitive variables – are always initialized to standard primitive values. 28. static object variables – references are always set to null unless a new object is created and reference is attached. 29. static initialization occurs only if its necessary. a. They are initialized only when first static access occurs. b. They are always initialized before the non-static members. c. Once initialized, no further initialization takes place. d. * Static blocks can be used to group static members together. static { … } 30. Initialization of references can be done at a. objects are defined in classes – hence always initialized even before constructors are called. b. In constructors c. Right before they are needed (lazy Intialization) – objects created on need basis. 31. Similar to static blocks, anonymous inner class can be used for grouping nonstatic initialization { // no static keyword before opening brace …// initialize non-static keyword for each object. } 32. Array initialization : In java, Arrays are objects. Square brackets [] is indexing operator. a. All arrays have intrinsc member called Length b. Largest accessible element is length-1 c. ArrayOutOfBoundException thrown if member outside the bounds is accessed. d. Assignment operator for two array objects actually copy the reference of right side array to left one. e. Once defined, the array length can be changed at runtime. int[] a; … …
a = new int[20]; Also the primitive types are automatically initialized to “default” values [zero for chars and ints and false for booleans] f. for non primitive arrays, always use new. because we actually create an array of references g. The final comma in the list of initializers is optional. No Error is thrown. Integer[] a = {new Integer(1), new Integer(2), new Integer(3), this comma is optional h. for creating heterogenous arrays, use Object[]. Later on use RTTI to find the type of object. Chapter 4 1. The agreement between the client (library user) and the server (library provider) should remain same. 2. Java provides access specifiers to allow the access check. public, private, protected are the access specifiers. 3. package is used to bundle the components together. Together with access specifiers it is used to check the accessability. 4. import is the key word usd to bring in the library or its component. * will bring in entire library. Specifying the name of specific component will bring only that component. In this case none of the other classes in package are available. Importing is actually done to manage namespaces to prevent clashes of same method names of different classes when imported at same place. 5. Compilation unit / Translation Unit : Source code file with extension .java. Should have only one public class. Other classes if present are support classes and are not exposed to outside world (not public). When compiled, a .class file for each of the class (public and support) is generated. These classes are compressed to Jar files. Java Interpreter is responsible for finding, loading and interpreting these files. * The public class in a .java file is optional. 6. A .java file produces many .class files. To group them together use package statement which should be first non comment in the file. Only one public class can be there in java file. So to use that public class, use import with package name (followed by * or fully qualified name). 7. To prevent the cluttering .class files, package the files into single sub directory. This actually does the following: a. Name clashes : since compiler forces the first name of package to be internet domain reversed. This prevents name clashes. b. Directory Structure : package names are resolved into a directory on machine., so when java programs runs it needs to load the .class file, it can loacate the directory easily. How interpreter works : suppose we import com.mypack.myclasses.*, in this case
i. The CLASSPATH variable is searched and loaded in memory. A CLASSPATH contains number of alternative search paths. A “.” (dot) in classpath means class search should include the current directory. If not present, the current directory is not searched. ii. The dots are replaced with slashes. So com.mypack.myclasses.* becomes com/mypack/myclasses/ iii. Starting with first entry in CLASSPATH, the string is concatenated and lookup for .class is made. 8. Collision : occurs when two classes of different package having same names are used in java file. For example, Import mypack.myclass.Vector; Import java.util.Vector; .. // Wrong Vector v = new Vector(); which vector. Compiler forces to fully qualify the name of class. //Correct java.util.Vector v = new java.util.Vector(); Qualifying fully solves the Collision problem. 9. No Conditional Compilation is allowed in Java : in C/C++ this feature is used to solve the cross platform issues i.e. different code portion compiled for different platform. Since java is automatically cross platform this feature is not required. 10. A field or a method can have access specifiers – public, private and protected. In c++, access specifiers control all the definition following it until another specifier is encountered. In java each access specifier controls the access for only that particulr definition. 11. “Friend” ** if no access specifier is mentioned, it means all the other classes in the current packeage have access to the friendly member but to all classes outside of this package the member appears to be private. i.e. PACKAGE ACCESS ONLY. – friends have mutual access in package. 12. Access Control is implementation hiding 13. Access specifiers: a. public - everybody can access it and anywhere b. no specifier – “Friend”, other classes of same package can access it. c. protected –classes inheriting can access these. “private for users but available to inheritor or anyone in same package”. d. Private – hide from the out side world. Nobody from outside can access. Any private method in class are implicitly final hence inline 14. If a java file is in [sub]directory and has no package statement, it is accessible to all the files of same level (Default package). But if package is specified and the file is imported in some other package, then its members without any specifiers “friendly” are not available to outside world.
Java treats files without package statement as implicitly part of the “default package” for that directory, hence friendly to all other files in that directory. A friendly member is inaccessible to users of the package. Also the members won’t be available to inherited classes. 15. private means no one can access except that particular class and inside method of that class. Not even other classes of same package. a. Making default constructor private controls the creation of object. Instead other constructors with arguments or methods (calling this private constructor) can be defined to create objects. b. Make all fields private and expose getters and setters. 16. protected keyword is used with inhertience. Specifying a member with protected makes it available for derived class only. 17. Encapsulation is wrapping data and methods in class along with Access specifiers (defines the behaviour i.e. client will get to see what all methods. Also interfaces can be seprated from implementation) 18. Separating interfaces (exposed to world) from implementation is advantageous as the agreement (interface) is not changed but the implementation that’s hidden from world can be changed just by changing the support classes. 19. Access specifier and class access: The class accessiblity can be modified by placing public or nothing(“friendly” – that class can be used only within that package). They can’t be private (accessible to themselve) or protected. To make a class inaccessible to all, make all constrctors private. Also calling these private constructors in some public static method allows only you to create objects. 20. Singleton class : allows only a single object to ever be created. Chapter 5 – Reusing classes 1. Two ways of Reusing an exisiting class : a. Composition (has-a relationship): the new class is composed of existing classes generally by creating objects of existing class inside the new class. It reuses the functionality of code not the form It is used when : features of a class are required inside derived class and not in interface. Done by embeding private objects of the class. But if at times there is need for class users to access the members, make them public (The members are public but they will hide their implementations). b. Inheritance (is-a relationship): creating a new class of type of an existing class. Take form of existing class, optionally add more to it without modifying the existing class. It is used when: A genenral purpose class (say shape) is used for specific purposes (say triangle, circle etc), then the general class can be extended with specialization implementation. “both Composition and inheritance can be used together”
2. Composition of classes : Generally done in class definition by simply putting object references inside new classes. class abc { String FirstName = new String(); composition; references are kept in class; if not initialized will be set to null; int i ; primitive data type; need not be initialized. 3. Lazy Initialization : is creating objects right before they are actually needed. Helpful in reducing overheads in situations where the objects doesn’t need to be created everytime. 4. Object is the root of all classes. So all classes in java are derived classes except the Object class. Hence inheritence is obvious. 5. All the classes (support and public) in a compilation unit (.java file) can have public static void main method. This method can be called directly from command prompt to Unit Test the class (java ). 6. General rule : make all fields private and all methods public. Make members protected if inheritence is planned. 7. Inheritance actually is reusing the interface and optionally adding more functionality. 8. If derived class is instantiated : it contains a sub-object of base class wrapped with in the derived class object. Java automatically inserts calls to base-class constructor in derived-class constructor (if there are not overloaded constructors). The initialization is always base “outwards” i.e. starting from base class. 9. super keyword is used a. when a derived class also implements the same method inherited from base class and to invoke the base class method super is used followed by method name. Simply specifying method name calls the methods of derived class. b. If there are overloaded constructor (constructor with arguments) of base class, then super(with arguments) should be the first line in derived class constructor. Else compiler will throw an error. 10. Name Hiding : in java, if a method is overloaded in base class and derived class is implementing it again, all versions of the method will be available. So overriding a base class method name in a dervied class does not hide the base class versions. 11. Derived class is superset of base class as it can contain more methods than base class but must contain atleast the methods in base class. 12. Upcasting : casting of derived objects to base class. It moves up on the inheritance diagram. It is loss of methods actually as we go from derived class with more methods to base class with less methods. Class Instrument { public void play() static void tune(Instrument i) {.. }
} // end of class Instrument class Wind extends Instrument { public static void main(String args[]) Wind Flute = new Wind(); Instrument.tune (Flute); // Upcasting } Upcasting is always safe (the methods are always available so call will never fail). Reverse is downcasting (problamatic, new methods are added in dervied classes so calling methods on base class object might throw no such method exception.) 13. Upcasting can be used to choose between Composition and inheritance. If upcast is required, choose inheritance. If not, check if composition is problem solver? 14. Final actually means “cannot be changed”. In java, the keyword is used to : a. Compile time constants : to eliminate run time overheads, i. A primitive field that is static final has only one storage that cannot be changed. These are initialized once upon loading and not each time a new object is created. Non-static final have different storages. A value must be given at the time of definition. With primitve, final makes the value a constant. ii. non primitive final : with object references, final makes the reference a constant. Means reference cannot point to another object once initialized to an object. But the value of the object can be modified. iii. At Run time – it can be a value at run time that shouldn’t be changed. b. Blank finals : fields declared as final but with no value i.e. not initialized. If a blank final is used without initialization, the compiler throws an error. So its guranteed that final field will always be instantiated before use. c. Final Arguments : arguments can be declared final in method definitions. Hence inside the method, the argument reference or value can’t be changed d. Final methods : methods are made final to: i. Lock them – inheriting classes shouldn’t change them or to retain the behaviour ii. Compiler makes all calls to such final methods inline. If methods are big, inlining will bloat so its better if we write or break methods into short for performance purpose. Important things to remember: “Any private method in class are implicitly final hence inline” “if a private method is overridden, the compiler will not throw an exception because actually we are writing a new method” “a final private method is as good as private method.”
“overriding can be done for exposed function in interfaces. If methods are not exposed i.e. private, then they will not throw errors if implemented in derived class” “making a method final removes the late binding” e. final classes: making classes final means “No change to class”. Declare a class final when no Subclassing (inheritance) is required or when no need to change the form is required. “declaring class as final means all methods are final as there is no way of inheriting or overriding them” 15. The static initialization takes place in textual order and is done only once. 16. In java, class code is loaded at the first point of use. Even if you call main (which is static) of any class, the class loader searches the compiled code. it checks if there is any base class and loads that next. Once all the base classes are loaded, the object is created. The primitives in this object are set to default values and object references to null. Then base constructor is called [which may be explicitly done by using super()]. Once all the constructors are called, the instance variables are initialized in textual order. And only then rest of the body of constructor is executed. Chapter 6 – polymorphism 1. Encapsulation - creates new data types by combining characterstics and behaviours. Implementation Hiding – seperates the interface from implementation by hiding (privatizing) the details. Inheritance – allows the objects to be of its own type or its base type. 2. Polymorphism – decoupling of types. i.e. of many forms. Also called dynamic binding or late binding or run time binding 3. Binding – Connecting a method call to a method body. When binding is performed before the program is run (while compiling and linking) it is early binding. 4. All method binding in java used late binding (unless method is declared final since inheritance is not possible and hence there is no need to check object before binding method calls). 5. Late binding – means binding occurs at run time based on the type of object. Suppose there is class shape with draw() and erase() methods. Circle, Square and Triangle extends that. Now Shape s = new Circle(); reference of circle assigned to shape is valid as circle is a shape s.draw(); will call the draw method of circle and not shape because of late binding.
6. Upcasting – Taking an object reference and treating it as a reference to its base type. (the inheritance trees always have base class at top). This is also called “narrowing” of the interface. 7. Overloading – when a method signature changes while deriving and implementation may or may not be changed Overriding – when method is overriden with same signature in same or derived class with new or changed implementation. Late binding is applicable in this case. 8. Abtract classes : These are classes meant to express interfaces. Objects of these have no meaning hence object creation is not allowed. abstract keyword is used. A class containing all abstract methods or qualified with abstract keyword is called an abstract class. The compiler won’t allow object creation of such classes. 9. Abstract methods : are incomplete methods having declaration and no implementation. Deriving classes should provide the implementation 10. if inheritance of abstract class happens, then method definitions must be provided for all abstract methods in the base class. If not then derived class is also abstract and compiler will force to qualify derived class with abstract keyword 11. An abstract class with non abstract method is declared when we want to prevent creation of any instance of the class. 12. Sequence of Constructor call for complex class i. The storage is allocated for object and is initialized to binary zero. ii. The deepest base class constructor is called iii. Unfurls the base classes by Calling the next derived class constructor until the most derived class is reached. iv. Members are then initialized in the order of declaration. v. The body of derived class constructor is called 13. Inheritance and Garbage collection : when finalize()method is overriden in the derived class, it must call the base class version of finalize() [super.finalize()], otherwise the base class finalization will not happen. Each overriden finalize() must have access to atleast protected members since the finalize() method in class Object is protected and the compiler will not allow to reduce the access during inheritance. 14. Derived class finalization should occur before base class as some methods calls in base class require that the base class component are still alive. So they shouldn’t be destroyed prematurely. 15. what happens if a dynamically bound method is called inside a constructor – The constructors job is to bring the object into exisitence. But this call may occur when the object is partially complete as we don’t know which classes are inherited from this. A dynamic call reaches outward and call a method that might manipulate members that haven’t been initialized yet. for example abstract class Glyph { abstract void draw();
Glyph() { draw(); problamatic as which draw to call if Glyph is inherited } class RoundGlyph extends Glyph { … void draw(); inherited and overridden } 16. Design issues: i. Using Composition : Composition is flexible since its dynamically possible to choose a type. ii. Inheritance : need the exact type to be known at the compile time. You can’t inherit differently at run-time. Use inheritance to express differences in behaviour. iii. Pure inheritance – when methods established in base class are overriden in derived class. Generally inheritance guarantees that any derived class will have the interface of base class and nothing less. But in pure inheritance, derived class has no more than the base class interface. Other words both base and derived class have same methods. The base class and derived class can receive same set of messages. Upcasting can divert the same message to base class. Chapter – 7 – Interfaces and Inner classes 1. interface – keyword used to provide pure abstract classes, one that provide no implementation at all. It allows the creators to establish the form for a class : method names, argument list and return types. a. An interface can have fields. All of them would be implicitly static and final. b. An interface provides only a form but no implementation c. Interface actually is an agreement of services provided by implementing class and service user. d. To make a class conforms to a particular interface use implements keyword. e. Use public keyword before interface if that interface is defined in a file of same name. f. Even if methods are not declared public in interface, they are implicitly public. So when interfaces are implemented, the methods from interface must be declared public in implementation class. Else they would at least have friendly access (if not done, the inheritance will have reduced accessibility . g. Interfaces helps in multiple inheritance We can combine multiple interfaces as there is not implementation or storage class. h. Base class +interface 1 + interface 2 … = Derived class method set or its interface. 2. To inherit multiple interfaces, separate them with commas. The concrete class i.e. class with no abstract methods should come first followed by interfaces.
3. If smth is going to be base class, then make it as interface. Only if it need some implementation choose abstract class or concrete class. 4. Name Collision while combining interfaces can occur. This will lead to compile time error. Avoid such instances. 5. Extending an interface with interface use extends keyword. Imp: extends can be followed by comma seperated multiple interface names (which is different from single class inheritance). 6. Any field in interface is by default static public and final. (c++ has enum but this is improvement over hardcoding numbers into the programs). Moreover the fields cannot be “blank finals” 7. fields in interfaces can be initialized when class is first loaded. They are not part of interface but stored in static storage area for that interface. 8. Nesting interfaces: can be done within the class or within other interfaces. The nested interfaces can be public or “friendly” and these interfaces can be implemented as public, “friendly” or private nested classes. 9. A nested private interface can be implemented as public class. **They cannot be implemented outside of their defining classes. You can write public methods returning references to private interfaces. But the parent interface only has right to manipulate.
Inner classes 10. Inner classes: When a class definition is placed inside another class definition. It also allows us to group classes that logically belong together and to control the visibility of one within the other. *inner classes are different from composition. Also inner classes can be made within methods or arbitrary scope to actually prevent such piece of code from being publically available. 11. To make an object of inner classes (except from a non-static method of outer class) use OuterClassName.InnerClassName 12. Generating an interface reference from an object that implements it is same as upcasting to a base class – as the implementation of interface or inner class is hidden from all. So we get only reference to base class or interface. 13. private inner classes cannot be downcasted at all. Protected inner class can be downcasted if inherited. 14. private inner classes are accessible to its base outer class. 15. protected inner classes like other variables have package “friendly” access and inheritor access. 16. non-inner classes cannot be made private or protected – they can be only public or “friendly”. 17. An inner class defined inside a method cannot be accessed outside it. Better way is to define a public interface, implement it in inner class inside a method. Use another method to return reference to interface and use the reference. This way we can hide the implementation. 18. An inner class can also be defined inside arbitrary scope like ifs{} and for(). They are compiled along with the main class and not conditionally created. But they are not available outside the scope, else they behave like ordinary classes. 19. Anonymous classes are definitions without names. Generally, they are used inside the methods etc.
… public Contents cont() { return new Contents() { // Method returns anonymous inner class. The Class returns reference to Content Interface private int i = 11; public int Value() {return i;} }; Semi Colon is must as this is expression not a usual class definition. …. Here the Contents is created using default Constructor. But if initialization is needed for an object of an anonymous inner class , perform it at the point of definition. If the object used in anonymous inner class is defined out side the class, the compiler requires the object to be final. 20. Instance initializers are methods with anonymous inner classes. They have arguments that are passed to create an object with initialized variables in anonymous inner class. For example, .. dest (final String dest, final float price) { This method is instance initializer or a sort of constructor for anonymous inner class return new Destination () { private int cost ; // instance varaible … cost = Math.round(price); // value passed to dest() is used to initialize instance variables if (price > 100) … ..} *** These can’t be overloaded so that only one i.e. default constructor is there. 21. Inner classes have access rights to all the elements of the enclosing classes. They can access the methods and fields from the enclosing class as if they owned them or have automatic access. Hence inner class must keep a reference to the particular object that was responsible for creating it. Construction of the inner class objects requires the reference to the object of the enclosing class, and the compiler will complain if it cannot access that reference. Hence a connection is there between the inner class and enclosing class objects. 22. The link to outer class is achieved through “this”reference. If it is required to produce a reference to the outer class object inside inner class use outerclassname.this. 23. making inner classes static removes the connection between the inner and enclosing classes. A static inner class means we don’t need an outer class object
in order to create an object of inner class and also we can’t access an outer class object from an object of a static inner class. 24. A non-static inner classes cannot have static data, static fields or static inner class as they can only be at the outer level of the class. But a static inner class can have all. 25. A static inner class does not have special reference this. 26. **Interfaces have definitions only. But to put some code in these we can use static inner class as the class is in namespace of interface 27. To create an object of inner class in some other object, use a reference to the outer class in new expression public class Parcel1 { class Contents { // inner class .. } } public static void main(String args[]) { Parcel1 p = new Parcel1(); // create an object of outer class which will later be used to create objects of inner class … Parcel1.Contents c = p.new Contents(); // use p to create instance of inner class ** the “.new” syntax produce correct scope so no need to qualify the class name in constructor call. 28. if it is mutliply nested classes, to reach outward use the dotted notation like outerclass.nextinnerclass.nextinnerclass = new … 29. Nested classes can access all members of all levels of the classes they are nested within. 30. To inherit inner classes, we should initialize the object of enclosing class(es). As the inner class constructor is attached to reference of the enclosing class objects For example, class WithInner { class Inner {} } public class InheritInner extends WithInner.Inner { InheritInner() {} // this won’t Compile as it need outer class object InheritInner(WithInner wi) { // this is okay as it creats a Wi.super(); // this is must for compilation } 31. Overriding inner classes. The inner classes can be overriden but since they are in their own namespaces, so it depends which one you are calling For example, Class A { Class B {.. inner class } private B b;
public A() { .. b= new B(); } } public class C extends A { public class B { // class over ridden in extended class. But its in different name space so won’t be called … } psvm(String args[]) { new C(); // this will call default constructors of A and B (inner to A) since C extends A. This won’t call B inner to C. } But if the inheritance is like (refer example file BigEgg2.java) public class C extends A { public class B extends A.B{ // class over ridden in extended class. Since it extends and overrides the class now in its space,this class will be invoked now. … } 32. The inner class on compilation produces class files with “name of enclosing class, followed by $ sign, followed by the name of the inner class”. For example, the class InheritInner on last page produce following classes: InheritInner.class WithInner$Inner.class WithInner.class If inner classes are anonymous, the compiler simply starts generating number as inner class identifiers. If inner class are nested, their names are simply appended after a “$” and out class identifier 33. inner class is not limited by whether the outer class is already inheriting from an implementation. Inner classes allows us to inherit from more than one noninterface. Hence help in multiple inheritance of abstract classes***. For example, class C {} abstract class D {} class Z extends C {} // Z class extends C and makes an objects of D D makeD() { return new D() {};} } public class MultiImplementation { static void takesC (C c) {} static void takesD(D d) {}
psvm(String args[]) { Z z = new Z(); takesC(z); takesD(z.makeD()); } } 34. Closure is a callable object that retains information from the scope in which it was created. Inner classes are not closures are they don’t contain but have reference back to whole outer class object even the private members. For details look example Callbacks.java. Chapter 8 – Java Containers 1. Containers are objects holding other objects or may be their references Arrays 2. Array is the most efficient way to store and randomly access a sequence of objects (or their references). But Arrays have fixed size and cannot be changed during the life time. Hence if more spaces are requried, we have to create new Array. 3. Array Identifier is a reference to a true object created on Heap regardless of type of array. This is the reference that holds the reference to other objects and it can be created implicitly as part of array initialization syntax or explicitly with a new expression. The only other member exposed is length that tells the count of elements in array and [] to get indexed elements. 4. Arrays of objects hold references while array of primitive holds the primitive values directly. Also primitives are initialized to default values. 5. simply declaring array variable creates an Array reference pointing to NULL on Heap like Integer[] a; // this creates a NULL reference on Heap 6. Declaring array variable with size creates array with NULL references. Though the array object has its own reference on Heap. Integer[] a = new Integer[5]; //creates 5 NULL references again Heap Now “a” will have reference and length of 5 which tells how many objects can be placed in array (but not how many are already their). 7. Aggregate Initialization : causes array object to be created in one statement Integer a[] = {new Integer(1), new Integer(2), new Integer(3)}; 8. If one array object is assigned to second, it means the array reference is copied to the second. Hence both array point to same array object on Heap. 9. Its better to use wrappers for primitives inside a container, but wrappers are difficult and complex to handle than the primitives themselves. 10. In Java, methods can return a reference to an array and it will be garbage collectors responsibility to cleanup the memory. The array will persist till it is or its reference is needed. Actually speaking returning an array is as good as returning any other objects- here a reference. 11. java.util has Arrays class which has all methods static– equals() to compare two arrays for equality, fill() to fill an array with a value, sort() to sort array and binarySearch() to find an element in a sorted array.
12. fill() method only duplicates a single value into each location or in the case of objects copies the same reference into each location. Also there are overloaded methods to fill a specified range of From Elements to To Elements 13. System.arrayCopy() , can make much faster copies of an array. Its overloaded to handle all types. The syntax is System.arrayCopy(Source Array, offset of Src Array, Dest Array, offset of Dest Array, number of elements to copy) 14. equals() compares entire array object for equality. Its an overloaded method. To be equal, the arrays must have: a. same number of elements b. each element must be equiv to corresponding element in other array. 15. ** Array equality is based on Contents. String s1 = new String[5]; Arrays.fill(s1,”Hi”); // all five elements points to same object. Only references are copied String[] s2 = {“Hi”, “Hi”, “Hi”, “Hi”, “Hi” }; Five new objects five new references. Arrays.equals(s1, s2); // this will always return true as the contents pointed is same. 16. To Compare, there are two ways a. By implementing java.lang.Comparable interface. This interface has only one method compareTo() which takes another object as argument and produces i. result < 0 if argument is less than current object ii. result=0 if argument is equal to current object iii. result>0 if argument is greater than current object Since we are supposed to implement Comparable, its our responsibility to decide the outcome also. b. By implementing an interface Comparator which has two methods compare() and equals(). equals() is not implemented as it can be directly inherited from Object. So the implementation of equals() can include call to Object.equals(). The compare() method takes two arguments and compares them. It produces i. result < 0 if first argument is less than Second argument ii. result=0 if first argument is equal to second argument iii. result>0 if first argument is greater than second argument 17. Arrays has got method equals() overloaded for all types. it is generally used as default when no other implementation is required. 18. Sorting is performed using the sort() method. sort() is a static method with two different index for all types. sort(array of any type) for sorting whole of array while sort(array of any type, starting index, end index) for sorting a portion of the array. ** Primitives don’t allow the use of comparators in sorting 19. Sorted arrays can be searched using binarySearch() of Arrays. ** Don’t try to use binarySearch() with UNSORTED arrays. Arrays.binarySearch() returns value greater than or equal to zero if search item is found. Else it produces negative
results (-insertion point -1) representing the place that element should be inserted if we want to maintain the sorted array. The insertion point is the index of first element greater than the key [or a.size(), if all elements in array are less than specified key]. ** The binarySearch won’t give proper results in case of Duplicates in array. Use TreeSet to create sorted list of non-duplicates. **if sorting is done using any Comparator implemented by us, include the same when performing binarySearch().
Containers – heterogenous storage 20. Java provides a library of container classes – List, Set (holds only object of each value), Map(an associated array). All these container classes resize themselves. 21. Java 2 container library divides the issue of holding objects into two concepts: a. Collection (java.util.Collections): which is group of individual elements. A list (eg ArrayList) must holds elements in sequence and storage is exactly as entered w/o ordering , a set (eg HashSet) cannot have duplicates and use its internal ordering. To add element there is add() method in collections. When printed using sop, out put is like “[element1, element2, element3 ..]” b. Map or associative arrays: a group of key-value object pairs. A map can return a collection (list or set) to represent that portion. A map (eg HashMap) can return a set of its keys, a collection of its values, or a set of its pairs. A map can have values as maps. Maps only accepts one of each type no duplicates, based on key and use its own internal ordering. To add elements there is put() method in Maps. When printed using sop, output is like “{key1=value1, key2=value2,..}” 22. Disadvantage of containers: loss of type information. Actually Objects references are put into container. Since the type info is thrown away when putting object reference into a container, there is no restriction on the type of Object that can be put into container . Explicit casting is required before using object references ** if casted to a different type, runtime exception is thrown. 23. Lists have all Non-Static methods - add(), get(), size() 24. An Iterator is an object whose job is to move through a sequence of objects and select each objects in that sequence without programmers efforts. Since Iterators are light weight objects, they have certain limitation, like forward only iterations etc. Java uses iterator() method to return iterator to an container which will be ready to return the first element in the sequence on first call of next() method. Use next() method to get next object. Use hasNext() to check if there exist any next element, use remove() to remove the last element returned by iterator. For example, ArrayList myList = new ArrayList(); For (…..) myList.add(new Integer(5)) // add objects to arrayList … Iterator e = myList.iterator(); // get the iterator while(e.hasNext()) // check if objects exist in List System.out.println(e.next()); // uses Object.toString() to print
the object returned by next();
25. Containers Taxonomy iterator
Collection
ListIterator AbstractCollection AbstractList
List
Map
Set AbstractMap
SortedSet AbstractSet HashSet
TreeSet
HashMap
TreeMap
WeakHashMap
Vector (Legacy)
SortedMap
ArrayList
Hashtable
AbstractSequentialList
Stack (Legacy) LinkedList 26. In the diagram above, dotted yellow boxes are interfaces, dashed orange boxes are abstract class while solid white boxes are regular class. Dotted line arrow indicate a particular class is implementing an interface. Solid arrows indicate a class can produce objects of the class 27. The interfaces that can hold the objects are Collection, List, Set and Map. 28. Abstract classes partially implement these interfaces. So its better to use abstract classes rather than implementing whole of interface once again. But Container library has enough functionality. 29. Generally we make the object of implementing classes, upcast them to interfaces, then use the interface. we can equally ignore the legacy elements. Map iterator Collection
ListIterator
List
ArrayList
LinkedList
HashMap
Set HashSet
TreeSet
WeakHash Map
30. All collections can produce an Iterator via their iterator() method.
SortedMap TreeMap
31. All classes with “Tree” are sorted collections.
32. Following table shows the functionality of Collection i.e. Set and List (excluding the methods of Object) which are inherited from Collections. Maps are not inherited from Collections. Method Description boolean add (object) Ensures that the container holds the argument. Return false if it doesn’t add the argument boolean addAll(Collection) Adds all the elements in the argument. Return true if any elements were added void clear() Removes all the elements in the container boolean contains(object) True if the container holds the argument boolean containsAll(Collection) True if the container holds all the elements in the argument. boolean isEmpty() True if the container has no elements Iterator iterator() Returns an iterator that you can use to move through the element in the element in the container boolean remove(Object) If the argument is in the container, one instance if that element is removed. Returns true if a removeal occurred. boolean removeAll(Collection) Removes all the elements that are contained in the argument. Returns true of any removals occurred. boolean retainAll(Collection) Retains only elements that are contained in the argument. Returns true if any changes occurred. int size() Returns the number of elements in the container Object[] toArray() Returns an array containing all the elements in the container Object[] toArray(Object[] a) Returns an array containing all the elements in the container, whose type is that of the array a rather than plain Object. 33. ** No get() method in table above as collections include Sets which maintain there own ordering.
Lists 34. The following table shows the interface and concrete classes of List family – ArrayList – which excels at randomly accessing elements and LinkedList – for optimal sequential Access. add(), get() and iterator() are commonly used methods. List (interface) Maintains elements in particular sequence.
Returns ListIterator which can be used to traverse List in both direction and to Add and remove elements. ArrayList It’s a List implement with an Array. Allows random access. Slow when middle elements are manipulated. ListIterator should be used only for travesing not for insert/delete as its expensive. LinkedList Optimal Sequential Access with inexpensive inserts and deletes. Slow for random access. **has addFirst(), addLast(), getFirst(), getLast(), removeFirst() and removeLast() which allow it to be used as stack, queue and deque. 35. LinkedLists can be used to implement Stack – a LIFO container which has push() [implemented using addFirst()] and pop() [implemented using removeFirst()] 36. LinkedLists can also be used to implement Queue – a FIFO container which has put() [implemented using addFirst()] and get()[implemented using removeLast()] 37. LinkedLists can also be used to implement Deque – double ended container which has put() [implemented using addFirst() and addLast()] and get()[implemented using removeLast() and removeFirst()]
Sets 38. A set cannot hold duplicates. 39. It has same set of methods as its interface Collection. While Lists has LinkedList which has some additional functionality Set (interface) Holds unique elements [Objects added should have equals() to check for uniqueness]. Same interface as collections. Elements are not maintained in any order. HashSet Used for fast lookups. **Objects should define own hashCode(), compareTo() and equals(). TreeSet Ordered Set, can be used to extract an ordered sequence from a Set. **Objects should define own equals() and compareTo(). 40. When creating own type and using Sets to store them, always implement the Comparable interface and define compareTo() method. 41. TreeSets are SortedSet, the elements are guaranteed to be in sorted order which allows additional functionality to be provided with SortedSet Interface: a. Comparator comparator() produces the Comparator used for this set or null for natural overlaoding. b. Object first() : produces the lowest element
c. Object last() : produces the highest element. d. SortedSet subset(fromElement, toElement) : produces a view of this Set with elements from fromElement(inclusive) to toElement(exclusive) e. SortedSet headSet(toElement) : Produces a view of this Set with elements less than toElement. f. SortedSet tailSet(fromElement) : Produces a view of this Set with elements greater than or equal to fromElement.
Maps 42. Maps associate an object stored in it with some other criteria, again an object which can be used to fetch objects. They are like lists which associate stored objects with indexes or numbers which are criterias for fetching them randomly. 43. Maps have put(Object key, Object Value), get(Object key), containsKey(Object Key), containsValue(Object Value) etc are few of the methods. Map (interface) Maintains Key-value pairs. Lookup done using Key HashMap Based on hash table (better than HashTable). Performance achieved through constructors which allows setting capacity and load factor of hash table beforehand. TreeMap (a type of SortedMap) Based on red-black tree. Sorted, **and is only Map with subMap() to get portion of Tree 44. SortedMaps (eg. TreeMaps) – keys are in sorted order. Have additional Functionality provided with SortedMap Interface: a. Comparator comparator() produces the Comparator used for this map or null for natural overlaoding. b. Object firstKey() : produces the lowest key c. Object lastKey() : produces the highest key. d. SortedMap subMap(fromKey, toKey) : produces a view of this map with elements from fromKey(inclusive) to toKey(exclusive) e. SortedSet headMap(toElement) : Produces a view of this map with keys less than toKey. f. SortedSet tailMap(fromElement) : Produces a view of this map with keys greater than or equal to fromKeys. 45. When creating own classes, if the classes doesn’t override the hashCode() and equals(), and doesn’t anyother class which is overiding this, then Object class methods are used and has following consequences: a. Object’s hashCode() is used to generate the hashCode for each object and default is storing address of its object. So lookup will fail b. Object’s equal() simply compares objects addresses. So when HashMap try to find if the key is equal to any other key in table, it uses this method and fails.
Hence one should always provide logic for hashCode() and equals() so that Hashed data structures can deal properly with the key. 46. ArrayList can be used to implement Maps by declaring and instantiating two ArrayLists – one for Key and one for Value. Then we can write put(), get(), entrySet() etc can be created easily. To improve the performance of such objects, keep the keys sorted and use Collection.binarySearch() to perform the lookup. 47. Terms related to HashMap: a. Capacity : No. of buckets in table. b. Initial capacity : no. of buckets when the table is created. c. HashMap and HashSet : constructors to set the initial capacity. d. Size : the number of enteris currently in the table e. Load factor : Size/capacity. i. 0 = means table is empty ii. 0.5 = means table is half full. iii. 0.75 is the default load factor , doesn’t rehash till the table is ¾ full ** A high load factor decreases space required by table but increases the lookup cost. ** if storing large enteries in HashMap, create them with large capacities to prevent from loads of auto rehashing. 48. java.lang.ref library has classes that allows greater flexibility in garbage collection (decreasing order of weakness . a. Abstract class Reference b. SoftReference – for implementing memory-sensitive caches. (optionally built on ReferenceQueue) c. WeakReference – for canonicalizing mappings where instances of object can be simultaneously used in multiple places, to save storage (that do not prevent their keys from being reclaimed) (optionally built on ReferenceQueue) d. PhantomReference – are for scheduling pre-mortem cleanup actions in more flexible wac than is possible with the Java finalization. (Can only be built on ReferenceQueue class) Each of these give different level of indirection for garbage collector (GC). 49. When object is reachable, means stack has ordinary reference that refer the object hence the garbage collector cannot release it as it is still used by the program. But if we want to allow the GC to release the object and also be able to reach that object, use Reference which is not an ordinary reference. 50. WeakHashMap – map to hold weak references, creation of canonicalized mappings to save storage by making only one instance of a particular value. When the value is needed by program, lookup is done for existing objects in mapping and use that. These maps allows the garbage collector (say a call to System.gc() ) to automatically clean up the keys and values which are automatically wrapped in WeakReferences by the map. 51. To choose from the containers: a. Generally legacy classes have the old code which doesn’t break like Hashtable, Vector and Stack.
b. Both LinkedList and ArrayList implements List interfaces. So program will produce same result. But ArrayList is backed by arrays (which are faster than any container for random access, lookups and iteration). But LinkedLists are implemented as doubly linked list (references pointing to prev and next element in list), so its insertion and espacially deletions are easy. By default choose ArrayList and change to LinkedLists if performance is impacted due to many insertions and removals. c. Vectors are not as fast as ArrayList so their use should be avoided. d. Set can be implemented as either a TreeSet or a HashSet. TreeSet are sorted, so if size of set is large, insertions tend to become slow. By default choose HashSet which are backed by HashMap. HashSet have superior performance espacially for addition and lookup. Just to have ordered set, use TreeSet. e. HashMaps are better and faster than Hashtables. TreeMap is slower than HashMap but they are used in situations where ordered list is required [call TreeMap.keySet().toArray()]. Use Array.binarySearch() to rapidly find objects. By default, choose HashMap and switch to TreeMap if ordering is must.
Collection Utilities enumeration(Collection) max(Collection), min(Collection) max(Collection, Comparator), min(Collection, Comparator) reverse() copy(List dest, List Src) fill(List list, Object o) nCopies(int n, Object o)
Produces an old-style Enumeration for the argument. Returns the min or max element of the collection using natural comparision method of objects Returns the min or max element of the collection using Comparator Reverses all the elements in place Copies element from source to destination Replace all the elements of the list with o Return a list of size n whose references all point to o.
52. min() and max() work with collections and not list 53. To make a Collection unmodifiable, use Collection class which allows passing the original container into Collection.unmodifiableCollection(), and hands back a read only version. The method can take Collection, Map, Set and List For example, Collection c = new ArrayList(); … c = Collection.unmodifiableCollection(c); // c is returned back as un modifiable. Calling unmidifiable method for a particular type does not throw compiler error. Once the Txformation has occurred, any calls to method that modify the contents of a particular container will produce UnsupportedOperationException. 54. To automatically synchronize a collection, use Collection.synchronizedCollection().
55. ConcurrentModificationException is thrown to prevent more than one process from modifying the contents of a container. This is fail-fast mechanism incorporated. For example, after getting an iterator from collection, if we modify same collection using add() method rather than using iterator, it will throw this exception. ** So its always better to get iterator after all elements are added to collection or use iterator to change the collection.
Old Containers 56. Vectors are like ArrayLists but has numerous flaws. 57. Enumeration is interface smaller than Iterator. It has two methods a. boolean hasMoreElements() – true if enumeration contains more elements b. Object nextElement() – returns the next element if there are anymore. Enumeration is only an interface (not an implementation). Always prefer Iterators in new classes. By calling Collections.enumeration(), we can produce enumeration for any collection But for vectors call VectorObject.elements() to get the enumeration. 58. Hashtables are now days not used. Prefer HashMaps. 59. Stack – inherited from Vector (so has smth extra). Its LIFO and has push(), pop() and other operations of vector like elementAt() as Stack is Vector. 60. BitSet – used to store a lot of binary info. a. Minimum size = long 64 bits. So if anything is less than this (like ints or chars) create new class as their would be wastage of space. Methods like set(), clear() are used to manipulate the contents. b.