Tuesday, April 30, 2024

Pre-defined Functional Interfaces in Java

We saw in the post Functional Interfaces in Java how you can create your own functional interface and also annotate it using @FunctionalInterface Annotation. Though it is not always required that you have to create your own functional interface for each scenario, Java has introduced a new package java.util.function that defines many general purpose pre-defined functional interfaces used by many Java libraries like Collection framework, Java Stream API and used by user code as well. In this post we’ll go through these built-in functional interfaces in Java so you have a good idea which functional interface to use in which context while using with Lambda expressions in Java.


Pre-defined functional interfaces categorization

Functional interfaces defined in java.util.function package can be categorized into five types-

  1. Consumer- Consumes the passed argument and no value is returned.
  2. Supplier- Takes no argument and supplies a result.
  3. Function- Takes argument and returns a result.
  4. Predicate- Takes argument and returns a boolean result (true or false).
  5. Operators- Functional interfaces categorized under Operator are specialized Function where the passed argument and result are of the same type.

Consumer functional interface

Consumer<T> represents a function that accepts a single input argument and returns no result. Consumer functional interface definition is as given below consisting of an abstract method accept() and a default method andThen()-

@FunctionalInterface
public interface Consumer<T> {
  void accept(T t);
  default Consumer<T> andThen(Consumer<? super T> after) {
    Objects.requireNonNull(after);
    return (T t) -> { accept(t); after.accept(t); };
  }
}

Following pre-defined Consumer functional interfaces are categorized as Consumer as all of these interfaces have the same behavior of consuming the passed value(s) and returning no result. You can use any of these based on number of arguments or data type.

  • BiConsumer<T,U>- Represents an operation that accepts two input arguments and returns no result.
  • DoubleConsumer- Represents an operation that accepts a single double-valued argument and returns no result.
  • IntConsumer- Represents an operation that accepts a single int-valued argument and returns no result.
  • LongConsumer- Represents an operation that accepts a single long-valued argument and returns no result.
  • ObjDoubleConsumer<T>- Represents an operation that accepts an object-valued and a double-valued argument, and returns no result.
  • ObjIntConsumer<T>- Represents an operation that accepts an object-valued and a int-valued argument, and returns no result.
  • ObjLongConsumer<T>- Represents an operation that accepts an object-valued and a long-valued argument, and returns no result.

Consumer functional interface Java example

In the example elements of List are displayed by using an implementation of Consumer functional interface.

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample {
  public static void main(String[] args) {
    Consumer<String> consumer = s -> System.out.println(s);
    List<String> alphaList = Arrays.asList("A", "B", "C", "D");
    for(String str : alphaList) {
      // functional interface accept() method called
      consumer.accept(str);
    }
  }
}

Output

A
B
C
D

Supplier functional interface

Supplier<T> represents a function that doesn't take argument and supplies a result. Supplier functional interface definition is as given below consisting of an abstract method get()-

@FunctionalInterface
public interface Supplier<T> {
  T get();
}

Following pre-defined Supplier functional interfaces are categorized as Supplier as all of these interfaces have the same behavior of supplying a result.

  • BooleanSupplier- Represents a supplier of boolean-valued results.
  • DoubleSupplier- Represents a supplier of double-valued results.
  • IntSupplier- Represents a supplier of int-valued results.
  • LongSupplier- Represents a supplier of long-valued results.

Supplier functional interface Java example

In the example Supplier functional interface is implemented as a lambda expression to supply current date and time.

import java.time.LocalDateTime;
import java.util.function.Supplier;

public class SupplierExample {
  public static void main(String[] args) {
    Supplier<LocalDateTime> currDateTime = () -> LocalDateTime.now();
    System.out.println(currDateTime.get());
  }
}

Function functional interface

Function<T,R> represents a function that accepts one argument and produces a result. Function functional interface definition is as given below consisting of an abstract method apply(), two default methods compose(), andThen() and a static method identity().

@FunctionalInterface
public interface Function<T, R> {

  R apply(T t);

  default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
  }

  default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
  }
  static <T> Function<T, T> identity() {
    return t -> t;
  }
}

