Top 50+ Java 8 Interview Questions & Answers 2025 [Updated]

Top 50+ Java 8 Interview Questions & Answers 2025 [Updated]

18 Sep 2024
Question
7.81K Views
38 min read
Learn with an interactive course and practical hands-on labs

Java Online Course Free with Certificate

Java 8 is a known language for every Java developer. The latest release contains newJava Features, enhancements, and bug fixes to improve efficiency in developing and running Java programs. So, acquiring knowledge about Java 8 is now a need for every Java developer. Learning Java 8 can significantly contribute to your success in the Java developer journey.

Hence In this Java Tutorial, we will explore the top 50 Java 8 Interview Questions and Answers. These questions cover both standard and advanced commonly encountered topics during interviews. By thoroughly reading and understanding these questions, you’ll be well-prepared for your Java interview. Let’s start with Java 8 Interview Questions & Answers for Beginners.

Become a full stack expert with our Full Stack Java Developer Course—enroll and build your future!

Java 8 Interview Questions & Answers for Beginners

1. What are the features of Java 8?

  • Lambda expressions

A way to characterize and pass around blocks of code as if they were objects, which permits for more concise, functional-style code.

  • Functional interfacing

Interfacing has precisely one unique method, which allows for behavior parameterization and the capacity to pass behavior as a method argument.

  • Streams

A modern API for processing collections of information that allows for operations such as filtering, mapping, and decreasing to be performed in a more functional and clear way.

  • Date and time API

A modern API for working with date and time, which replaces the legacy java.util.Date and java.util.Calendar classes.

  • Concurrent Accumulators

A set of classes planned for utilization with parallel streams, which permit for the effective amassing

2. In Java 8, What are lambda expressions and their use?

Lambda expressions are nothing but a new feature that allows programmers to write more concise, functional-style code.

It is composed of three parts:

  • A list of parameters (or none) is enclosed in parentheses or brackets.
  • The “arrow” token ->
  • The body of the lambda expression can be a single expression or a block of code.

Syntax of simple lambda expression

 (int x, int y) -> {return x + y; }   

Uses of lambda expressions

  • Lambda expressions can be utilized to define functional interfacing, which are interfacing that have a single abstract method. The java.util.function package in Java 8 incorporates a few functional interfacing such as Customer, Work, Predicate, and Provider.
  • Lambda expressions can also be passed to methods or utilized as arguments for functional interfacing. For case, the forEach method of the java.util.stream.Stream class takes a Consumer functional interface as an argument, allowing us to pass in a lambda expression to perform a particular action on each component within the stream.
  • Lambda expressions can also be used with other features of Java 8 such as streams and the new date and time API to perform operations such as filtering, mapping, and decreasing collections of information, in a more functional and clear way.
  • It's worth noticing that, in spite of the fact that lambda expressions can offer assistance to make your code more concise and readable, they can also make it more difficult to get it if they are not used accurately. It's critical to utilize them in a way that produces the code simple to understand.

3. What are different kinds of Method References?

 different kinds of Method References?

4. In which programming paradigm did Java 8 fall?

programming paradigm did Java 8

5. What are Java 8 significant advantages?

  • It is Compact, readable, and reusable code.
  • It has Less boilerplate code.
  • It can do Parallel operations and execution.
  • It can be ported across operating systems.
  • It has High stability.
  • It has a Stable environment.

6. What is MetaSpace in Java 8? How does it differ from PermGen?

What is MetaSpace in Java 8? How does it differ from PermGen?

MetaSpace:

Java 8 stores the MetaData of classes in local memory called 'MetaSpace'. It is not a contiguous Heap Memory and hence can be developed dynamically which makes a difference to overcome the size limitations. This moves forward the garbage collection, auto-tuning, and de-allocation of metadata.

PremGen:

PreGem stands forPermanent-Generation, MetaData data of classes was stored in PremGen memory type before Java 8. PremGen is settled in size and cannot be dynamically resized. It was a contiguous Java Heap Memory.

Become a Java Full-Stack Developer with ScholarHat’s expert-led training.

Training Name Price
Full-Stack Java Developer Course (Learn Today, Earn ₹3 - ₹9 LPA* Tomorrow) Book a FREE Live Demo!

7. What are static methods in Interfaces?

