Search Logic Blocks

Monday, March 29, 2021

Java: Nested Interface in an Interface

We had talked about interfaces and their fully / partial implementations. We also talked about Nested Interface in a Class (declaring an interface in a class) and Nested Class in an Interface (declaring a class in am interface). Let's declare an interface inside an interface (Nested Interface in an Interface) -

The inner interface class instance can be used three ways -
  • instance methods can be called directly
  • instance is passed to interface variable by reference and then methods are called through that variable
  • instance is passed to the outer interface method which takes a parameter interface variable

All three examples are shown in the code given below -
// Outer Interface
public interface OuterInterface {
public void display();
public void showInner(InnerInterface i);

// Inner Interface
public interface InnerInterface {
public void display();
}
}
// Implementation of Outer Interface
public class OuterInterfaceClass implements OuterInterface {
public void display() {
System.out.println("Display method from OuterInterfaceClass");
}

public void showInner(InnerInterface i) {
System.out.println("Show method from OuterInterfaceClass");
i.display();
}
}
// Implementation of Inner Interface
public class InnerInterfaceClass implements OuterInterface.InnerInterface {
public void display() {
System.out.println("Display method from InnerInterfaceClass");
}
}
// Demo class showing accessing inner interface in all three ways
public class Test {
public static void main (String args[]) {
// Creates a an object of class implementing OuterInterface
OuterInterfaceClass oic = new OuterInterfaceClass();
oic.display();
System.
out.println("___________________________________________________");

// Creates a an object of class implementing InnerInterface
InnerInterfaceClass iic = new InnerInterfaceClass();
iic.display();
System.
out.println("___________________________________________________");

// Creates a a variable of inner interface and assign the class variable By Reference
OuterInterface.InnerInterface oiii;
oiii = iic;
oiii.display();
System.
out.println("___________________________________________________");
// Calls the outer interface method which accesses inner interface
oic.showInner(iic);
}
}
Let's explore all three options -

InnerInterfaceClass is created by implementing inner interface InnerInterface directly.
// Implementation of Inner Interface
public class InnerInterfaceClass implements OuterInterface.InnerInterface {
public void display() {
System.out.println("Display method from InnerInterfaceClass");
}
}
1. instance methods can be called directly -

Create an instance of class implementing inner interface and then call interface methods:
// Creates a an object of class implementing InnerInterface
InnerInterfaceClass iic = new InnerInterfaceClass();
iic.display();
2. instance is passed to an interface variable by reference and then methods are called through that variable -

Declare a variable of inner interface and assign the inner class variable (Using class reference), call the method through interface variable:
// Creates a a variable of inner interface and assign the class variable By Reference
OuterInterface.InnerInterface oiii;
oiii = iic;
oiii.display();
3. instance is passed to the outer interface method which takes a parameter interface variable -

Creates an instance of class implementing outer interface and then call interface methods passing inner interface as a parameter:
// Creates a an object of class implementing OuterInterface
OuterInterfaceClass oic = new OuterInterfaceClass();
// Calls the outer interface method which accesses inner interface
oic.showInner(iic);
Here is the output of the above code -

Display method from OuterInterfaceClass
___________________________________________________
Display method from InnerInterfaceClass
___________________________________________________
Display method from InnerInterfaceClass
___________________________________________________
Show method from OuterInterfaceClass
Display method from InnerInterfaceClass

Code can be accessed on Github Link.

Tuesday, March 23, 2021

Java: Nested Class in an Interface

We already discussed about interfaces, partial interface and nested interface in a class. In this post, we will learn, how we can declare a class inside an interface. The outer interface can access the inner class in its own methods. Suppose there is an interface named as Magazine, and it has inner class named as Article. A class MagazineDemo implements the interface Magazine and creates an instance of inner class Article -

