Java


Explanation of each keyword of public static void main (String args[])
public- main(..) is the first method called by java environment when a program is executed so it has to accessible from java environment. Hence the access specifier has to be public.
static: Java environment should be able to call this method without creating an instance of the class, so this method must be declared as static.
void: main does not return anything so the return type must be void
The argument String indicates the argument type which is given at the command line and arg is an array for string given during command line.
Calling constructor within another constructor in the same class?

public class Cons {

 public Cons() {
  // A no arguments constructor that sends default values to the largest
  this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
 }

 public Cons(int arg1, int arg2) {
  // An example of a partial constructor that uses the passed in arguments
  // and sends a hidden default value to the largest
  this(arg1,arg2, madeUpArg3Value);
 }

 // Largest constructor that does the work
 public Cons(int arg1, int arg2, int arg3) {
  this.arg1 = arg1;
  this.arg2 = arg2;
  this.arg3 = arg3;
 }
}

A class can contain any of the following variable types.
·      Local variables − Variables defined inside methods, constructors or blocks are called local variables. The variable will be declared and initialized within the method and the variable will be destroyed when the method has completed.
·      Instance variables − Instance variables are variables within a class but outside any method. These variables are initialized when the class is instantiated. Instance variables can be accessed from inside any method, constructor or blocks of that particular class.
·      Class variables − Class variables are variables declared within a class, outside any method, with the static keyword.
What is super?
super is a keyword which is used to access the method or member variables from the superclass. If a method hides one of the member variables in its superclass, the method can refer to the hidden variable through the use of the super keyword. In the same way, if a method overrides one of the methods in its superclass, the method can invoke the overridden method through the use of the super keyword.
Note:
·       You can only go back one level.
·       In the constructor, if you use super(), it must be the very first code, and you cannot access any this.xxx variables or methods to compute its parameters.
final Class in Java
Java class with final modifier is called final class in Java. Final class is complete in nature and can not be sub-classed or inherited. Several classes in Java are final e.g. String, Integer and other wrapper classes. Here is an example of final class in java

final class PersonalLoan{
}
class CheapPersonalLoan extends PersonalLoan{  //compilation error: cannot inherit from final class 
}
Benefits of final keyword in Java
1.     Final keyword improves performance. Not just JVM can cache final variable but also application can cache frequently use final variables.
2.     Final variables are safe to share in multi-threading environment without additional synchronization overhead.
3.     Final keyword allows JVM to optimized method, variable or class.

Constructor
A constructor is a special method whose task is to initialize the object of its class.
It is special because its name is the same as the class name.
They do not have return types, not even void and therefore they cannot return values.
They cannot be inherited, though a derived class can call the base class constructor.
Constructor is invoked whenever an object of its associated class is created.
differences between Constructors and Methods

Constructors
Methods
Purpose
Create an instance of a class
Group Java statements
Modifiers
Cannot be abstract, final, native, static, or synchronized
Can be abstract, final, native, static, or synchronized
Return Type
No return type, not even void
void or a valid return type
Name
Same name as the class (first letter is capitalized by convention) -- usually a noun
Any name except the class. Method names begin with a lowercase letter by convention -- usually the name of an action
this
Refers to another constructor in the same class. If used, it must be the first line of the constructor
Refers to an instance of the owning class. Cannot be used by static methods.
super
Calls the constructor of the parent class. If used, must be the first line of the constructor
Calls an overridden method in the parent class
Inheritance
Constructors are not inherited
Methods are inherited

Access Specifiers
One of the techniques in object-oriented programming is encapsulation. It concerns the hiding of data in a class and making this class available only through methods. Java allows you to control access to classes, methods, and fields via so-called access specifiers.
Different types of Access Specifiers in Java
Java offers four access specifiers, listed below in decreasing accessibility:
Publicpublic classes, methods, and fields can be accessed from everywhere.
Protectedprotected methods and fields can only be accessed within the same class to which the methods and fields belong, within its subclasses, and within classes of the same package.
Default (no specifier)- If you do not set access to specific level, then such a class, method, or field will be accessible from inside the same package to which the class, method, or field belongs, but not from outside this package.
Privateprivate methods and fields can only be accessed within the same class to which the methods and fields belong. private methods and fields are not visible within subclasses and are not inherited by subclasses.
 Situation 
 public 
 protected 
 default 
 private 
 Accessible to class
 from same package? 