Static methods, which contain method implementation are owned by the interface and are invoked using the name of the interface, it is suitable for defining the utility methods and cannot be overridden.

Example:

static methods in interfaces
 interface DemoInterface {

	// static method
	static void hello()
	{
		System.out.println("Hello, Welcome to Scholarhat");
	}
	// Public and abstract method of Interface
	void overrideMethod(String str);
}

// Implementation Class
public class InterfaceEx implements DemoInterface {

	public static void main(String[] args)
	{
		InterfaceEx interfaceEx= new InterfaceEx();

		// Calling the static method of interface
		DemoInterface.hello();

		// Calling the abstract method of interface
		interfaceEx.overrideMethod("Hello, Override Method here");
	}

	// Implementing interface method

	@Override
	public void overrideMethod(String str)
	{
		System.out.println(str);
	}
}  

Output

Hello, Welcome to Scholarhat
Hello, Override Method here    

8. What are some standard Java pre-defined functional interfaces?

  • Runnable: used to execute the instances of a class over another thread with no arguments and no return value.
  • Callable: used to execute the instances of a class over another thread with no arguments and it either returns a value or throws an exception.
  • Comparator: used to sort different objects in a user-defined order
  • Comparable: used to sort objects in the natural sort order

9. What are the various categories of pre-defined function interfaces?

  1. Function: To transform arguments in returnable value.
  2. Predicate: To perform a test and return a Boolean value.
  3. Consumer: Accept arguments but do not return any values.
  4. Supplier: Do not accept any arguments but return a value.
  5. Operator: Perform a reduction-type operation that accepts the same input types.

10. How does a lambda expression relate to a functional interface?

  • It is a type of function without a name. It may or may not have its results and parameters. It is also known as an anonymous function as it does not have type information by itself. It is executed on demand. It is advantageous in iterating, filtering, and extracting data from a collection.
  • As lambda expressions are similar to anonymous functions, they can only be applied to the single abstract method of Functional Interface. It will infer the return type, type, and several arguments from the signature of the abstract method of the functional interface.

11. What Is the Meaning of String::Valueof Expression?

String::Valueof Expression( ) is a static method reference to the valueOf method of the String class.

12. Explain Some of the Functional Interfaces in the Standard Library

  • Function – takes one argument and returns a result
  • Consumer – takes one argument and returns no result (represents a side effect)
  • Supplier – takes no arguments and returns a result
  • Predicate – takes one argument and returns a boolean
  • BiFunction – takes two arguments and returns a result
  • BinaryOperator – is similar to a BiFunction, taking two arguments and returning a result. The two arguments and the result are all of the same type.

13. What Is Nashorn in Java8?

  • Nashorn is the new Javascript processing engine for the Java platform that shipped with Java 8. Until JDK 7, the Java platform used Mozilla Rhino as a Javascript processing engine for the same purpose.
  • Nashorn provides better compliance with the ECMA-normalized JavaScript specification and better runtime performance than its predecessor.

14. What Is JJS?

In Java 8, jjs is the new executable or command-line tool for executing Javascript code at the console.

15. What Is Stream Pipelining in Java 8?

  • Stream pipelining is the concept of chaining operations together. We do this by splitting the operations that can happen on a stream into two categories: intermediate operations and terminal operations.
  • Each intermediate operation returns an instance of Stream itself when it runs. Therefore, we can set up an arbitrary number of intermediate operations to process data, forming a processing pipeline.
  • There must then be a terminal operation that returns a final value and terminates the pipeline.

16. Specify the advantages of using Java 8

  • It helps in creating applications much faster and more easily.
  • It provides a very stable ambient for the developers.
  • Concise, reusable, and easy-to-comprehend codes.
  • Improved and effective support.
  • Easy to port across various operating systems.
  • Minimum boilerplate codes.

17. What is a collection, and how is it different from a stream?

A collection is an in-memory database that records all the values according to the current data structure. So, before you add it to the collection, it’s important to compute each of them. Whereas a stream is a visually fixed data structure where we can compute the elements according to our needs.

18. What are predicate and consumer in Java 8?

  • A predicate is a functional interface that typically receives arguments and retrieves a Boolean value. You can use it to apply the filter for a collection of objects.
  • On the other hand, the consumer is referred to as an in-build functional interface found in Java.util.function package. You can use it to consume any object, and it takes the input value and gives out nothing.