// Interface Magazine - prototype of a magazine
public interface Magazine {

// Prints the article
void postArticle(Article a);

// Gets the number of characters in an Article
int getArticleLen(Article a);

// Gets the number of words in an Article
int getArticleWords(Article a);

// Class Article in the interface Magazine
class Article {
String title;
String author;
String content;

// Article class constructor
Article(String title, String author, String content) {
this.title = title;
this.author = author;
this.content = content;
}
}
}
The interface Magazine is implemented by a demo class MagazineDemo. The main() method creates an instance of inner class Article and calls the implemented methods to print the Article details -
import java.util.Scanner;

// Implements the interface Magazine
public class MagazineDemo implements Magazine {
// Prints the Article
public void postArticle(Article a) {
System.out.println("title: " + a.title);
System.out.println("author: " + a.author);
System.out.println("content: " + a.content);
}

// Implements the interface method - getArticleLen(Article a)
public int getArticleLen(Article a) {
int len = a.content.length();
System.out.println("Article has " + len + " characters.");
return len;
}

// Implements the interface method - getArticleWords(Article a)
public int getArticleWords(Article a) {
String words[] = a.content.split(" ");
int wordCount = words.length;
System.out.println("Article has " + wordCount + " words.");
return wordCount;
}

public static void main(String args[]) {
System.out.print("Enter title:");
Scanner sc = new Scanner(System.in);
String title, author, content;
title = sc.nextLine();

System.out.print("Enter author name:");
author = sc.nextLine();

System.out.print("Enter content:");
content = sc.nextLine();
System.out.println("----------------");

MagazineDemo d = new MagazineDemo();
Article a = new Article(title, author, content);
d.getArticleLen(a);
d.getArticleWords(a);
d.postArticle(a);
}
}
Here is the example of output -

Enter title:Implementing Interfaces
Enter author name:Herbert Schildt
Enter content:Once an interface has been defined, one or more classes can implement that interface.
----------------
Article has 85 characters.
Article has 14 words.
title: Implementing Interfaces
author: Herbert Schildt
content: Once an interface has been defined, one or more classes can implement that interface.

The code can be found at Github Link.

Tuesday, March 16, 2021

Java: Linear Data Structures

What are the Data Structures -

Data structure is a an organization system of data (same data type) collection. It is a system to store the data (like arrays) in the memory on the computer and the method to access and manipulate the data efficiently. There are two types of data structures -

Linear Data Structures -

In Linear data structures, data is stored sequentially and linked to previous and next elements (data). They are linked on the single level and connected in such a way that they are traversed sequentially. The data elements can be traverse in the single run using the iterations (loops). The examples of Linear Data Structures are - Arrays, Queue, Stack and LinkedList. Classes and interfaces - Arrays, Stack, Queue and LinkedList, can be accessed through java.util package. We already discussed briefly about data structures Arrays and Stack in our earlier posts - Arrays and How to create a class stack.

Stack -
  • Stack is a collection of same data type elements / class objects.
  • New data element is pushed (added) on top of the stack, and only the data element on the top is popped out (retrieved).
  • Always the data element last pushed in the stack, will be popped out - LIFO (Last In First Out).
  • Stack data elements are stored in contiguous memory locations.
  • Push - pushes (appends) the new data element on top of the stack and points to the last element of the stack.
  • Pop - pops (gets) the top element from the stack, uses it and the second last data element comes on top (points to the second last data element). The last retrieved element has no connection with the stack.
  • Empty stack - When the last data element in the stack is popped up, stack is empty - there are no data elements left in the stack.
  • Full stack - When the stack has the data elements equals to the stack size, no other element can be pushed in, the stack is full.
  • Java has its own generic (For all data types) class as Stack and it has methods - push(), pop(), peek(), empty(), search()
  • Example of how stack works - I have created a custom class Stack of integers in the post - How to create a class Stack.