Following pre-defined Function functional interfaces are categorized as Function as all of these interfaces have the same behavior of accepting argument(s) and producing a result.

  • BiFunction<T,U,R>- Represents a function that accepts two arguments and produces a result.
  • DoubleFunction<R>- Represents a function that accepts a double-valued argument and produces a result.
  • DoubleToIntFunction- Represents a function that accepts a double-valued argument and produces an int-valued result.
  • DoubleToLongFunction- Represents a function that accepts a double-valued argument and produces a long-valued result.
  • IntFunction<R>- Represents a function that accepts an int-valued argument and produces a result.
  • IntToDoubleFunction- Represents a function that accepts an int-valued argument and produces a double-valued result.
  • IntToLongFunction- Represents a function that accepts an int-valued argument and produces a long-valued result.
  • LongFunction<R>- Represents a function that accepts a long-valued argument and produces a result.
  • LongToDoubleFunction- Represents a function that accepts a long-valued argument and produces a double-valued result.
  • LongToIntFunction- Represents a function that accepts a long-valued argument and produces an int-valued result.
  • ToDoubleBiFunction<T,U>- Represents a function that accepts two arguments and produces a double-valued result.
  • ToDoubleFunction<T>- Represents a function that produces a double-valued result.
  • ToIntBiFunction<T,U>- Represents a function that accepts two arguments and produces an int-valued result.
  • ToIntFunction<T>- Represents a function that produces an int-valued result.
  • ToLongBiFunction<T,U>- Represents a function that accepts two arguments and produces a long-valued result.
  • ToLongFunction<T>- Represents a function that produces a long-valued result.

Function functional interface Java example

In the example a Function interface is implemented to return the length of the passed String.

import java.util.function.Function;

public class FunctionExample {
  public static void main(String[] args) {
    Function<String, Integer> function = (s) -> s.length();
    System.out.println("Length of String- " + function.apply("Interface"));
  }
}

Output

Length of String- 9

Predicate functional interface

Predicate<T> represents a function that accepts one argument and produces a boolean result. Abstract method in the Predicate functional interface is boolean test(T t).

Following pre-defined Predicate functional interfaces are categorized as Predicate as all of these interfaces have the same behavior of accepting argument(s) and producing a boolean result.

  • BiPredicate<T,U>- Represents a predicate (boolean-valued function) of two arguments.
  • DoublePredicate- Represents a predicate (boolean-valued function) of one double-valued argument.
  • IntPredicate- Represents a predicate (boolean-valued function) of one int-valued argument.
  • LongPredicate- Represents a predicate (boolean-valued function) of one long-valued argument.

Predicate functional interface Java Example

In the example a number is passed and true is returned if number is even otherwise odd is retuned.

import java.util.function.Predicate;

public class PredicateExample {
  public static void main(String[] args) {
    Predicate<Integer> predicate = (n) -> n%2 == 0;
    boolean val = predicate.test(6);
    System.out.println("Is Even- " + val);    
    System.out.println("Is Even- " + predicate.test(11));
  }
}

Output

Is Even- true
Is Even- false

Operator functional interfaces

Operator functional interfaces are specialized Function interfaces that always return the value of same type as the passed arguments. Operator functional interfaces extend their Function interface counterpart like UnaryOperator extends Function and BinaryOperator extends BiFunction.

Following pre-defined Operator functional interfaces are there that can be used in place of Function interfaces if returned value is same as the type of the passed argument(s).

  • BinaryOperator<T>- Represents an operation upon two operands of the same type, producing a result of the same type as the operands.
  • DoubleBinaryOperator- Represents an operation upon two double-valued operands and producing a double-valued result.
  • DoubleUnaryOperator- Represents an operation on a single double-valued operand that produces a double-valued result.
  • IntBinaryOperator- Represents an operation upon two int-valued operands and producing an int-valued result.
  • IntUnaryOperator- Represents an operation on a single int-valued operand that produces an int-valued result.
  • LongBinaryOperator- Represents an operation upon two long-valued operands and producing a long-valued result.
  • LongUnaryOperator- Represents an operation on a single long-valued operand that produces a long-valued result.
  • UnaryOperator<T>- Represents an operation on a single operand that produces a result of the same type as its operand.

UnaryOperator functional interface Java example

In the example UnaryOperator is implemented to return the square of the passed integer.

import java.util.function.UnaryOperator;

public class UnaryOperatorExample {
  public static void main(String[] args) {
    UnaryOperator<Integer> unaryOperator = (n) -> n*n;
    System.out.println("4 squared is- " + unaryOperator.apply(4));
    System.out.println("7 squared is- " + unaryOperator.apply(7));
  }
}

Output

4 squared is- 16
7 squared is- 49

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


