Monday, 27 February 2017

Type erasure in Java Generics

When generics was introduced in Java there was a requirement for it to be compatible with the existing code, written in previous versions, which of course was non-generic. That is why you can still add raw types (List alist = new ArrayList(); this will give you warning for raw type but you can still have a non-generic list like this) and another thing that happens internally is type erasure.

The Java compiler applies type erasure to -

  • Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. Which means, if you have a unbounded type parameter that will be replaced by Object while compiling the code. If there is a bounded parameter that will be replaced by the provided bound.
    The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
  • Insert type casts if necessary to preserve type safety.
  • Generate bridge methods to preserve polymorphism in extended generic types.

Erasure of type parameters

As mentioned above, during the type erasure process, the Java compiler erases all type parameters and replaces each with its first bound if the type parameter is bounded, or Object if the type parameter is unbounded.

As example if you have the following generic class

 
public class GenType<T> {
    T obj;

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }
    
}

here type parameter T is unbounded, thus the Java compiler replaces it with Object, so your compiled class won’t have any type parameter

public class GenType {
    Object obj;

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }
}

If your class were using a bounded parameter as below -

public class GenType<T extends Number> {
    T obj;

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }   
}

Here it will be replaced by the bound i.e. Number

public class GenType {
    Number obj;

    public Number getObj() {
        return obj;
    }

    public void setObj(Number obj) {
        this.obj = obj;
    }  
}

Bridge methods

When compiling a class or interface that extends a parametrized class or implements a parametrized interface, the compiler may need to create a synthetic method, called a bridge method, as part of the type erasure process. In order to get an idea what bridge methods are let’s see an example.

If we have the following two classes -

GenType

public class GenType<T> {
    T obj;
    public GenType(T obj) { 
        this.obj = obj; 
    }

    public void setObj(T obj) {
        this.obj = obj;
    }
    
}

MyGen

 
public class MyGen extends GenType<Integer> {
     public MyGen(Integer num) { 
         super(num); 
     } 
     public void setObj(Integer data) {
       System.out.println(" In MyGen.setData");
       super.setObj(data);
    } 
}

Here note that MyGen class extends the GenType class which has the Integer parameter. After compilation and type erasure type parameters will be removed from both the classes and these classes will look as follows -

 
public class GenType {
 Object obj;
 public GenType(Object obj) { 
  this.obj = obj; 
 }

 public void setObj(Object obj) {
  this.obj = obj;
 }
 
}
 
public class MyGen extends GenType {
  public MyGen(Integer num) { 
   super(num); 
  } 
  public void setObj(Integer num) {
       System.out.println(" In MyGen.setData");
       super.setObj(num);
    }
 
}

If you have noticed, after type erasure the the setObj() method signatures don’t match in GenType and MyGen classes. In GenType class it becomes setObj(Object obj) where as in MyGen it becomes setObj(Integer num).

Therefore, the MyGen setObj method does not override the GenType setObj method.

To solve this problem and preserve the polymorphism of generic types after type erasure, a Java compiler generates a bridge method to ensure that subtyping works as expected. For the MyGen class, the compiler generates the following bridge method for setObj:

 
public class MyGen extends GenType {
  public MyGen(Integer num) { 
   super(num); 
  } 

  // Bridge method generated by the compiler
  public void setObj(Object num) {
  setObj((Integer) num);
  }
  public void setObj(Integer num) {
           System.out.println(" In MyGen.setData");
           super.setObj(num);
    }
 
}

Here you can see a bridge method which has the same signature as the setObj method of the GenType class is inserted and it delegates to the actual setObj method.

Generics Ambiguity errors

Let’s say you have the following class where you are trying to have two overloaded methods (set) with different type parameters K and V respectively.

 
class GenClass<K, V>{
    private K key;
    private V value;
    public GenClass(K key, V value) {
        this.key = key;
        this.value = value;
    }
    
    public void set(K key){
        this.key = key;
    }
    
    public void set(V value){
        this.value = value;
    }
    
    public K getKey(){
        return key;
    }
    public V getValue(){
        return value;
    }
}

This class will give compilation error
Erasure of method set(K) is the same as another method in type GenClass<K,V>
Erasure of method set(V) is the same as another method in type GenClass<K,V>

Though you may think since K and V are two different parameters so its ok to write overloaded methods using these parameters as arguments. But there is no such compulsion that these two parameters will be different, at the time of creating objects you can provide same type for both the type parameters.