yes
Yes
yes
No
 Accessible to class
 from different package? 
yes
 no, unless it is a subclass 
no
No

static methods?
Methods declared with the keyword static as modifier are called static methods or class methods. They are so called because they affect a class as a whole, not a particular instance of the class. Static methods are always invoked without reference to a particular instance of a class.
Note: The use of a static method suffers from the following restrictions:
A static method can only call other static methods.
A static method must only access static data.
A static method cannot reference to the current object using keywords super or this.

Static members (variables and methods) in Java offer several advantages: 

Memory Efficiency:

  • Static members belong to the class, not individual instances. This means they're allocated memory only once, regardless of the number of objects created, leading to efficient memory usage.
Shared Data:
  • Static variables provide a way to share data across all instances of a class. This is useful for maintaining global state or counters. 

Principle concepts of OOPS
There are four principle concepts upon which object-oriented design and programming rest. They are:
1.     Abstraction
2.     Polymorphism
3.     Inheritance
4.     Encapsulation
(i.e. easily remembered as A-PIE).

Abstraction:
Abstraction is a process of hiding the implementation details and showing only the functionality.
Abstraction refers to the act of representing essential features without including the background details or explanations.
There are two ways to achieve abstraction in java
  1. Abstract class
  2. Interface
Abstract class example
public abstract class Employee {
   private String name;
   private String address;
   private int number;

   public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
  
   public double computePay() {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
  
   public void mailCheck();
   }
}

Inheriting the Abstract Class
We can inherit the properties of Employee class just like concrete class in the following way
public class Salary extends Employee {
   private double salary;   // Annual salary   
   public Salary(String name, String address, int number, double salary) {
      super(name, address, number);  //calling the super class    
   }   
   public void mailCheck() {
               System.out.println("Within mailCheck of Salary class ");
               System.out.println("Mailing check to " + getName() + " with salary " + salary);
   }
}

Abstract Methods:
If you want a class to contain a particular method but you want the actual implementation of that method to be determined by child classes, you can declare the method in the parent class as an abstract.
·      abstract keyword is used to declare the method as abstract.
·      You have to place the abstract keyword before the method name in the method declaration.
·      An abstract method contains a method signature, but no method body.
·      Instead of curly braces, an abstract method will have a semoi colon (;) at the end.
Following is an example of the abstract method.
public abstract class Employee {
   private String name;
   private String address;
   private int number;   
   public abstract double computePay();
   // Remainder of class definition
}

Interface
An interface is a description of a set of methods that conforming implementing classes must have
Note:
You can’t mark an interface as final.
Interface variables must be static.
An Interface cannot extend anything but another interfaces
You can’t instantiate an interface directly, but you can instantiate a class that implements an interface.
Interfaces may have member variables, but these are implicitly public, static, and final
Only public and abstract modifiers are allowed for methods in interfaces.

Interface example
public interface Dog
{
               public boolean Barks();
               public boolean isGoldenRetriever();
}
Now, if a class were to implement this interface, this is what it would look like: 
public class SomeClass implements Dog
{
               public boolean Barks{
               // method definition here      
               }
               public boolean isGoldenRetriever{
               // method definition here
               }
}

What is a marker interface?
Marker interfaces are those which do not declare any required methods, but signify their compatibility with certain operations. The java.io.Serializableinterface and Cloneable are typical marker interfaces. These do not contain any methods, but classes must implement this interface in order to be serialized and de-serialized.

Abstract Class
Interfaces
An abstract class can provide complete, default code and/or just the details that have to be overridden.
An interface cannot provide any code at all, just the signature.
In case of abstract class, a class may extend only one abstract class.
A Class may implement several interfaces.
An abstract class can have non-abstract methods.
All methods of an Interface are abstract.
An abstract class can have instance variables.
An Interface cannot have instance variables.
An abstract class can have any visibility: public, private, protected.
An Interface visibility must be public (or) none.
If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly.
If we add a new method to an Interface then we have to track down all the implementations of the interface and define implementation for the new method.
An abstract class can contain constructors.
An Interface cannot contain constructors.
Abstract classes are fast.
Interfaces are slow as it requires extra indirection to find corresponding method in the actual class.
Abstract classes are useful in a situation that Some general methods should be implemented and specialization behavior should be implemented by child classes.