19. Why is the peek () method used in Java 8?

The peek() method helps support debugging, where one wants to notice the elements as they tend to flow from a specific point in a pipeline. It is a representation of our observation of how each element passes.

Syntax:

public Object peek() 

20. Which situation is most suitable for using stream API in Java 8?

  • For executing lazy operations
  • To perform database operations
  • Use for internal iterations.
  • For writing functional-style programming
  • You can use it for using pipeline operations.

Java 8 Interview Questions and Answers for Intermediate

21. What are functional or SAM interfaces?

  • Functional Interfaces are interfaces with only one abstract method.
  • Due to this, it is also known as the Single Abstract Method (SAM) interface.
  • It is also known as a functional interface because it wraps a function as an interface.
  • These interfaces can have any number of default, static, and overridden methods.
  • If declaring Functional Interfaces @FunctionalInterface annotation is optional to use.
  • If this annotation is used for interfaces with more than one abstract method, it will generate a compiler error.

22. Can we extend the functional interface to another interface?

No, we can not extend or inherit a functional interface into another interface also it can not be be achievable through abstract methods as it will void the rule of one abstract method per functional interface.

Example:

interface Student{ 
public int studenttMethod(); 
} 
@FunctionalInterface // This cannot be FunctionalInterface 
interface Child extends Parent { 
public int childMethod(); 
}   

As shown in the above code, It will also extend the abstract method of the Parent Interface. Hence it will have more than one abstract method And will give a compiler error.

23. What is the function of Type Inference?

Type Inference assists the compiler in identifying or recognizing the types of arguments by just having an overview of the corresponding declaration and method invocation.

24. What is the default method, and why is it required?

  • A method in the interface that has a predefined body is known as the default method.
  • It uses the keyword default.
  • default methods were introduced in Java 8 to have 'Backward Compatibility in case JDK modifies any interfaces.
  • In case a new abstract method is added to the interface, all classes implementing the interface will break and will have to implement the new method. With default methods, there will not be any impact on the interface implementing classes.
  • Default methods can be overridden if needed in the implementation. Also, it does not qualify as synchronized or final.
@FunctionalInterface // Annotation is optional 
public interface Foo() { 
// Default Method - Optional can be 0 or more 
public default String Scholarhat() { 
return "Welcome to Scholarhat"; 
} 
// Single Abstract Method 
public void bar(); 
}    

25. What is the basic structure/syntax of a lambda expression?

FunctionalInterface fi = (String name) -> { 
System.out.println("HelloScholarhat "+name); 
return "HelloScholarhat "+name; 
}   

A lambda expression can be divided into three distinct parts as below: 1. List of Arguments/Params: (String name) A list of params is passed in () round brackets. It can have zero or more parameters. Declaring the type of parameter is optional and can be inferred for the context. 2. Arrow Token: -> Arrow token is known as the lambda arrow operator. It is used to separate the parameters from the body, or it points the list of arguments to the body. 3. Expression/Body:

{ 
System.out.println("HelloScholarhat "+name); 
return "HelloScholarhat "+name; 
}   
A body can have expressions or statements. {} curly braces are only required when there is more than one line. In one statement, the return type is the same as the return type of the statement. In other cases, the return type is either inferred by the return keyword or void if nothing is returned.

26. What are the types and common ways to use lambda expressions?

A lambda expression does not have any specific type by itself. A lambda expression receives type once it is assigned to a functional interface. That same lambda expression can be assigned to different functional interface types and can have a different type.
  1. s -> s.isEmpty() :
  2. Predicate<String> stringPredicate = s -> s.isEmpty();
  3. Predicate<List> listPredicate = s -> s.isEmpty();
  4. Function<String, Boolean> func = s -> s.isEmpty();
  5. Consumer<String> stringConsumer = s -> s.isEmpty();

27. In Java 8, what is Method Reference?

Method reference is a compact way of referring to a method of functional interface. It is used to refer to a method without invoking it. :: (double colon) is used for describing the method reference. The syntax is class::methodName

Example:

Integer::parseInt(str) \\ method reference
str -> Integer.ParseInt(str); \\ equivalent lambda   

28. What is an Optional class?