Also type erasure will replace the type parameter with Object in this case so both the methods will become -

 
public void set(Object key){
 this.key = key;
}
 
public void set(Object value){
 this.value = value;
}

In a case like this it is better to give different name for the methods and avoid any ambiguity.

That's all for this topic Type erasure in Java Generics. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Generics in Java
  2. Generic class, interface and generic method
  3. Bounded type parameter in Java generics
  4. Wildcard in Java Generics
  5. Lambda expressions in Java 8

You may also like -

>>>Go to Java advance topics page

Thursday, 23 February 2017

How to count lines in a File - Java Program

Sometimes you just want to count the number of lines in the file, rather than reading the file and performing some logic. The easiest way, I feel, is to use LineNumberReader for counting the lines. LineNumberReader class has a method getLineNumber() that gives the current line number of the file. So the logic is; to read all the lines of the files using the LineNumberReader until you reach the end and then use getLineNumber() method to get the current line number.

Example code

If you have a file with lines as follows -

This is a test file.
Line number reader is used to read this file.
This program will read all the lines.
It will give the count.

Then you can get the count of lines using the following code -

 
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

public class LineNumberDemo {

 public static void main(String[] args) {
  LineNumberReader reader = null;
     try {
         reader = new LineNumberReader(new FileReader(new File("F:\\abc.txt")));
         // Read file till the end
         while ((reader.readLine()) != null);
         System.out.println("Count of lines - " + reader.getLineNumber());
     } catch (Exception ex) {
      ex.printStackTrace();
     } finally { 
         if(reader != null){
    try {
     reader.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
         }
     }

 }

}

Output

Count of lines – 4

Printing lines of the file with line number

If you want to print lines of the file along with the line number you just need to tweak the above code a little.

Java code

 
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

public class LineNumberDemo {

 public static void main(String[] args) {
  LineNumberReader reader = null;
     try {
         reader = new LineNumberReader(new FileReader(new File("F:\\abc.txt")));
         String str;
         // Read file till the end
         while ((str = reader.readLine()) != null){
          System.out.println(reader.getLineNumber() + "- " + str);
         }
         
     } catch (Exception ex) {
      ex.printStackTrace();
     } finally { 
         if(reader != null){
    try {
     reader.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
         }
     }

 }

}

Output

1- This is a test file.
2- Line number reader is used to read this file.
3- This program will read all the lines.
4- It will give the count.

That's all for this topic How to count lines in a File - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Reading delimited file in Java using Scanner
  2. Reading file in Java 8
  3. Zipping files in Java
  4. How to create PDF from XML using Apache FOP
  5. How to read file from the last line in Java

You may also like -

>>>Go to Java Programs page

Wednesday, 22 February 2017

Object creation using new operator in Java

In OOP a class provides the blueprint for objects; you create an object from a class. When a new class is created essentially a new data type is created. This type can be used to declare objects of that type.

Creating Objects

Creation of an object for a class is done in three steps -