Interfaces are useful in a situation that all properties should be implemented.

Polymorphism
Polymorphism is briefly described as "one interface, many implementations." Polymorphism is a characteristic of being able to assign a different meaning or usage to something in different contexts - specifically, to allow an entity such as a variable, a function, or an object to have more than one form.
Polymorphism can be achieved by Inheritance, Overloading and Overriding.
There are two types of polymorphism one is Compile time polymorphism and the other is run time polymorphism. Compile time polymorphism is method overloading. Runtime time polymorphism is done using inheritance and interface.
NoteFrom a practical programming viewpoint, polymorphism manifests itself in three distinct forms in Java:
Method overloading
Method overriding through inheritance
Method overriding through the Java interface

runtime polymorphism or dynamic method dispatch?
In Java, runtime polymorphism or dynamic method dispatch is a process in which a call to an overridden method is resolved at runtime rather than at compile-time. In this process, an overridden method is called through the reference variable of a superclass. The determination of the method to be called is based on the object being referred to by the reference variable.

Dynamic  and Static Binding
Binding refers to the linking of a procedure call to the code to be executed in response to the call. Dynamic binding (also known as late binding) means that the code associated with a given procedure call is not known until the time of the call at run-time. It is associated with polymorphism and inheritance.
Here are a few important differences between static and dynamic binding:
1.     Static binding in Java occurs during compile time while dynamic binding occurs during runtime.
2.     privatefinal and static methods and variables use static binding and are bonded by compiler while virtual methods are bonded during runtime based upon runtime object.
3.     Static binding uses Type (class in Java) information for binding while dynamic binding uses object to resolve binding.
4.     Overloaded methods are bonded using static binding while overridden methods are bonded using dynamic binding at runtime.

Example of Dynamic Binding in Java
public class DynamicBindingTest {  
    public static void main(String args[]) {
        Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
        vehicle.start(); //Car's start called because start() is overridden method
    }
}

class Vehicle {
    public void start() {
        System.out.println("Inside start method of Vehicle");
    }
}

class Car extends Vehicle {
    @Override
    public void start() {
        System.out.println("Inside start method of Car");
    }
}
Output: Inside start method of Car

Method overloading
Method Overloading means to have two or more methods with same name in the same class with different arguments. The benefit of method overloading is that it allows you to implement methods that support the same semantic operation but differ by argument number or type.
Note:
Overloaded methods MUST change the argument list
Overloaded methods CAN change the return type
Overloaded methods CAN change the access modifier
Overloaded methods CAN declare new or broader checked exceptions
A method can be overloaded in the same class or in a subclass

Method overriding?
Method overriding occurs when sub class declares a method that has the same type arguments as a method declared by one of its superclass. The key benefit of overriding is the ability to define behavior that’s specific to a particular subclass type.
Note:
The overriding method cannot have a more restrictive access modifier than the method being overridden (Ex: You can’t override a method marked public and make it protected).
You cannot override a method marked final
You cannot override a method marked static
13. What are the differences between method overloading and method overriding?

Method Overloading

Method Overriding
Parameter must be different and name must be same
Both name and parameter must be same
Compile time polymorphism.
Runtime polymorphism
Increase readability of code
Increase reusability of code
Access specifier can be changed
Access specifier must not be more restrictive than original method (can be less restrictive)
Overloaded methods CAN change the access modifier
You cannot override a method marked static, or final


Inheritance
Inheritance is the process by which objects of one class acquire the properties of objects of another class.
A class that is inherited is called a superclass.
The class that does the inheriting is called a subclass.
Inheritance is done by using the keyword extends.
The two most common reasons to use inheritance are:
To promote code reuse
To use polymorphism

Encapsulation
Encapsulation is a technique used for hiding the properties and behaviors of an object and allowing outside access only as appropriate. It prevents other objects from directly altering or accessing the properties or methods of the encapsulated object.

           
public class EncapTest{
 