Related Topics

  1. Exception Handling in Java Lambda Expressions
  2. Method Reference in Java
  3. How to Fix The Target Type of This Expression Must be a Functional Interface Error
  4. Java Stream API Tutorial
  5. Java Lambda Expressions Interview Questions And Answers

You may also like-

  1. Java Stream flatMap() Method
  2. Java Lambda Expression Callable Example
  3. Invoke Method at Runtime Using Java Reflection API
  4. LinkedHashMap in Java With Examples
  5. java.lang.ClassCastException - Resolving ClassCastException in Java
  6. Java String Search Using indexOf(), lastIndexOf() And contains() Methods
  7. BeanFactoryAware Interface in Spring Framework
  8. Angular Two-Way Data Binding With Examples

Monday, April 29, 2024

Checkbox in Angular Form Example

In this post we’ll see how to use check boxes in Angular form. We’ll see examples of adding check boxes to both template-driven and reactive form in Angular.

Checkbox in Reactive form Angular example

In this Angular Reactive form example we’ll have a form with two input fields for name and date (with a date picker for picking date) and a group of check boxes to select favorite exercises.

Friday, April 26, 2024

Printing Numbers in Sequence Using Threads Java Program

This post shows how you can print numbers in sequence using three threads in Java. If there are three threads thread1, thread2 and thread3 then numbers should be printed alternatively by these threads like this.

thread1 - 1
thread2 - 2
thread3 – 3
thread1 - 4
thread2 - 5
thread3 – 6
...
...
...

Print numbers in sequence using three threads in Java

While printing numbers in sequence using threads trick is to use modulo division to check which thread can print the number and which threads are to be blocked waiting.

Each thread is assigned one of the numbers 0, 1 and 2. Each number is divided by 3 (number of threads), remainder will be any one of these numbers 0, 1 or 2. That is what is checked; if (remainder = number assigned to thread) only then thread can work otherwise it goes into waiting state.

class SharedPrinter{
  int number = 1;
  int numOfThreads;
  int numInSequence;
  SharedPrinter(int numInSequence, int numOfThreads){
    this.numInSequence = numInSequence;
    this.numOfThreads = numOfThreads;
  }
  public void printNum(int result){
    synchronized(this) {
      while (number < numInSequence - 1) {
        while(number % numOfThreads != result){
          try {
            this.wait();
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
        }
        System.out.println(Thread.currentThread().getName() + " - " + number++);
        this.notifyAll();
      }
    }
  }
}
class SeqRunnable implements Runnable{
  SharedPrinter sp;
  int result;
  static Object sharedObj = new Object();
  SeqRunnable(SharedPrinter sp, int result){
    this.sp = sp;
    this.result = result;
  }
  @Override
  public void run() {
    sp.printNum(result);
  }
}
public class SeqNumber {
  final static int NUMBERS_IN_SEQUENCE = 10;
  final static int NUMBER_OF_THREADS = 3;
  public static void main(String[] args) {
    // Shared object
    SharedPrinter sp = new SharedPrinter(NUMBERS_IN_SEQUENCE, NUMBER_OF_THREADS);
    // Creating 3 threads
    Thread t1 = new Thread(new SeqRunnable(sp, 1), "Thread1");
    Thread t2 = new Thread(new SeqRunnable(sp, 2), "Thread2");
    Thread t3 = new Thread(new SeqRunnable(sp, 0), "Thread3");

    t1.start();
    t2.start();
    t3.start();
  }
}

Output

Thread1 - 1
Thread2 - 2
Thread3 - 3
Thread1 - 4
Thread2 - 5
Thread3 - 6
Thread1 - 7
Thread2 - 8
Thread3 - 9
Thread1 - 10

That's all for this topic Printing Numbers in Sequence Using Threads Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. How to Run Threads in Sequence in Java
  2. Print Odd-Even Numbers Using Threads And wait-notify Java Program
  3. Producer-Consumer Java Program Using ArrayBlockingQueue
  4. How to Create Deadlock in Java
  5. Race condition in Java multi-threading

You may also like-