  • Declaration - Declare a variable of the class type, note that no object is defined yet. This variable can refer to an object as and when the object is created.
  • Instantiation - Create an object and assign it to the variable created in step 1. This object creation is done using new operator.
  • Initialization - Class name followed by parenthesis after the new operator (new classname()) means calling the constructor of the class to initialize the object.

General form of using new operator by combining all these three steps is as -

Class_Name class_Variable = new Class_Name();

Here Class_Name is the class whose object is created and class_Variable is the variable that refers to the created object. Here note that when you refer Class_Name followed by parenthesis, you are actually calling the constructor of the class to initialize the object. That constructor may be a constructor with arguments or a no-argument constructor (or default constructor).

Let’s go through the steps of declaration, instantiation and initialization -

Declaring a Variable to Refer to an Object

When you just declare a variable no memory is allocated for it. As example if you declare a variable obj of class Test -

Test obj;

What you have done here is to notify the compiler that you will use obj to refer to data whose type is Test.

At this stage, when you have just declared the variable test, it doesn’t refer to an object. Actually its value is undetermined at this time. To create an object you need to use the new operator. You must assign an object to obj before you use it in your code. Otherwise, you will get a compiler error.

A variable in this state, which currently has no reference to any object can be pictorially represented as follows -

object declaration
Object declaration

Instantiating a Class

The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory. The new operator also invokes the object constructor.

The new operator requires a single, postfix argument: a call to a constructor and it returns the refrence to the object it created. This reference is usually assigned to a variable of the appropriate type, As example

Test obj = new Test(9, 10);

Initializing an Object

The last step is to initialize an object. This is the process where constructor of the class is called to initialize the object.

As example -

If we have a Test class as follows -

public class Test{
    public int x = 0;
    public int y = 0;
    //constructor
    public Test(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

This class contains a single constructor which takes two integer arguments, in order to initialize a object created using new operator you can have a statement as follows -

Test obj = new Test(9, 10);

Here you have a variable obj of type Test, using new operator you have created a new object of class Test and initialized it to have values 9 and 10 for variables x and y respectively. So, this instantiation of class Test has its variables initialized to 9 and 10 i.e. obj.x = 9 and obj.y = 10.

obj is the variable that refers to the object.

If we have to pictorially represent this instantiation and initialization, it will look as follows.

Initializing an Object
Initializing an Object

That's all for this topic Object creation using new operator in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Package in Java
  2. Access modifiers in Java
  3. Abstraction in Java
  4. Difference between abstract class and interface
  5. abstract class in Java

You may also like -

>>>Go to Java Basics page

Monday, 20 February 2017

Wildcard in Java Generics

In Java generics there is also an option of giving question mark (?) called wild card as type. This question mark(?) represents an unknown type.

The wildcard can be used in a variety of situations -

  • As the type of a parameter, field, or local variable;
  • Sometimes as a return type (though it is better programming practice to be more specific).

Wildcards can be classified into three types -

  1. Upper bounded wildcards
  2. Lower bounded wildcards
  3. Unbounded wildcards

Upper bounded wildcards

The way we can have bounded parameters in generics same way we can have bounded wildcards too. So let’s see with an example when we should have upper bounded wildcards.

Suppose you want to write a method that can take list of any type of Number which means a method that works on lists of Number and the subtypes of Number, such as Integer, Double, and Float i.e. List<Integer>, List<Double>, and List<Number>.

Here note one thing, though Integer is a subtype of Number, List<Integer> is not a subtype of List<Number> and, in fact, these two types are not related. Same applies for Double and Float too.

So you can’t have your method as follows -

public static  double sumOfElements(List<Number> list){
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}

If you try to write your method as above you can’t call it with a List with integers because of the reason stated above.

List<Integer> li = Arrays.asList(1, 2, 3);
System.out.println("sum = " + sumOfElements(li));

Trying to call the sumOfElements method with argument List<Integer> will result in compile-time error

The method sumOfElements(List<Number>) in the type WildCardDemo is not applicable for the arguments (List<Integer>)

In the case like this where you want your method to be generic enough to be able to work with a list of type Number or any of its subclasses. you can achieve this by using an upper bounded wildcard.

General form of upper bounded wildcard

To declare an upper-bounded wildcard, use the wildcard character ('?'), followed by the extends keyword, followed by its upper bound.

<? extends UpperBoundType>

Example code with upper bounded wildcard

To write the above mentioned method sumOfElements so that it works with Number or any of its subtype you need to provide a wild card and Number as the upper bound i.e. <? extends Number>. This will match Number or any of its subtype.

Full code

import java.util.Arrays;
import java.util.List;

public class WildCardDemo {

    public static void main(String[] args) {
        // With List<Integer>
        List<Integer> li = Arrays.asList(5, 6, 7);
        System.out.println("sum = " + sumOfElements(li));
        // With List<Double>
        List<Double> ld = Arrays.asList(1.2, 3.8, 8.2);
        System.out.println("sum = " + sumOfElements(ld));
    }
    
    public static  double sumOfElements(List<? extends Number> list){
         double s = 0.0;
            for (Number n : list)
                s += n.doubleValue();
            return s;
    }

}

Output

sum = 18.0
sum = 13.2

Unbounded wildcards

Unbounded wildcards are, as the name suggests, wild cards with out any upper or lower bound. Unbounded wildcard type is specified using the wildcard character (?), for example, List<?>.This is called a list of unknown type.

There are two scenarios where an unbounded wildcard is a useful approach -

  • If you are writing a method that can be implemented using functionality provided in the Object class.
  • When the code is using methods in the generic class that don't depend on the type parameter. For example, List.size or List.clear.

Example

Suppose you want to write a method that can print elements of a List of any type. If you write that method using Object as type for the List, you will get an error when you pass it a List of integers.

public static void printElements(List<Object> list){
     for (Object elem : list){
        System.out.println(elem + " ");
     }
     System.out.println();
}

If you try to invoke this method using the following lines -

List<Integer> li = Arrays.asList(5, 6, 7);
printElements(li);

You will get compile-time error -

The method printElements(List<Object>) in the type WildCardDemo is not applicable for the arguments (List<Integer>)

You get this error because the above method prints only a list of Object instances; it cannot print List<Integer>, List<String>, List<Double>, and so on, because they are not subtypes of List<Object>. To write a generic printElements method, use List<?>:

import java.util.Arrays;
import java.util.List;

public class WildCardDemo {

    public static void main(String[] args) {
        // With List<Integer>
        List<Integer> li = Arrays.asList(5, 6, 7);
        printElements(li);
        // With List<Double>
        List<Double> ld = Arrays.asList(1.2, 3.8, 8.2);
        printElements(ld);
    }
    

    public static void printElements(List<?> list){
         for (Object elem : list){
                System.out.print(elem + " ");
         }
         System.out.println();
    }

}

Output

5 6 7 
1.2 3.8 8.2

Lower Bounded Wildcards

The way Upper bounded wildcard restricts the unknown type to be a specific type or a subtype of that type same way lower bounded wildcard restricts the unknown type to be a specific type or a super type of that type.

General form of the lower bounded wildcard

A lower bounded wildcard is expressed using the wildcard character ('?'), following by the super keyword, followed by its lower bound:

<? super bounded_type>

Example code

Suppose you want to write a method that put elements of type Integer into a List. If you want to make sure that method works for List<Integer>, List<Number>, and List<Object> — anything that can hold Integer values. Here note that Number and Object are super type of Integer.

That generic method can be written as follows by using the lower bounded wildcard where lower bound is Integer.

public static void addNumbers(List<? super Integer> list) {
    for (int i = 1; i <= 10; i++) {
        list.add(i);
    }
}

You can invoke this method using the following code -

// Using object
List<Object> lo = new ArrayList<Object>();
addNumbers(lo);
// Using Integer
List<Integer> li = new ArrayList<Integer>();
addNumbers(li);

Note - You can specify an upper bound for a wildcard, or you can specify a lower bound, but you cannot specify both.

Reference : https://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html

That's all for this topic Wildcard in Java Generics. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Generics in Java
  2. Generic class, interface and generic method
  3. Bounded type parameter in Java generics
  4. covariant return type in Java

You may also like -

>>>Go to Java advance topics page

Thursday, 16 February 2017

Splitting a String - Java Program

In many applications you get data in a text file which is either separated using a pipe (|) symbol or a tab symbol (/t). Now, if you want to do a quick split around that separating symbol you can easily do it using split() method which is in the String class itself.

In this post we’ll see how to split a String using split() method -

Splitting pipe delimited data - Example code

 
public class SplitDemo {

 public static void main(String[] args) {
  String str = "E001|Ram|IT|India|";
  // splitting
  String[] rec = str.split("\\|");
  System.out.println("" + rec[3]);
 }
}

Output

India

Points to note

  1. Since pipe (|) is also used in conditions like OR (||) so that is a special symbol and needs to be escaped.
  2. split() method returns the array of strings computed by splitting this string around matches of the given regular expression.

Splitting tab delimited data – Example code

You can use the following code snippet if you are splitting tab delimited data.

 
String str = "E001 Ram IT India";
// splitting
String[] recArr = str.split("\t");
for(String rec : recArr){
 System.out.println(" " + rec);
}

Output

 E001
 Ram
 IT
 India

Splitting dot delimited data – Example code

You can use the following code snippet if you are splitting dot (.) delimited data. Note that . Has to be escaped as it is a special symbol.

 
String str = "E001.Ram.IT.India";
// splitting
String[] recArr = str.split("\\.");
for(String rec : recArr){
 System.out.println(" " + rec);
}

Output

 E001
 Ram
 IT
 India
 

That's all for this topic Splitting a String - Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Check whether a given String/Number is a palindrome or not
  2. Converting string to double - Java Program
  3. How to add double quotes to a String
  4. Matrix Multiplication Java Program
  5. Zipping files in Java

You may also like -

>>>Go to Java Programs page

Wednesday, 15 February 2017

Bounded type parameter in Java generics

In the post generics in Java you would have already seen example where type parameters are replaced by any class type. But there are times when you want to restrict the types that can be used as type arguments in a parametrized type.

As example if you have a generic class with a method that operates on numbers you would want to restrict it to accept instances of Number or its subclasses only.

Let’s first see an example where you don’t do it to analyse what happens in that case -

You have a generic class Test with a method average which returns the average of the numbers in the array passed to it. Since the class is generic so you intend to pass array of any type integer, double, float. Here return type of method average is double as you want an accurate value. Since Number class (Super class of all numeric classes) has doubleValue() method so you can always get the double value out of any type of number.

 public class Test<T> {
    T[] numArr;
    Test(T[] numArr){
        this.numArr = numArr;
    }
    public double getAvg(){
        double sum = 0.0;
        for(int i = 0; i < numArr.length; i++){
            sum += numArr[i].doubleValue();
        }
        double avg = sum/numArr.length;
        return avg;
    }
}

This code will give you compile-time error -

The method doubleValue() is undefined for the type T

You get this error as there is no way for compiler to know type T will always be used for numeric classes. You need to let the compiler know. That’s when you need bounded type to restrict the types that can be used for parametrized type. In the above case that restriction is; the type should be Number.

Bounded type

In order to create a bounded type what you need to provide is an upper bound which acts as a restriction for types. As this upper bound is a superclass and the type that can be used has to be a sub class of that upper bound.

General form of bounded type parameter

To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound.

T extends superclass

In the example used above that upper bound has to be the Number class as Number class is the super class of all the numeric classes. Thus in that case your bounded type will be - T extends Number

Example code with bounded type

public class Test<T extends Number> {
    T[] numArr;
    Test(T[] numArr){
        this.numArr = numArr;
    }
    public double getAvg(){
        double sum = 0.0;
        for(int i = 0; i < numArr.length; i++){
            sum += numArr[i].doubleValue();
        }
        double avg = sum/numArr.length;
        return avg;
    }
}

Now you won’t get compile-time error as you have provided the Number class as upper bound for your generic type T. Which means any type passed for the generic type T has to be the sub class of class Number. Since doubleValue() method is in Number class it will be part of any sub class of Number through inheritance. So no compile-time error!

Multiple Bounds

A type parameter can have multiple bounds:
<T extends B1 & B2 & B3>

A type variable with multiple bounds is a subtype of all the types listed in the bound. If one of the bounds is a class, it must be specified first. For example:

Class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }

class D <T extends A & B & C> { /* ... */ }

Not specifying bounds in this order will result in compile-time error.

Generic Methods and Bounded Type Parameters

You can also use bounded types with generic methods. Let’s see an example where it becomes necessary to use bounded types. Consider a method where you want to count the number of elements in an array greater than a specified element elem.

public static <T> int countGreaterThan(T[] anArray, T elem) {
    int count = 0;
    for (T e : anArray)
        if (e > elem)  // compiler error
            ++count;
    return count;
}

This method will result in compile-time error as greater than (>) operator can be used only with primitive types such as short, int, double, long, float, byte, and char. It can’t be used to compare objects, you have to use types that implement Comparable interface in order to compare objects. Thus, Comparable interface becomes the upper bound in this case.

Code with upper bound

public class Test{
    public <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {
        int count = 0;
        for (T e : anArray){
            if (e.compareTo(elem) > 0) {
                ++count;
            }
        }
        return count;
   }
}

You can use the following code to run it -

Test test = new Test();
Integer[] numArr = {5, 6, 7, 1, 2};
int count = test.countGreaterThan(numArr, 5);
System.out.println("count - " + count);

Output

count – 2

That's all for this topic Bounded type parameter in Java generics. If you have any doubt or any suggestions to make please drop a comment. Thanks!

Reference - https://docs.oracle.com/javase/tutorial/java/generics/boundedTypeParams.html


Related Topics