   private String name; //here we are hiding the value/data by making private.
   private String idNum;
   private int age;
 
   public int getAge(){
      return age;
   }
   public String getName(){
      return name;
   }
   public String getIdNum(){
      return idNum;
   }
   public void setAge( int newAge){
      age = newAge;
   }
   public void setName(String newName){
      name = newName;
   }
   public void setIdNum( String newId){
      idNum = newId;
   }
}

The public methods are the access points to this class fields from the outside java world. Normally, these methods are referred as getters and setters. Therefore, any class that wants to access the variables should access them through these getters and setters.
The variables of the EncapTest class can be access as below:
public class RunEncap{
 
   public static void main(String args[]){
      EncapTest encap = new EncapTest();
      encap.setName("Sathish");
      encap.setAge(35);
      encap.setIdNum("1234567");
      System.out.print("Name : " + encap.getName()+ 
                             " Age : "+ encap.getAge());
    }
}

Collections in Java
A Collection is a group of individual objects represented as a single unit. Java provides Collection Framework which defines several classes and interfaces to represent a group of objects as a single unit.
The Collection interface (java.util.Collection) and Map interface (java.util.Map) are the two main “root” interfaces of Java collection classes.
Hierarchy of Collection Framework




List Interface

List interface is the child interface of Collection interface.
1.     we can store the ordered collection of objects.
2.     It can have duplicate values.
List interface is implemented by using ArrayList, LinkedList, Vector, and Stack classes.
There are various methods in List interface that can be used to insert, delete, and access the elements from the list.

To instantiate the List interface, we must use:
List <data-type> list1= new ArrayList();  
List <data-type> list2 = new LinkedList();  
List <data-type> list3 = new Vector();  
List <data-type> list4 = new Stack();  

ArrayList

The ArrayList class implements the List interface.

It uses a dynamic array to store the duplicate element of different data types.

The ArrayList class maintains the insertion order

The ArrayList is non-synchronized.

The elements stored in the ArrayList class can be randomly accessed.

 

List<Integer> list = new ArrayList<>();
// we can have Integer, String, POJO class ...
        list.add(2);
        list.add(3);
        list.add(1);
        list.add(8);
        for (Integer integer : list) {
               System.out.println("\t" + integer);
        }
        list.set(3, 5);// we can update the value
        list.remove(2);
        list.add(1, 6);
 

LinkedList

LinkedList implements the Collection interface. It uses a doubly linked list internally to store the elements.
It can store the duplicate elements.
It maintains the insertion order
It is not synchronized. In LinkedList,
The manipulation is fast because no shifting is required.
// Creating a LinkedList
LinkedList<String> familyAndFriends = new LinkedList<>();
 
// Adding new elements to the end of the LinkedList using add() method.
familyAndFriends.add("Sathish");
familyAndFriends.add("Sony");
 
System.out.println("Initial LinkedList : " + familyAndFriends);
 
// Adding an element at the beginning of the LinkedList
familyAndFriends.addFirst("Kariyanna");
System.out.println("After addFirst(\"Kariyanna\") : " + familyAndFriends);
//Adding an element at the end of the LinkedList (This method is equivalent to the add() method)
familyAndFriends.addLast("Sanika");
System.out.println("After addLast(\"Sanika\") : " + familyAndFriends);
 
// Adding all the elements from an existing collection to the end of the
// LinkedList
List<String> faceBookFriends = new ArrayList<>();
faceBookFriends.add("Sai");
faceBookFriends.add("Vijay");
 
familyAndFriends.addAll(faceBookFriends);
System.out.println("After addAll(faceBookFriends) : " + familyAndFriends);
 
System.out.println("*************Retrieve LinkedListElements *********** ");
 
// Getting the first element in the LinkedList using getFirst()
 
String firstElement = familyAndFriends.getFirst();
System.out.println("First name in the list : " + firstElement);
 
// Getting the last element in the LinkedList using getLast()
String lastElement = familyAndFriends.getLast();
System.out.println("last name in the list  : " + lastElement);
 
// Getting the element at a given position in the LinkedList
String secondName = familyAndFriends.get(1);
System.out.println("second name in the list  : " + secondName);
 
// Remove element from the LinkedList
familyAndFriends.remove(4);
System.out.println("After removing 5th eleement, list is : " + familyAndFriends);
 