Optional is a container type which may or may not contain value i.e. zero(null) or one(not-null) value. It is part of java.util package. There are pre-defined methods like isPresent(), which returns true if the value is present or else false and the method get(), which will return the value if it is present.
static Optional changeCase(String word) {
if (name != null && word.startsWith("A")) {
   return Optional.of(word.toUpperCase());
  }
else {
return Optional.ofNullable(word); // someString can be null
}
}    

29. What are the main components of a Stream?

The components of the stream are:
  • A data source
  • Set of Intermediate Operations to process the data source
  • Single Terminal Operation that produces the result

What are the main components of a Stream?

30. What are the sources of data objects a Stream can process?

A Stream can process the following data:
  • A collection of an Array.
  • An I/O channel or an input device.
  • A reactive source (e.g., comments on social media or tweets/re-tweets)
  • A stream generator function or a static factory.

31. What are Intermediate Operations

  • Process the stream elements.
  • Typically transforms a stream into another stream.
  • Are lazy, i.e., not executed till a terminal operation is invoked.
  • Does internal iteration of all source elements.
  • Any number of operations can be chained in the processing pipeline.
  • Operations are applied as per the defined order.
  • Intermediate operations are mostly lambda functions.

32. What are Terminal Operations?

  • Kick-starts the Stream pipeline.
  • used to collect the processed Stream data.
int count = Stream.of(1, 2, 3, 4, 5)
.filter(i -> i <4) // Intermediate Operation filter
.count(); // Terminal Operation count 

33. What are the most commonly used Intermediate operations?

  • Filter(Predicate<T>) - Allows selective processing of Stream elements. It returns elements that are satisfying the supplied condition by the predicate.
  • map(Funtion<T, R>) - Returns a new Stream, transforming each of the elements by applying the supplied mapper function.= sorted() - Sorts the input elements and then passes them to the next stage.
  • distinct() - Only pass on elements to the next stage, not passed yet.
  • limit(long maxsize) - Limit the stream size to maxsize.
  • skip(long start) - Skip the initial elements till the start.
  • peek(Consumer) - Apply a consumer without modification to the stream.
  • flatMap(mapper) - Transform each element to a stream of its constituent elements and flatten all the streams into a single stream

34. What is the stateful intermediate operation? Give some examples of stateful intermediate operations.

  • To complete some of the intermediate operations, some state is to be maintained, and such intermediate operations are called stateful intermediate operations.
  • Parallel execution of these types of operations is complex.
  • For Eg: sorted() , distinct() , limit() , skip() etc.
  • Sending data elements to further steps in the pipeline stops till all the data is sorted for sorted() and stream data elements are stored in temporary data structures.

35. What is the difference between findFirst() and findAny()?

What is the difference between findFirst() and findAny()?

Java 8 Interview Questions and Answers for Experienced

36. How are Collections different from Stream?

How are Collections different from Stream?

37. Explain with example, LocalDate, LocalTime, and LocalDateTime APIs.

LocalDate

  • Date with no time component
  • Default format - yyyy-MM-dd (2020-02-20)
  • LocalDate today = LocalDate.now(); // gives today’s date
  • LocalDate date = LocalDate.of(2011, 12, 30); //(year, month, date)

LocalTime

  • Time with no date with nanosecond precision
  • Default format - hh:mm:ss: zzz (12:06:03.015) nanosecond is optional
  • LocalTime now = LocalTime.now(); // gives time now
  • LocalTime aTime2 = LocalTime.of(18, 20, 30); // (hours, min, sec)

LocalDateTime

  • Holds both Date and Time
  • Default format - yyyy-MM-dd-HH-mm-ss.zzz (2020-02-20T12:06:03.015)
  • LocalDateTime timestamp = LocalDateTime.now(); // gives timestamp now
  • //(year, month, date, hours, min, sec)
  • LocalDateTime dt1 = LocalDateTime.of(2011, 12, 30, 18, 20, 30);

38. What is the use of JJS in Java 8?

JAVA>jjs
jjs> print("Hello, Java 8 - Welcome to Scholarhat!")
Hello, Java 8 -Welcome to Scholarhat!!
jjs> quit()
>> 

39. How is the Functional Interface created in Java 8 in detail?

You can employ lambda expression to implement the abstract method of the functional interface in Java 8. Below is a coding example of the same:
import java.util.function.Consumer;
public class FunctionalInterfaceExample {
    public static void main(String[] args) {
        Consumer printer = System.out::println;
        printer.accept("Hello, Welcome to scholahat!");
    }
}    