  1. Generics in Java
  2. Generic class, interface and generic method
  3. varargs in Java
  4. Method reference in Java 8
  5. Spliterator in Java

You may also like -

>>>Go to Java advance topics page

Tuesday, 14 February 2017

Generic class, interface and generic method

In the post generics in Java basics of Java generics are already covered. In this post we’ll see how to create generic class, generic method and generic interface.

Generic class

A generic class is defined with the following format:

class name<T1, T2, ..., Tn> { 
    /* ... */ 
} 

The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies the type parameters (also called type variables) T1, T2, ..., and Tn.

Generic class example

Let us create a generic class with two type parameters and see it in use with different data types.

class GenClass<K, V>{
    private K key;
    private V value;
    public GenClass(K key, V value) {
        this.key = key;
        this.value = value;
    }
    public K getKey(){
        return key;
    }
    public V getValue(){
        return value;
    }
}

public class GClassDemo {

    public static void main(String[] args) {
        GenClass<String, String> g1 = new GenClass<>("A", "Value A");
        System.out.println("Key- " + g1.getKey());
        System.out.println("Value- " + g1.getValue());
        
        GenClass<Integer, String> g2 = new GenClass<>(1, "Value 1");
        System.out.println("Key- " + g2.getKey());
        System.out.println("Value- " + g2.getValue());

    }

}

Output

Key- A
Value- Value A
Key- 1
Value- Value 1

Here you can see that first time String is passed as the type for both generic types K and V, where as it is passed as Integer and String second time.

Generic Interface

You can create a generic interface much the same way as a generic class but there are some conditions while implementing the generic interface.

Generic interface example

public interface GInterface<E> {
    void setValue(E e);
    E getValue();
}

Implementing class

import org.netjs.examples.interfaces.GInterface;

public class GClassImpl<E> implements GInterface<E> {
    E e;
    @Override
    public void setValue(E e) {
        this.e = e;
        
    }