Queue -
  • Queue is a collection of same data type elements / class objects.
  • New data element is put (added) in start of the queue, but only the data element in the end is got out (retrieved).
  • Always the data element first put in the queue, will be retrieved - FIFO (First In First Out).
  • Queue data elements are stored in contiguous memory locations.
  • Put - puts (appends) the new data element on start of the queue and points to the first element of the queue.
  • Get - gets (retrieves) the first element from the queue, uses it and the second data element becomes the first data element (points to the second data element). The last retrieved element has no connection with the queue.
  • Empty queue - When the last data element in the queue is got out, queue is empty - there are no data elements left in the queue.
  • Full queue - When the queue has the data elements equals to the queue size, no other element can be put in, the queue is full.
  • Java has its own generic (For all data types) interface as Queue and to implement this interface, the programmer has to override the methods - add()offer()remove()poll()element() and peek().


Linked List -
  • Linked List is a collection of same data type elements / class objects.
  • New data element can be added at start, end or middle of the Linked List.
  • LinkedList data elements are not stored in contiguous memory locations. Each data element is like a container which has two parts - data and address to the next data element. The last data element has address as null
  • Any data element can be accessed randomly by using index no, and can be referred any time till it is not removed explicitly.
  • Java has its own generic (For all data types) class as LinkedList and it has several methods to add, remove or manipulate data elements in the list - getFirst()getLast()removeFirst()removeLast()addFirst(), addLast(), contains(), size(), add(), remove(), addAll(), clear(), get(), set(), indexOf(), listIterator() and toArray() etc.



Non-Linear Data Structures -

In Non-Linear Data Structures, data is stored in multi-level hierarchy, and are complex to implement. The data elements can not be accessed sequentially and can't be traversed in the single run by using the iterations (loops). The examples of Non-Linear Data Structures are - Trees and Graphs.

Note: I will cover Non-Linear Data Structures in a separate post.

Tuesday, March 9, 2021

Java: Multiply Binary Numbers

We already know what are the binary numbers through earlier posts - What are the binary numbers, conversion between the binary numbers and decimal numbers and addition of the binary numbers. Let's discuss how to multiply binary numbers.

How to multiply bits (0 and 1)
Bits are multiplied in the similar way as we multiply the decimal numbers -

0 0 1
x 0 x 1 x 1
0 0 1

And -

1 1 1 1
x 0 x 1
0 0 1 1

When we do binary multiplication with 2 or more bits, the approach will be the same like as normal decimal multiplication, just we do binary addition after multiplying by each of the bits - 

1 1 1 1 = 15
x 1 1 = 3
1 1 1 1
+ 1 1 1 1 0 x 10
1 0 1 1 0 1 = 45 Binary Addition

Here is another example -

1 0 1 1 = 11
x 1 0 1 = 5
1 0 1 1
0 0 0 0 0 x 10
+ 1 0 1 1 0 0 x 100
1 1 0 1 1 1 = 55 Binary Addition

We already have programs to convert binary numbers to decimal and decimal to binary numbers, and to add two binary numbers. Using same methods, we will write our new class MultipleBinaryNumbers. This class uses the same methods from our previous classes - binaryToDecimal(), calcPower() and addBinaryNumbers(). A new method is added - multiplyBinaryNumbers()
// Multiplies Two Binary Numbers
public static Long multiplyBinaryNumbers(Long binary1, Long binary2) {
Long binaryVal = 0L;

int rem;

int pos = 1;
Long tempBinaryVal = 0L;

// Multiplication is done bit by bit by binary2
while(binary2 != 0) {
rem = (int)(binary2 % 10);
tempBinaryVal = binary1 * rem;
for(int i = 1; i < pos; i++)
tempBinaryVal = tempBinaryVal * 10;

binaryVal = addBinaryNumbers(binaryVal, tempBinaryVal);

pos++;
binary2 = binary2 / 10;
}

int totVal = binaryToDecimal(binaryVal);
System.out.println();
System.out.println("Multiplication of two binary numbers => " + binaryVal + " : " + totVal);
return binaryVal;
}
The method takes two binary numbers as the parameters - binary1 and binary2
  • Set the result binary number as 0
  • Set the position as 1 for the rightmost bit of the second binary number
  • Set the temporary binary value as 0
  • While loop is run till the leftmost bit of the second binary number -
  1. Gets rightmost bit using mod (%) operator
  2. Multiply first binary number by bit got using step 1 and put result in the temporary variable
  3. If position of the bit is greater than 1 
    • Multiply temporary number by 10 to the power of position of the bit
  4. Assign result binary value to the temporary binary value + last result
  5. Position is increased
  6. Second binary number is changed by removing the rightmost bit