System.out.println("\n********* Iterate over a LinkedList using iterator() ************");
Iterator<String> humanSpeciesIterator = familyAndFriends.iterator();
while (humanSpeciesIterator.hasNext()) {
        String speciesName = humanSpeciesIterator.next();
        System.out.println(speciesName);
}
// Clear the LinkedList by removing all elements
familyAndFriends.clear();
System.out.println("Cleared the LinkedList => " + familyAndFriends);
 

Vector

Vector uses a dynamic array to store the data elements.
It is similar to ArrayList.
It is synchronized and contains many methods that are not the part of Collection framework.

Vector<String> vectColor=new Vector<String>();  
vectColor.add("Blue");  
vectColor.add("Green");  
vectColor.add("Red");  
vectColor.add("Yellow");  
vectColor.add("White");  
Iterator<String> itr= vectColor.iterator();  
while(itr.hasNext()){  
       System.out.println(itr.next());  
}  

 

Stack

It implements the last-in-first-out(LIFO) data structure.
The stack has some of the methods like boolean push(), boolean peek(), boolean push(object o), pop(), search(object o)
// Creating a Stack
Stack<String> stackOfCards = new Stack<>();
 
// Pushing new items to the Stack
stackOfCards.push("Jack");
stackOfCards.push("Queen");
stackOfCards.push("King");
stackOfCards.push("Ace");
 
System.out.println("Stack => " + stackOfCards);
System.out.println();
 
// Popping items from the Stack
String cardAtTop = stackOfCards.pop(); // Throws EmptyStackException if the stack is empty
System.out.println("Stack.pop() => " + cardAtTop);
System.out.println("Current Stack => " + stackOfCards);
System.out.println();
 
// Get the item at the top of the stack without removing it
cardAtTop = stackOfCards.peek();
System.out.println("Stack.peek() => " + cardAtTop);
System.out.println("Current Stack => " + stackOfCards);
 
// Check if the Stack is empty
System.out.println("Is Stack empty? : " + stackOfCards.isEmpty());
 
// Find the size of Stack
System.out.println("Size of Stack : " + stackOfCards.size());
 
// Search for an element
// The search() method returns the 1-based position of the
// element from the top of the stack
// It returns -1 if the element was not found in the stack
int position = stackOfCards.search("Queen");
 