    @Override
    public E getValue() {
        return e;
    }
}

Points to note here

  1. Here note that a class that implements a generic interface has to be a generic class.
    public class GClassImpl<E> implements Ginterface<E>
    

    If implementing class of the generic interface is not a generic class that will result in compile time error because the type parameter E is not known in that case.

    public class GClassImpl implements Ginterface<E>
    
    This will result in compile-time error.
  2. Of course providing a proper data type with the interface while implementing it is OK, in that case normal class can be used.
    public class GClassImpl implements GInterface<String> {
        String str;
        @Override
        public void setValue(String e) {
            this.str = e;
            
        }
    
        @Override
        public String getValue() {
            return str;
        }
    
    }
    
    Here you have used String as a type parameter with the interface so it is OK to use a normal class but type will become String in the class then.
  3. A generic class implementing a generic interface can have other parameters too. This is perfectly ok -
    public class GClassImpl<E, K> implements Ginterface<E>
    

Generic method

Any method in the generic class can use the type parameter of the class so that way methods in a generic class are generic.
Generic methods can add more parameters of their own.
There can be generic methods even in a non-generic class.

When you are writing a generic method after the access modifier you need to declare the type parameters then the return type. As example if you are writing a public method that uses one type parameter and doesn’t return anything then it will be written as -
 
public <T> void MethodName(T obj1){

} 

Generic method example

If you want to write a generic method that can be used to display elements of an array of any type.

 
public class GenericMethodDemo {  
    public static void main(String[] args) {
        GenericMethodDemo gm = new GenericMethodDemo();
        Integer[] intArray = {1, 2, 3, 4, 5, 6, 7};
        Double[] doubleArray = {3.4, 5.6, 7.8, 1.2, 4.5};
        // integer array
        gm.printElements(intArray);
        // double array
        gm.printElements(doubleArray);
    }
    