Here is the whole program:
import java.util.Scanner;

public class MultiplyBinaryNumbers {
public static void main(String args[]) {
System.out.println("Enter two binary values");
Scanner sc = new Scanner(System.in);
Long binary1 = sc.nextLong();
Long binary2 = sc.nextLong();

int decVal1 = binaryToDecimal(binary1);
int decVal2 = binaryToDecimal(binary2);

System.out.println("Binary number 1 => " + binary1 + " : " + decVal1);
System.out.println("Binary number 2 => " + binary2 + " : " + decVal2);

multiplyBinaryNumbers(binary1, binary2);
}

// Converts Binary Number To Decimal Number
public static int binaryToDecimal(Long binaryVal) {
int decVal = 0;
int rem, pow = 0;

while(binaryVal != 0) {
rem = (int)(binaryVal % 10);
decVal = decVal + rem * calcPower(2, pow);
binaryVal = binaryVal / 10;
pow++;
}
return decVal;
}

// Calculate to the power
public static int calcPower(int no1, int no2) {
int powVal = 1;
for(int i = 0; i < no2; i++) {
powVal = powVal * no1;
}
return powVal;
}

// Adds Two Binary Numbers
public static Long addBinaryNumbers(Long binary1, Long binary2) {
Long binaryVal = 0L;

int sum = 0;
int rem1, rem2, remainder = 0, i = 0, pow = 0;

// Addition is done bit by bit
while(binary1 != 0 || binary2 != 0) {
// rem1 is next bit of binary1 and rem2 is next bit of binary2
rem1 = (int)(binary1 % 10);
rem2 = (int)(binary2 % 10);

// remaining bits of binary numbers
binary1 = binary1 / 10;
binary2 = binary2 / 10;

// sum of the bits + carryover if any
sum = (rem1 + rem2 + remainder) % 2; // remainder is carry over
remainder = (rem1 + rem2 + remainder) / 2;
binaryVal = binaryVal + sum * calcPower(10, pow);
pow++;
}
if(remainder != 0) {
// If last bit addition has carryover, add it too
binaryVal = binaryVal + calcPower(10, pow);
}

int totVal = binaryToDecimal(binaryVal);

return binaryVal;
}

// Multiplies Two Binary Numbers
public static Long multiplyBinaryNumbers(Long binary1, Long binary2) {
Long binaryVal = 0L;

int rem;

int pos = 1;
Long tempBinaryVal = 0L;

// Multiplication is done bit by bit by binary2
while(binary2 != 0) {
rem = (int)(binary2 % 10);
tempBinaryVal = binary1 * rem;
for(int i = 1; i < pos; i++)
tempBinaryVal = tempBinaryVal * 10;

binaryVal = addBinaryNumbers(binaryVal, tempBinaryVal);

pos++;
binary2 = binary2 / 10;
}

int totVal = binaryToDecimal(binaryVal);
System.out.println();
System.out.println("Multiplication of two binary numbers => " + binaryVal + " : " + totVal);
return binaryVal;
}
}
And Here is the output:

Enter two binary values
1011
101
Binary number 1 => 1011 : 11
Binary number 2 => 101 : 5

Multiplication of two binary numbers => 110111 : 55

The code can be accessed here: Github Link