Java Fundamentals: Part 1

Java Fundamentals: Part 1Vijay BalaBlockedUnblockFollowFollowingJan 6This document highlights some of the most important aspects of Java programming.

The keywords and concepts covered in this blog are commonly covered in software engineering interviews.

OutlineJava Keywords and ConceptsData StructuresJava 8Java Keywords and Concepts:A) final, finally, finalizeA.

1) finalWhen you assign the final reserved keyword to a variable in Java, this prevents modification of its’ state once initialized.

If a variable is declared as final, you cannot modify its’ value — the result if we were to try is an immediate Compile Time Error.

When you assign the final keyword to a class, this disallows the class from being extended.

When you assign the final keyword to a method, then it cannot be overridden.

It is important to note that in the case that a class is declared as final, then by default all methods in the class are also final… variables however are not.

A.

2) finallyThe finally keyword is a reserved keyword that really functions exactly as it’s named.

It is used in association with the try/catch block, and basically identifies a piece of code that always executes when the try block exists.

It is code that is executed even if an unexpected exception (checked or unchecked) occurs.

Common practice is to put cleanup code (i.

e.

close a file), or in a bigger picture — code that prevents resource leaks — in a finally block because the run-time system always executes the statements regardless of what happens in the try block.

try { int i = arr[4]; // this statement will never execute // as exception is raised by above statement System.

out.

println("Inside try block"); } catch(ArrayIndexOutOfBoundsException ex) { System.

out.

println("Exception caught in catch block"); } finally { System.

out.

println("finally block executed"); }A.

3) finalizeThe root of all classes — Object.

This class contains a finalize method, which gets invoked when the lifecycle of an object is coming to an end and the JVM figures out that a particular object should be garbage collected.

The main purpose of a finalize() method is provide a piece of code which allows for the release of resources used by objects BEFORE they’re removed from memory.

This method can serve as a safety net when other methods fail.

However, there are several problems that exist when using the reserved keyword finalizer, without getting into the implementation details, just realize a few things…No timing guarantee of method execution since garbage collection can occur at anytimeSystem resources are limited, not all code may be executed prior to a system crashPerformance hit due to the JVM having to work extra hard when dealing with objects containing a non-empty finalize()B) ImmutabilityB.

1) Why is it important?In Java, an object is immutable if its state cannot change after construction.

Immutable objects provide the benefit of being Thread safe — they do not permit concurrent modifications of the same instance across several threads.

Immutable objects can be passed around without fear they will be modified, and in the case that their is a modification in state, this results in a new instance.

B.

2) Examples of Immutable ClassesThe MOST POPULAR immutable class in Java is the String.

When you initialize a variable of the String type, that value is final by definition, and it cannot be modified.

Operations such as trim(), substring(), and replace() ALWAYS return a new instance, and don’t affect the current instance.

String test = "test";test = "changed"; // Compile time errorString test = "test";String testTrim = test.

trim(); // Correct – new instance returnedOther examples from the JDK include the wrapper classes: Integer, Float, and Boolean — these classes create a new instance every time you attempt to modify them.

B.

3) Create an Immutable ClassThere are a few rules that must be adhered to in order to create an immutable class…Mark all fields as finalThe whole point of an immutable class is to create an object that is safe from modification.

Marking all fields as final means that they cannot be changed after initial construction.

Mark the class as final — no classes can extend itMark the fields as final — one-time initialization2.

Don’t expose setter methodsIf you would like to expose methods which allow modification of an object’s state, you must always return a new instance of the class.

3.

Immutable classes can include mutable object referencesIf the class holds a mutable object, make sure to use a clone copy when modifying fields.

This is simple.

When we have an immutable class with a mutable object as a member variable, we will simply pass it into the constructor, the same as we do for all objects in OOP and additionally we will also create a new instance of that class.

It is on the new instance that we will extract the parameters from the object provided as input, and set on the new instance.

This is the clone copy method.

Upon setting all fields of the cloned copy, we will than assign the new object to the instance field for the class, ensuring our entire class remains immutable.

public class ImmutableObject { private final int primitiveField; private final Object objectField;public ImmutableObject(int p, Object o) { primitiveField = p; objectField = new Object(); // Clone objectField.

setField(o.

getField()); // Copy }}C) Abstract class vs.

InterfaceC.

1) Abstract classAn abstract class is a class which MUST contain one or more abstract methods.

All this really means is that a class marked as “abstract” can contain “abstract” methods (methods with no implementation), and/or regular methods which do contain implementation details.

The idea behind an abstract class is to provide a basic level of functionality across your class hierachy while also keeping in mind that operations may be performed differently for various classes.

An abstract method is useful when we want to force subclasses to provide a custom implementation for it.

C.

2) InterfaceAn interface is just like a class except that it can only contain method signatures and fields.

A Java interface cannot contain implementation details of the method, only the signature (name, parameters, exceptions, return type).