    public <T> void printElements(T[] arr){
        // Displaying elements
        for(int i = 0; i < arr.length; i++){
            System.out.print(" " + arr[i]);
        }
        System.out.println();
    }
}

Output

1 2 3 4 5 6 7
3.4 5.6 7.8 1.2 4.5

When you are calling a generic method there is no need to specify type (though you can do it if you want). Type will be inferred automatically based on the type of the method arguments. So calling your method using this form gm.<Integer>printElements(intArray); for Integer argument is also ok but it is not needed at all.

That's all for this topic Generic class, interface and generic method. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Generics in Java
  2. Wildcard in Java Generics
  3. Bounded type parameter in Java generics
  4. Type erasure in Java Generics
  5. Lambda expressions in Java 8

You may also like -

>>>Go to Java advance topics page

Friday, 10 February 2017

Matrix Multiplication Java Program

When you multiply two matrices with each other, you actually do a “dot product” of rows and columns.

As example if you are multipying a 3X3 matrix with a 3X2 matrix -

Matrix multiplication

The result you get can be explained as follows -

s11 = r11Xp11 + r12Xp21 + r13Xp31
s12 = r11Xp12 + r12Xp22 + r13Xp32
s21 = r21Xp11 + r22Xp21 + r23Xp31
s22 = r21Xp12 + r22Xp22 + r23Xp32
s31 = r31Xp11 + r32Xp21 + r33Xp31
s32 = r31Xp12 + r32Xp22 + r33Xp32

When you are writing a Java program to multiply two matrices -

You need an outer loop that will run as many times as there are rows in the first matrix.
Then you’ll have a second loop that will run as many times as the number of columns in the second matrix.
Then you’ll have a third loop that will run as many times as there are columns in the first matrix.

Also remember these points when multiplying one matrix with another -