  1. Converting String to Enum Type in Java
  2. Connection Pooling Using C3P0 in Java
  3. Java Program to Find First Non-Repeated Character in a Given String
  4. How to Convert String to Date in Java
  5. Java Multithreading Interview Questions And Answers
  6. How and Why to Synchronize ArrayList in Java
  7. BigDecimal in Java With Examples
  8. Introduction to Hadoop Framework

Thursday, April 25, 2024

FormGroup in Angular With Examples

Using FormGroup in Angular forms you can group FormControl instances and track the value and validity state of those instances as a group rather than for each individual FormControl instance. In this post we'll see example of using FormGroup with Angular template-driven form as well as with Reactive form.


Wednesday, April 24, 2024

How to Setup a Node.js Project

In this article we'll see how to set up a Node.js project with a package.json file so that you can easily install other dependencies using NPM. This also shows how you'll use NodeJS' module pattern to create projects which is a collection of many files and packages.

Prerequisite to creating a project is that Node.js is installed in your system (which also install NPM) and you have an IDE like Visual Studio Code.

Check this post How to Install Node.js and NPM in Windows to see how to install Node.js

Setting up NodeJS project

To start with, let's create a new directory and you can name it nodeapp or any other meaningful name. If you open this directory in Visual Studio Code as expected you won't have anything with in it!

In order to make it a Node project you'll have to use the command npm init which creates a package.json file by asking you few questions. If you want to bypass these questions and answer "yes" by default for all the questions you can use npm init -y command instead.

Go to the directory you have just created and run the npm init command to initialize your Node project.

nodeapp>npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (nodeapp)
version: (1.0.0)
description: A node project
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\NETJS\NetJS_2017\NodeJS\nodeapp\package.json:

{
  "name": "nodeapp",
  "version": "1.0.0",
  "description": "A node project",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)

As you can see for most of the questions asked, I have just pressed enter, only entry is for the "description". You can always go later to the created package.json file and edit it so no worries.

If you go to Visual Studio code now you should see the generated package.json file.

Setting NodeJS project

Since the starting file is named as "index.js" so let's create such a file in our "nodeapp" project.

index.js

console.log("It's a new Node project");

Running this JavaScript file should output the content as expected.

node index.js

It's a new Node project

Now let's change our package.json a little and add a kay-value entry in the "scripts" section.

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },

This instructs Node to use start script as the executor of the command given as value "node index.js". Now you can use npm start command to start your project.

npm start

> nodeapp@1.0.0 start
> node index.js
It's a new Node project

Importing packages in NodeJS

Let's try to import and use modules in our code files. To start with we'll import built-in Node modules for which you don't need any extra installation as these modules are already there in NodeJS.

We'll use fs and path modules to write a file. The 'fs' module is used to handle the file system and the 'path' module is used to handle file paths.

In order to use these modules, you'll need to import them, in NodeJS you can do it as given below.

const fs = require('fs');

const path = require('path');

Using writeFile() method of the fs package we'll write to a file. Here is the description of the writeFile() method.

fs.writeFile( file, data, options, callback )
  • file: Path of the file where it has to be written.
  • data: The data you want to write to the file.
  • options: To specify optional parameters like encoding
  • callback: It is the function that would be called when the method is executed.

index.js

Here is the modified index.js file.

const fs = require('fs');
const path = require('path');
console.log(__dirname);
console.log("It's a new Node project");
const content = "A test file";
fs.writeFile(path.join(__dirname, 'test.txt'), content, (err) => {
    if (err)
      console.log(err);
    else {
      console.log("File written successfully\n");
    }
});

Note that __dirname is a variable that tells you the absolute path of the directory containing the currently executing file. Using path.join() method an absolute path for the file is given.

If you run npm start command now you should see a file "test.txt" created within your root project directory.

Installing third party packages in Node project

In the above example we used built-in modules that don’t need any installation but you will definitely use many other third-party packages that would need installation. For that you will use npm install <package_name> command.

In our project we'll try to install Nodemon package that helps develop Node.js based applications by automatically restarting the node application when file changes in the directory are detected.

To see Nodemon in use we'll change the index.js to create a HTTP Server using Node.js

index.js

const http = require('http');

const hostname = 'localhost';
const port = 3000;

const requestListener = function(req, res){
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.write('Hello World');
    res.write(' From NodeJS\n');
    res.end();
}
const server = http.createServer(requestListener);

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

If you run the npm start command now and go to the URL http://localhost:3000/ once the server is started you should see the response as sent by the server.

If we make a slight change in the code now and change the line from res.write(' From NodeJS\n'); to this res.write(' From NodeJS Project\n');

Above change won't be reflected automatically and you'll have to stop the server and restart it to get this change reflected. That's where Nodemon can help as it automatically restarts the node application when file changes are detected.

npm install options

You can control where and how the specified packages get saved by using some additional flags with npm install

-P, --save-prod: Package will appear in your dependencies. You'll use this option if you want the installed package to be part of production build too. This is the default also