if (position != -1) {
       System.out.println("Found the element \"Queen\" at
      position : " + position);
} else {
       System.out.println("Element not found");
}

Queue Interface

Queue interface maintains the first-in-first-out order(FIFO). It can be defined as an ordered list that is used to hold the elements which are about to be processed.
There are different implementation classes like PriorityQueue, Deque, and ArrayDeque
Queue interface can be instantiated as:
1.     Queue<String> q1 = new PriorityQueue();  
2.     Queue<String> q2 = new ArrayDeque();  

PriorityQueue
The PriorityQueue class implements the Queue interface. It holds the elements or objects which are to be processed by their priorities.
PriorityQueue doesn't allow null values to be stored in the queue.
Queue<Integer> integerPriorityQueue = new PriorityQueue<>(7);
integerPriorityQueue.add(1);
integerPriorityQueue.add(3);
integerPriorityQueue.add(2);
integerPriorityQueue.add(7);
integerPriorityQueue.add(4);
integerPriorityQueue.add(6);
integerPriorityQueue.add(5);
             
for (int i = 0; i < 7; i++) {
       Integer in = integerPriorityQueue.poll();
       System.out.println("Processing Integer:" + in);
}

ArrayDeque

ArrayDeque class implements the Deque interface. It facilitates us to use the Deque. Unlike queue, we can add or delete the elements from both the ends.
ArrayDeque is faster than ArrayList and Stack and has no capacity restrictions.
Consider the following example.
Deque<String> deque = new ArrayDeque<String>();
deque.add("Sathish");
deque.add("Kariyanna");
deque.add("Sam");
deque.add("Tom");
// Traversing elements in the Queue
for (String str : deque) {
       System.out.println(str);
}

Set Interface

It represents the unordered set of elements which doesn't allow us to store the duplicate items. We can store at most one null value in Set. Set is implemented by HashSet, LinkedHashSet(It maintains the insertion order), and TreeSet.

Set can be instantiated as:
1.     Set<data-type> s1 = new HashSet<data-type>();  
2.     Set<data-type> s2 = new LinkedHashSet<data-type>();  
3.     Set<data-type> s3 = new TreeSet<data-type>();  

 

HashSet

HashSet class implements Set Interface. It represents the collection that uses a hash table for storage. Hashing is used to store the elements in the HashSet. It contains unique items.

// Set demonstration using HashSet
Set<String> hash_SetA = new HashSet<String>();
hash_SetA.add("Sathish");
hash_SetA.add("Tom");
hash_SetA.add("King");
hash_SetA.add("Mike");
hash_SetA.add("Tom");
System.out.print("Set output without the duplicates");
System.out.println(hash_SetA);

 

LinkedHashSet

LinkedHashSet class represents the LinkedList implementation of Set Interface. It extends the HashSet class and implements Set interface. Like HashSet.
it also contains unique elements(No duplicate elements).
It maintains the insertion order and permits null elements.

// LinkedHashSet of String Type
LinkedHashSet<String> lhset = new LinkedHashSet<String>();
 
// Adding elements to the LinkedHashSet
lhset.add("Y");
lhset.add("QA");
lhset.add("AB");
lhset.add("N");
lhset.add("K");
System.out.println("LinkedHashSet of String : " + lhset);
 
// This will not add new element as N already exists
lhset.add("N");
lhset.add("E");
 
System.out.println("Size of LinkedHashSet = " + lhset.size());
System.out.println("Original LinkedHashSet:" + lhset);
System.out.println("Removing K from LinkedHashSet: " + lhset.remove("K"));
System.out.println("Trying to Remove C which is not " + "present: " + lhset.remove("C"));
System.out.println("Checking if N is present=" + lhset.contains("N"));
System.out.println("Updated LinkedHashSet: " + lhset);

 

SortedSet Interface

SortedSet is the alternate of Set interface that provides a total ordering on its elements. The elements of the SortedSet are arranged in the increasing (ascending) order. The SortedSet provides the additional methods that inhibit the natural ordering of the elements.

The SortedSet can be instantiated as:
SortedSet<data-type> set = new TreeSet();  

 

TreeSet

Java TreeSet class implements the Set interface that uses a tree for storage. Like HashSet,

TreeSet also contains unique elements. However
Tthe access and retrieval time of TreeSet is quite fast.
The elements in TreeSet stored in ascending order.

// Set demonstration using TreeSet
Set<String> tree_SetA = new TreeSet<String>();
Set<String> tree_SetA_Reverse = new TreeSet<String>();
tree_SetA.add("Sathish");
tree_SetA.add("Tom");
tree_SetA.add("King");
tree_SetA.add("Mike");
tree_SetA.add("Tom");
System.out.print("Set output without the duplicates");
System.out.println(tree_SetA);
 
// creating reverse set 
tree_SetA_Reverse = ((TreeSet<String>) tree_SetA).descendingSet();
System.out.println("Set output in reverse order :" + tree_SetA_Reverse);

Some of the additional methods present in the Collections
java.util.Collections.rotate()
It is used to rotate the elements present in the specified list of Collection by a given distance.
// to rotate the element by distance 2
Collections.rotate(list, 2);
Original List : [A, B, C, D]
Rotated List: [C, D, A, B]
java.util.Collections.disjoint()
It is used to check whether two specified collections are disjoint or not. Two collections are disjoint if they have no elements in common.

List<String>  mylist1  = Arrays.asList("Physics", "Chemistry");
List<String>  mylist2  = Arrays.asList("Biology", "Computers");
List<String>  mylist3  = Arrays.asList("Physics", “Electronics");
System.out.println("mylist1 disjoint to mylist2 : " +
                           Collections.disjoint(mylist1, mylist2));          
System.out.println("mylist1 is not disjoint to mylist3 : " +
                            Collections.disjoint(mylist1, mylist3));



java.util.Collections.frequency()
It is used to get the frequency of a element present in the specified list of Collection. It returns the number of elements e in the collection.
int frequency = Collections.frequency(mylist, "sathish");

java.util.Collections.reverse()
java.util.Collections.reverse() method is a java.util.Collections class method. It reverses the order of elements in a list passed as an argument.
Collections.reverse(list);

java.util.Collections max()
java.util.Collections class is used to return the maximum element of the given collection
Collections.max(list));

MAP

The java.util.Map interface represents a mapping between a key and a value. The Map interface is not a subtype of the Collection interface. Therefore it behaves a bit different from the rest of the collection types.


Most used MAP interface diagram


Complete MAP interface diagram



Few characteristics of the Map Interface are:
1.     A Map cannot contain duplicate keys and each key can map to at most one value. Some implementations allow null key and null value like the HashMap and LinkedHashMap, but some do not like the TreeMap,, HashTable.
2.     The order of a map depends on specific implementations, e.g TreeMap and LinkedHashMap have predictable order, while HashMap and HashTable does not.
3.     There are two interfaces for implementing Map in java: Map and SortedMap, and four classes: HashMap, HashTable, TreeMap and LinkedHashMap.

Most used Methods in Map Interface:
1.     public Object put(Object key, Object value): This method is used to insert an entry in this map.
2.     public void putAll(Map map): This method is used to insert the specified map in this map.
3.     public Object remove(Object key): This method is used to delete an entry for the specified key.
4.     public Object get(Object key):This method is used to return the value for the specified key.
5.     public boolean containsKey(Object key): This method is used to search the specified key from this map.
6.     public Set keySet(): This method is used to return the Set view containing all the keys.
7.     public Set entrySet(): This method is used to return the Set view containing all the keys and values.

HashMap

The HashMap class uses a hashtable to implement the Map interface.

HashMap<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "One");
map.put(3, "Three");
map.put(2, "Two");
 