  1. The number of columns of the first matrix is equal to the number of rows of the second matrix.
  2. The resultant matrix will have the same number of rows as in the first matrix and same number of columns as in the second matrix.

Matrix multiplication Java program

 
import java.util.Scanner;

public class MatixMultiplication {

    public static void main(String[] args) {
        int rowM1, colM1;
        int rowM2, colM2;
        
        Scanner in = new Scanner(System.in);
        System.out.print("Enter Number of Rows and Columns of First Matrix : ");
        rowM1 = in.nextInt();
        colM1 = in.nextInt();
        
        System.out.print("Enter elements of First Matrix : ");
        int M1[][] = new int[rowM1][colM1];
        for(int i = 0; i < rowM1; i++){
            for(int j = 0; j < colM1; j++){
                M1[i][j] = in.nextInt();
            }
        }
        System.out.println("First Matrix : " );
        for(int i = 0; i < rowM1; i++){
            for(int j = 0; j < colM1; j++){
                System.out.print(" " +M1[i][j]+"\t");
            }
            System.out.println();
        }
        
        System.out.print("Enter Number of Rows and Columns of Second Matrix : ");
        rowM2 = in.nextInt();
        colM2 = in.nextInt();
        if(colM1 != rowM2){
            throw new IllegalArgumentException("The number of columns of the first matrix should equal the number of rows of the second matrix.");
        }
        System.out.print("Enter elements of Second Matrix : ");
        int M2[][] = new int[rowM2][colM2];
        for(int i = 0; i < rowM2; i++){
            for(int j = 0; j < colM2; j++){
                M2[i][j] = in.nextInt();
            }
        }
        System.out.println("Second Matrix : " );
        for(int i = 0; i < rowM2; i++){
            for(int j = 0; j < colM2; j++){
                System.out.print(" " +M2[i][j] + "\t");
            }
            System.out.println();
        }
        //same number of rows as in the first matrix and 
        //same number of columns as in the second matrix
        int resMatrix[][] = new int[rowM1][colM2];
        int sum = 0;
        int row = 0;
        for(int i = 0; i < rowM1; i++){
            for(int j = 0; j < colM2; j++){
                sum = 0;
                for(int k = 0; k < colM1; k++){
                    sum = sum + M1[i][k] * M2[k][j];
                }
                resMatrix[i][j] = sum;
            }
        }
        
        System.out.println("Result Matrix : " );
        for(int i = 0; i < resMatrix.length; i++){
            for(int j = 0; j < colM2; j++){
                System.out.print(" " +resMatrix[i][j]+"\t");
            }
            System.out.println();
        }
    }
}

Output

Enter Number of Rows and Columns of First Matrix : 2
3
Enter elements of First Matrix : 1
2
3
4
5
6
First Matrix : 
 1  2  3 
 4  5  6 
Enter Number of Rows and Columns of Second Matrix : 3
2
Enter elements of Second Matrix : 7
8
9
10
11
12
Second Matrix : 
 7  8 
 9  10 
 11  12 
Result Matrix : 
 58  64 
 139  154 
 

That's all for this topic Matrix Multiplication Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Array in Java
  2. Lambda Expression Comparator example
  3. How to run javap programmatically from Java Program
  4. How to display pyramid patterns in Java - Part1
  5. Print odd-even numbers using threads and wait-notify

You may also like -

>>>Go to Java Programs page

Wednesday, 1 February 2017

Array in Java

An array in Java is a container object that holds values of a single type. These elements are stored in a contiguous memory location and referred by a common name. Note that this common name (variable) is an object which holds reference to the array.

Some important points about array

  1. Array holds a fixed number of elements.
  2. Length of an array is specified when an array is created. Once length of an array is specified it remains fixed.
  3. Array in Java is index based and the index starts from 0. So the first element is stored in the array at index 0.

Pictorial representation of an Array

Let’s say you have an array numArr of length 10 and numArr is of type int.

array in java
Array in Java

Types of array

Array can be of single dimension (one dimensional) or multi dimensional. So there are two types of arrays -