-D, --save-dev: Package will appear in your devDependencies. You'll use this option if you want the installed package to be used during development only.

-O, --save-optional: Package will appear in your optionalDependencies.

--no-save: Prevents saving to dependencies.

It makes sense to install Nodemon as dev dependency so use the following command to install Nodemon.

npm install nodemon --save-dev

Once the installation is done if you go back to your project structure you'll see some new directories and files like package-lock.json and node_modules folder.

package-lock.json- Provides version information for all packages installed into node_modules by the npmclient.
node_modules- Provides npm packages to the entire workspace. That's the directory where packages are installed.

Node project structure

In the package.json file now you'll see a "devDependencies" entry.

"devDependencies": {
    "nodemon": "^3.1.0"
  }

You'll need to make one more change in the start script to start using nodemon rather than node.

"start": "nodemon index.js"

With that if you use npm start command.

npm start

> nodeapp@1.0.0 start
> nodemon index.js

[nodemon] 3.1.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,cjs,json
[nodemon] starting `node index.js`
Server running at http://localhost:3000/

If you make changes in index.js file you can see that the application starts automatically now.

[nodemon] restarting due to changes...
[nodemon] starting `node index.js`
Server running at http://localhost:3000/

That's all for this topic How to Setup a Node.js Project. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Introduction to Node.js
  2. Creating HTTP server in Node.js
  3. JavaScript Rest Parameter
  4. JavaScript filter Method With Examples

You may also like-

  1. Count Number of Words in a String Java Program
  2. How to Use ngFor and ngIf in Same Element in Angular
  3. Angular @Input and @Output Example
  4. React create-react-app Project Structure
  5. BigDecimal in Java With Examples
  6. Spring Boot Hello World Web Application Example
  7. Java Exception Handling Interview Questions And Answers
  8. Creating PDF in Java Using iText

Tuesday, April 23, 2024

Difference Between StackOverflowError and OutOfMemoryError in Java

Differences between StackOverflowError and OutOfMemoryError in Java is a frequently asked Java interview question. You may also encounter one of these errors in your application. Before going into StackOverflowError Vs OutOfMemoryError let’s get some background about these errors.


StackOverflowError in Java

Whenever you run any Java program even if you don’t explicitly create any thread a main thread is started and that thread runs the program.

For each thread JVM creates a stack, whenever any method is invoked a new frame is created and pushed into the JVM stack for the thread. Each frame stores data corresponding to the invoked method including local variables, operand stack and a reference to the run-time constant pool and reference to exception table.

Once the method execution is completed corresponding stack frame is popped out of the stack.

JVM throws StackOverflowError if the stack memory requirement of any method exceeds the permitted stack memory size. A very common scenario where you may see StackOverflowError is when you have a recursive method with no terminating condition. For example following program that calculates factorial of a number using recursive method call. Since there is no exit condition defined so recursive method call never ends resulting in StackOverflowError.

public class StackOFErrorExp {
  public static void main(String[] args) {
    double factorialResult = factorial(1000);
    System.out.println(factorialResult);
  }
  private static int factorial(int i) {
    /*
     * if (i == 0 || i == 1 ) '
     *  return 1;
     */
    return i * factorial(i - 1);
  }
}

OutOfMemoryError in Java

In Java, memory for each object, for arrays and for instance variables (variables at class level not method level) is created on the heap. When there are no references to an object that object is garbage collected thus clearing the heap memory.

If you try to create an object or array that tries to take more memory than the allocated heap memory or there are a lot of objects in heap that are still referenced so can’t be garbage collected and JVM tries to allocate heap memory for a new object JVM throws java.lang.OutOfMemoryError because there is no sufficient heap memory.

Here is an example of java.lang.OutOfMemoryError where objects are added to an ArrayList in an infinite loop. Since objects stored to the List are not garbage collected so heap memoery will finally run out of memory resulting in OutOfMemoryError.

public class OutofMemoryExp {
  public static void main(String[] args) {
    List list = new ArrayList<>();
    int i = 0;
    // results in indefinite loop
    while(true) {
      i++;
      list.add(i * 1000000);
    }  
  }
}

Output

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at java.base/java.util.Arrays.copyOf(Arrays.java:3721)
 at java.base/java.util.Arrays.copyOf(Arrays.java:3690)
 at java.base/java.util.ArrayList.grow(ArrayList.java:237)
 at java.base/java.util.ArrayList.grow(ArrayList.java:242)
 at java.base/java.util.ArrayList.add(ArrayList.java:485)
 at java.base/java.util.ArrayList.add(ArrayList.java:498)
 at org.netjs.examples.OutofMemoryExp.main(OutofMemoryExp.java:14)