String value = map.get(1);
System.out.println("Key:1 " + " value: " + value);
System.out.println("looping HashMap in Java using EntrySet and java5 for loop");
for (Entry entry : map.entrySet()) {
       System.out.println("key: " + entry.getKey() + " value: " + entry.getValue());
}


HashTable

This class implements a hash table, which maps keys to values. Any non-null object can be used as a key or as a value.
It is similar to HashMap, but is synchronized.
// Creating a Hashtable
Map<String, String> hashtable = new Hashtable<String, String>();
// Adding Key and Value pairs to Hashtable
hashtable.put("Key1", "Tom");
hashtable.put("Key2", "Mike");
hashtable.put("Key3", "King");
hashtable.put("Key4", "Joe");
hashtable.put("Key5", "Suhash");
System.out.println("Iterating or looping map using KeySet Iterator");
Iterator<String> keySetIterator = hashtable.keySet().iterator();
while (keySetIterator.hasNext()) {
       String key = keySetIterator.next();
       System.out.println("key: " + key + " value: " + hashtable.get(key));
}

LinkedHashMap

LinkedHashMap is just like HashMap with an additional feature of maintaining an order of elements inserted into it. HashMap provided the advantage of quick insertion, search and deletion but it never maintained the track and order of insertion which the LinkedHashMap provides where the elements can be accessed in their insertion order.

// Adding Key and Value pairs to Hashtable
linkedHashMap.put("Key1", "Tom");
linkedHashMap.put("Key2", "Mike");
linkedHashMap.put("Key3", "King");
linkedHashMap.put("Key4", "Joe");
linkedHashMap.put("Key5", "Suhash");
// It prints the elements in the inserted     System.out.println(linkedHashMap); 
        
System.out.println("delete element 'Key3': " + linkedHashMap.remove("Key3")); 
System.out.println(linkedHashMap);

TreeMap
We use TreeMap when we need to store unique elements in a sorted order.
System.out.println("TreeMap Desc Order Example");
TreeMap<String, String> map1 = new TreeMap<String, String>(new DescOrder());
map1.put("A1", "A1 value");
map1.put("A4", "A4 value");
map1.put("A2", "A2 Value");
map1.put("A10", "A10 Value ");
map1.put("A30", "A30 value");
// map1.put(null, "A30 value"); //Tree map can not hold null key
map1.put("A31", null); // Tree map can have null value
map1.put("A41", null);
map1.put("A41", "33");
 
System.out.println(map1);