  • Single dimensional – It is essentially a sequence of elements of similar types.
  • Multi dimensional – It is essentially an array of arrays, in one dimensional array there is one row with multiple columns where as in multi-dimensional array there are multiple rows with multiple columns.

Array declaration and initialization

To declare an array you have to provide array’s type and array’s name. An array’s type is written as type[], where type is the data type of the contained elements; the brackets are special symbols indicating that this variable holds an array.

As example; if you want to declare an array, numArr of type int, it can be done as -

 int[] numArr;

here int denotes the type and numArr is the name of the array.

You can also place the brackets after the array name so this is also right -

 int numArr[];

But Java doc says “However, convention discourages this form; the brackets identify the array type and should appear with the type designation.” So let’s stick to type[] arrayName form.

Note that declaration does not actually create an array; it simply tells the compiler that this variable will hold an array of the specified type.

In order to create an array you can use new operator which is one of the way to create an array. It’s general form (in case of 1-D array) is -

arrayName = new type[size]

Here,

  • type – Specifies the type of the data.
  • size – Specifies the number of elements in an array.
  • arrayName – array variable that holds reference to the created array.

When the above array is created using new operator, memory for 10 int elements is allocated and the array variable numArr holds the reference to that memory.

Of course you can combine these two steps into one to make it more compact and readable -

int[] numArr = new int[10];

One important thing to note here is that the array created by using new operator will automatically initialize its elements to the default value, which is -

  1. 0 for numeric types.
  2. false for boolean.
  3. null for an array of class objects.

As example – If you have created an array which holds element of type int and print all the values just after creating it you will get all values as zeroes.

public class ArrayDemo {
    public static void main(String[] args) {
        int[] numArr = new int[10];
        for(int i = 0; i < numArr.length; i++){
            System.out.println("Value at index " + i + " is " + numArr[i]);
        }
    }
}

Output

Value at index 0 is 0
Value at index 1 is 0
Value at index 2 is 0
Value at index 3 is 0
Value at index 4 is 0
Value at index 5 is 0
Value at index 6 is 0
Value at index 7 is 0
Value at index 8 is 0
Value at index 9 is 0

Here few things to note are -

  1. As soon as array is created using new operator memory is allocated for all the elements (in this case 10).
  2. Since default for numeric type is zero so all the elements of the array have value zero.
  3. Array in Java is zero index based, which means, for array of length 10 start index is 0 and last index is 9.
  4. If you don't create an array and just declare it, then the compiler prints an error like the following, and compilation fails: Variable numArr may not have been initialized

Another way to create and initialize an array is to provide values in between the braces when the array is declared.

int[] numArr = {1, 2, 3, 4, 5};

Here the length of the array is determined by the number of values provided between braces and separated by commas.

Java run-time check

Java has strict run-time check for any out of range index. As example in numArr example used above if the length of the array is 10 then the index range for the array is 0-9. Any attempt to use index out of this range, either negative number or positive number, will result in a run-time exception ArrayIndexOutOfBoundsException.

Array of objects

You can also create an array of objects. As already mentioned above, at the time of creation of an array of objects, all the elements will be initialized as null for an array of class objects. What that means for each element of an array of object you will have to provide the object reference too.

As example -

Employee[] empArr = new Employee[10]; // array creation
Employee emp = new Employee();
empArr[0] = emp; // object reference

Multi-dimensional arrays

You can also declare an array of arrays (also known as a multidimensional array) by using two or more sets of brackets. As example, if you want to create a 2-D array of String called names -

String[][] names. 

Each element, therefore, must be accessed by a corresponding number of index values.

Example

public class ArrayDemo {

    public static void main(String[] args) {
        int[][] numArr = new int[3][3];
        // providing values for array
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                numArr[i][j] = i + j;
            }
        }
        // Displaying array elements
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                System.out.print(" " + numArr[i][j]);
            }
            System.out.println();
        }
        
    }

}

Output

 0 1 2
 1 2 3
 2 3 4
 

That's all for this topic Array in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Package in Java
  2. Access modifiers in Java
  3. Finding duplicate elements in an array - Java Program
  4. Generics in Java
  5. String in Java
  6. Matrix Multiplication Java Program

You may also like -

>>>Go to Java Basics page