StackOverflowError Vs OutOfMemoryError in Java

  1. StackOverflowError is thrown when there is no sufficient stack space for storing method data.
    OutOfMemoryError is thrown when no sufficient heap space left for creating new objects or requested array size is more than heap memory.
  2. StackOverflowError happens when you have Recursive methods with out terminating condition.
    OutOfMemoryError happens when new objects can’t be allocated on the heap as existing objects still have references so can’t be garbage collected.
  3. In order to avoid StackOverflowError ensure that methods are finishing their execution and corresponding stack memory is freed.
    In order to avoid OutOfMemoryError ensure that there are no references to objects which you don’t need anymore so that such objects can be garbage collected freeing heap memory in the process.

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


Related Topics

  1. Difference Between Checked And Unchecked Exceptions in Java
  2. Difference Between throw And throws in Java
  3. final Vs finally Vs finalize in Java
  4. java.lang.ClassCastException - Resolving ClassCastException in Java
  5. java.lang.UnsupportedClassVersionError - Resolving UnsupportedClassVersionError in Java

You may also like-

  1. Java Exception Handling Interview Questions And Answers
  2. Array in Java With Examples
  3. Varargs (Variable-length Arguments) in Java
  4. Type Erasure in Java Generics
  5. Pre-defined Functional Interfaces in Java
  6. Linear Search (Sequential Search) Java Program
  7. Introduction to Node.js
  8. Bean Scopes in Spring With Examples

Monday, April 22, 2024

What is In-place Algorithm

An in-place algorithm is an algorithm that doesn’t use any auxiliary space to transform the input. Though theoretically that would mean if you have an array of length n then you should use that n space itself to transform the input array but in reality you will definitely use some variables and index for array and that kind of auxiliary space is allowed for an in-place algorithm.

Examples of in-place algorithm are sorting algorithms like Bubble sort, Selection Sort, Insertion Sort which doesn’t require any extra space to perform sorting. That is why space complexity for these algorithms is O(1).

Merge sort, Bucket sort are examples of not in-place or out-of-place sorting algorithms.

In-place algorithm example

Let’s try to understand this auxiliary space requirement of in-place algorithm by taking an algorithm to reverse an array by using separate input and output arrays making it a not in-place algorithm.

import java.util.Arrays;

public class ReverseArray {
  public static void main(String[] args) {
    int[] intArr = {47, 85, 47, 34, 7, 10, 0, 106, 2, 54};
    reverseArray(intArr);
  }
    
  static void reverseArray(int[] intArray) {
    int n = intArray.length;
    // Using another array
    int[] tempArray = new int[n];
    for (int i = 0; i < n; i++) { 
      tempArray[n - i - 1] = intArray[i]; 
    } 
    System.out.println("Reversed Array- " + Arrays.toString(tempArray));
  }
}

But the algorithm to reverse an array can very well be written to use the same input array to reverse it. There is no need to use a separate array making it an in-place algorithm.

public class ReverseArray {
  public static void main(String[] args) {
    int[] intArr = {47, 85, 47, 34, 7, 10, 0, 106, 2, 54};
    reverseArray(intArr);
  }
    
  static void reverseArray(int[] intArray) {
    int n = intArray.length;
    for (int i = 0; i < n / 2; i++) {
      int temp = intArray[i];
      intArray[i] = intArray[n - 1 - i];
      intArray[n - 1 - i] = temp;
    }
    System.out.println("Reversed Array- " + Arrays.toString(intArray));
  }
}

That's all for this topic What is In-place Algorithm. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Programs Page


Related Topics

  1. Shell Sort Program in Java
  2. Tree Sort in Java Using Binary Search Tree
  3. Linear Search (Sequential Search) Java Program
  4. Reverse Each Word in a String Java Program
  5. How to Remove Elements From an Array Java Program

You may also like-

  1. Converting String to Enum Type in Java
  2. How to Read File From The Last Line in Java
  3. Java Program to Get Current Date and Time
  4. Running Dos/Windows Commands From Java Program
  5. How to Loop Through a Map in Java
  6. Difference Between Abstract Class And Interface in Java
  7. Angular One-Way Data Binding Using String Interpolation
  8. Changing String Case in Python