40.Explain the skip(long) using an example.

The skip (long) is an intermediate operation that retrieves the leftover elements after eliminating the initial n elements of a specific stream.

Example:

import java.util.Arrays;
import java.util.List;
public class SkipExample {
    public static void main(String[] args) {
        List names = Arrays.asList("Alice", "Bob", "Charlie", "Dave", "Eve");
        // Create a stream from the names list
        names.stream()
                // Skip the first two elements of the stream
                .skip(2)
                // Print the remaining elements to the console
                .forEach(System.out::println);
    }
} 

Output

Charlie
Dave
Eve   

41. Is there anything wrong with the following code? Will it compile or give any specific error?

@FunctionalInterface
public interface Test<A, B, C> {
    public C apply(A a, B b);
  
    default void printString() {
        System.out.println("Scholarhat");
    }
}   

Yes. The code will compile because it follows the functional interface specification of defining only a single abstract method. The second method, printString(), is a default method that does not count as an abstract method.

42. What is the difference between limit and skip?

The limit() method is used to return the Stream of the specified size. For Example, If you have mentioned limit(5), then the number of output elements would be 5.
import java.util.stream.Stream;
 
public class Java8 {
     
    public static void main(String[] args) {
        Stream.of(0,1,2,3,4,5,6,7,8)
        .limit(5)         
        /*limit is set to 5, hence it will print the 
        numbers starting from 0 to 4 
        */
        .forEach(num->System.out.print("\n"+num));
    }
}   

Whereas, the skip() method is used to skip the element.

Let’s consider the following example. In the output, the elements are 6, 7, and 8 which means it has skipped the elements till the 6th index (starting from 1).

import java.util.stream.Stream;
 
public class Java8 {
     
    public static void main(String[] args) {
        Stream.of(0,1,2,3,4,5,6,7,8)
        .skip(6)
        /*
         It will skip till 6th index. Hence 7th, 8th and 9th
         index elements will be printed
         */
        .forEach(num->System.out.print("\n"+num));
    }
}   

43.How will you get the current date and time using Java 8 Date and Time API?

The below program is written with the help of the new API introduced in Java 8. We have made use of LocalDate, LocalTime, and LocalDateTime API to get the current date and time. In the first and second print statement, we have retrieved the current date and time from the system clock with the time-zone set as default. In the third print statement, we have used LocalDateTime API which will print both date and time.
class Java8 {
    public static void main(String[] args) {
        System.out.println("Current Local Date: " + java.time.LocalDate.now());
        //Used LocalDate API to get the date
        System.out.println("Current Local Time: " + java.time.LocalTime.now());
        //Used LocalTime API to get the time
        System.out.println("Current Local Date and Time: " + java.time.LocalDateTime.now());
        //Used LocalDateTime API to get both date and time
    }
}

Output

Current Local Date: 2025-05-03
Current Local Time: 14:16:35.547225
Current Local Date and Time: 2025-05-03T14:16:35.547937    

44.What is the purpose of the limit() method in Java 8?

The Stream.limit() method specifies the limit of the elements. The size that you specify in the limit(X), it will return the Stream of the size of ‘X’. It is a method of java.util.stream.Stream

Syntax

limit(X)

45.Write a program to print 5 random numbers using forEach in Java 8.

The below program generates 5 random numbers with the help of forEach in Java 8. You can set the limit variable to any number depending on how many random numbers you want to generate.
import java.util.Random;
 
class Java8 {
    public static void main(String[] args) {
 
        Random random = new Random();
        random.ints().limit(5).forEach(System.out::println);
        /* limit is set to 5 which means only 5 numbers will be printed
        with the help of terminal operation forEach
        */
 
    }
}    

Output

-1646831910
1354901963
-931542791
1540023264
-2021335902    

46. What is the difference between Stream’s findFirst() and findAny()?.

As the name suggests, the findFirst() method is used to find the first element from the stream whereas the findAny() method is used to find any element from the stream. The findFirst() is predestinarianism in nature whereas the findAny() is non-deterministic. In programming, Deterministic means the output is based on the input or initial state of the system.You can carry out parallel processing.

47. What is the difference between Iterator and Spliterator?