A class that implements an interface is required to provide implementation details for all methods of the interface.

A Java class can implement multiple Java interfaces but remember this requires that the class implement all associated methods.

Interfaces are a way of achieving polymorphism, a concept which implies that instances of a class (objects) can be used as if it were of different types.

Main idea: An abstract class can contain unimplemented (abstract) and implemented methods which can be inherited from.

An abstract class is extended.

An interface simply serves as a contract, and cannot provide any method implementations.

An interface is implemented.

Data StructuresA) Arrays vs.

LinkedListsA.

1) An array is an object that contains a number of similarly typed variables.

When we create an array, the JVM creates a contiguous block of memory with spaces in which the address of each member object may be stored.

In the case of an array of objects, the heap contains an linear data structure which contains references to the values stored in the array.

The array class is a member of the Java Collections Framework.

Big-O Worst-Case PerformanceAccess, Search, Insertion, DeletionO(1), O(n), O(n), O(n)A.

2) Similar to an array, a linked list is a linear data structure but elements are not stored in contiguous locations and every element is a separate object with a value and an address.

Each object is known as a node, and elements are linked using pointers and addresses.

It provides advantages for insertions and deletions because of its’ dynamic nature which allows for updates to the head and tail of the list, while it has a few disadvantages with the major one being that nodes cannot be accessed directly.

Access into the list requires that we need to start from one end of the list and traverse each link to reach our target node.

A LinkedList is a member of the Java Collections Framework.

Big-O Worst-Case Run-Time PerformanceAccess, Search, Insertion, DeletionO(n), O(n), O(1), O(1)B) SetsJust some things to remember:Does not allow duplicate valuesHas no guaranteed internal orderInterface in the collections packageConcrete implementations include: HashSet, TreeSet, LinkedHashSetBig-O Worst-Case Run-Time PerformanceAccess, Search, Insertion, DeletionO(1), O(1), O(1), O(1)C) Hash MapOne of the most useful data structures in all of programming is the HashMap.

A HashMap implements the Map interface in the JDK and is used to store data in “key/value” pairs, in which one one object, a key (index) is used to access another object (a value).

In contrast to an array which stores items in an ordered collection in which items are accessed with an index number, a HashMap allows for indexing via any class type.

Here is everything you need to know about a HashMap.

Internally, a HashMap is just an array of single linked lists as elements.

A HashMap cannot contain duplicate keysA HashMap can contain a null key and/or null valueC.

1) Hash Functions and Hash CollisionsWhen a user calls put(K key, V value) or get(Object key), the function computes the index of the bucket in which the entry should be.

All this means is that the input key is passed to a function which computes a hashcode.

This hashcode tells us where to place the value or where it is located.

A hash collision occurs when a hash function returns the same bucket location for two different keys.

Two different keys can be found to have the same hashCode in the case of two unequal objects in Java.

HashMap uses the equals() and hashCode() methods to find the bucket location for a given input key.

Remember that Java does guarantee that the same hash code will result for equal objects but not vice versa.

Prior to Java 8, HashMaps handled collisions by using a linked list to store map entries which end up in the same array location.

From Java 8 onwards, balanced trees are used in-place of linked lists when the size of the bucket grows beyond a certain threshold.

Due to the tree properties, the worst case performance of retrieval operations improves from O(n) to O(logn).

Step by step:put(K key, Value v) hash(key) → hashcode index = hash & (n-1) → index valueWhen there is a collision, entries are appended to a linked list or balanced tree.

get(Object key) hash(key) → hashcode index = hash & (n-1) → index valueuse equals() to compare the hashcode of the given key with the hashcode of the key at the index value.

If it matches then return the value, if it doesn’t then traverse the linked list or balanced tree at the index location until there is a match.

Big-O Worst-Case Run-Time PerformanceAccess, Search, Insertion, DeletionO(1), O(1), O(1), O(1)Java 8A) What is a default method and when should it be used?In Java 8, interfaces support the addition of a “default” identifier on method declarations.

Marking a method as default simply means that an implementation (filled in method body).

This specifies a piece of code to be executed as the default in a situation where a concrete class fails to provide an implementation for that method.

The benefit of using a default methods is backwards compatibility.

Default methods introduce a mechanism for adding functionality to an interface without breaking all classes that extend the interface.

Think about it, when you add a method to an interface, all subclasses require an implementation for that method.

when you add a method to an interface and identify it as default, subclasses CAN override the default implementation to extend the functionality or unconcerned classes can leave the method out and simply use the default behavior.

A.

1) Why not use an abstract class?Although this update in Java 8 does make it seem as though interfaces and abstract classes are the same… that is not the case.

An abstract class can define a constructor.

They can be objects with a state associated with them, in contrast to an interface which simply defines a contract.

Methods in an abstract class can modify both method arguments as well as fields of their class, whereas default methods in an interface can only access its arguments because interfaces do not have any state.

Both are really used for different purposes.

.

. More details

Leave a Reply