IteratorSpliterator
It was introduced in Java version 1.2It was introduced in Java SE 8
It is used for Collection API.It is used for Stream API.
Some of the iterate methods are next() and hasNext() which are used to iterate elements.Spliterator method is tryAdvance().
We need to call the iterator() method on the Collection Object.We need to call the spliterator() method on Stream Object.
Iterates only in sequential order.Iterates in Parallel and sequential order.

48. What is the Difference Between Map and flatMap Stream Operation?

Map Stream operation gives one output value per input value whereas flatMap Stream operation gives zero or more output value per input value. While flatMap Stream operation is used for more complex Stream operation.

map() Vs. flatMap()

If we compare about both we should use map() when we want to perform a simple transformation on each element in the stream, and flatMap() when we want to produce a stream that contains elements from multiple sources.
Suppose you have a list of lists of integers, and you want to produce a stream of all the integers in the lists. You could use the map() operation to produce a stream of lists, and then use the flatMap() operation to produce a stream of integers.

Example:


import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class MapFlatMap {
    public static void main(String[] args) {
        List> listOfLists = Arrays.asList(Arrays.asList(3, 4, 5), Arrays.asList(6, 7, 8));
        Stream> listStream = listOfLists.stream().map(list -> list);
        Stream intStream = listStream.flatMap(list -> list.stream());
        System.out.println(intStream);
        intStream.forEach(System.out::println);
    }
}
    

Output

3
4
5
6
7
8    

49. Write down a Java 8 program that can find a Stream’s minimum and maximum number.


import java.util.Arrays;
import java.util.stream.IntStream;
public class MinMaxExample {
    public static void main(String[] args) {
        int[] numbers = {9, 3, 8, 1, 5, 7, 2, 6, 4};
        int min = IntStream.of(numbers).min().getAsInt();
        int max = IntStream.of(numbers).max().getAsInt();
        System.out.println("Minimum number: " + min);
        System.out.println("Maximum number: " + max);
    }
}
    

Output

Minimum number: 1
Maximum number: 9    
In Java 8, a new feature was introduced to store classes. The area where all the classes that are stored in Java 8 are called MetaSpace. MetaSpace has replaced the PermGen.
Till Java 7, PermGen was used by Java Virtual Machine to store the classes. Since MetaSpace is dynamic as it can grow dynamically and it does not have any size limitation, Java 8 replaced PermGen with MetaSpace.

50. What is JJS?

JJS is a command-line tool used to execute JavaScript code at the console. In Java 8, JJS is the new executable which is a JavaScript engine.
Conclusion:
So, here we have covered the mostly asked Java8 Questions from basic to advanced for all interested candidates. For a complete understanding of Java refer to our Java Certification Program.
Read More
1Top 50 Java Interview Questions and Answers
2Top 50 Java MCQ Questions
3Java Developer Salary Guide in India
4Java Full Stack Developer Salary
5Java Multithreading Interview Questions and Answers 2025

Download this PDF Now - JAVA 8 Interview Questions and Answers PDF By ScholarHat

FAQs

Brush up on object-oriented programming (OOP) principles, such as inheritance, polymorphism, encapsulation, and abstraction.

It allows developers to refer to methods or constructors using a concise syntax, improving code readability and reducing boilerplate code

It is a method that, when applied to a stream of values, maps each value to some required output value.
Share Article
About Author
Shailendra Chauhan (Microsoft MVP, Founder & CEO at Scholarhat by DotNetTricks)

Shailendra Chauhan, Founder and CEO of ScholarHat by DotNetTricks, is a renowned expert in System Design, Software Architecture, Azure Cloud, .NET, Angular, React, Node.js, Microservices, DevOps, and Cross-Platform Mobile App Development. His skill set extends into emerging fields like Data Science, Python, Azure AI/ML, and Generative AI, making him a well-rounded expert who bridges traditional development frameworks with cutting-edge advancements. Recognized as a Microsoft Most Valuable Professional (MVP) for an impressive 9 consecutive years (2016–2024), he has consistently demonstrated excellence in delivering impactful solutions and inspiring learners.

Shailendra’s unique, hands-on training programs and bestselling books have empowered thousands of professionals to excel in their careers and crack tough interviews. A visionary leader, he continues to revolutionize technology education with his innovative approach.
Accept cookies & close this