Closures in Javascript

Wherever the function is declared and defined, it remembers the complete snapshot of the function, i.e, the scope chains used within the function.

var a = 10;
function outer() {
  var b = 20;
  var inner = function() {
    console.log(a);
    console.log(b);
  }
  return inner;
}
var innerFn = outer();
innerFn();
var innerFn1 = outer();
innerFn1();

When innerFn() is executed, it prints both ‘a’ and ‘b’. Printing ‘a’ is fine because its in global scope but printing ‘b’ looks interesting because var ‘b’ is in outer scope which is run and complete and hence no longer exists and there scope for var ‘b’ should not exists. But its working because JS has feature of CLOSURES.

In above program, global variables are created only once, whereas function variables are created as many times as the function is invoked.
So when innerFn() is invoked first time, it remembers snapshot of global var ‘a’ (created only once) and function var ‘b’ (created with outer function execution first time)
So when innerFn() is invoked next time, it remembers snapshot of global var ‘a’ (as before) and function var ‘b’ (created again with outer function execution second time)
To verify this make a small modification

var a = 10;
function outer() {
  var b = 20;
  var inner = function() {
    a++;
    b++;
    console.log(a);
    console.log(b);
  }
  return inner;
}
var innerFn = outer();
innerFn();
var innerFn1 = outer();
innerFn1();

Output:
11
21
12
21

Asynchronous callbacks as closures
As JS engine is single threaded, there is no concept of pause/wait in the program. To achieve this we use a global function called ‘setTimeout’ where it fires the given function asynchronously after the specified time.

var a = 10;
var fn = function() {
  console.log(a);
}
setTimeout(fn, 1000);
console.log("done");

Important thing to notice here is that, this is the best example of CLOSUREs, because the function we declared is trying to access global variable ‘a’ which is remembered by the function eventhough its executed inside another function ‘setTimeout’

The Module Pattern in JS

var person = {
  "firstName": "Niranjan",
  "lastName": "Tallapalli",
  "getFirstName": function() {
    return this.firstName;
  },
  "getLastName": function() {
    return this.lastName;
  }
}
person.getFirstName(); // would give me first name BUT
person.firstName; // would also let me access the first name because there is no concept of private in JS

There is no concept of private variables in JS, everything is by default public. To make variable private, we can do one of the following

  • We can make use of closures
  • We can make use of Module Pattern

The idea here is to make use of the concept of new function SCOPE so that the variables are not visible outside the scope.

function createPerson() {
  var firstName = "Niranjan",
  var lastName = "Tallapalli",
  var person = {
    "getFirstName": function() {
      return this.firstName;
    },
    "getLastName": function() {
      return this.lastName;
    }
  }
}
person.getFirstName(); // would give me first name as usual
person.firstName; // will not work

Closures in Async Callbacks

var i;
var print = function() {
  console.log(i);
}

for(i = 0; i < 10; i++) {
  //print();
  setTimeout(print, 1000);
}

‘print()’ will work fine and prints 0-9
setTimeout will print 10 ten times, its because by the time setTimeout runs 10 different instances of the function, the value of ‘i’ is changed to 10 and then exited the loop.

Now HOW do we solve this problem???

var i;
for(i = 0; i < 10; i++) {
  (function() { // IIFE
    var currentValueOfI = i;
    setTimeout(function() { // make an inline function
      console.log(currentValueOfI);
    }, 1000);
  })();
}

// OR
var i;
for(i = 0; i < 10; i++) {
  (function(currentValueOfI) { // IIFE
    setTimeout(function() { // make an inline function
      console.log(currentValueOfI);
    }, 1000);
  })(i);
}

Compilation and Interpretation

To most of us it looks like JavaScript is an interpretor based language because we do see the direct source code in most of the web pages but it is actually not. JavaScript runtime engine compiles the source code into intermediate binary code on the fly and then interprets it.

Compilation Phase
The minute we create a function it actually creates an object behind the scenes and a variable by name function name binding to this object.

 
var a = 10;
function myFn(x) {
  var b = 20;
  var c = x;
  console.log(a+b+c);
}
myFn(30);

** If you notice carefully there are 5 variables (3 explicitly declared and 1 implicit myFn, 1 implicit param)
During compilation
line #1 // ‘a’ is put in global scope
line #2 // implicit var ‘myFn’ is put in global scope
line #2 // ‘x’ is put in myFn scope
line #3 // ‘b’ is put in myFn scope
line #4 // ‘c’ is put in myFn scope
Note that compilation phase does not look at RHS, it only looks at the LHS, i.e, declarations “var a”. Scope chains are created at compilation step.

Execution Phase
This phase ignores the declaration part and only looks at “a = 10” instead of “var a = 10”. It also refers to the scope chains created in compilation scope to find which variable to use where.
line #1 // Interpretor assigns var the value 10, similarly other variables at line 3 and 4
line #5 // It tries to search for ‘console’ var declaration in myFn scope, since its not declared, interpretor goes one level up and searches again (.. so on till it finds var console) and then invokes the log on it.

Global Scope Problem: Lets look at how interpretor interprets this code

var a = 10; // looks at 'a' from global scope from compilation step and assigns value 10
function myFn() {
  var b = a; // search for 'a' in myFn scope, its not declared, goes one level up to Global Scope and find it and uses it
  console.log(d); // search for 'd' in myFn scope, its not declared, goes one level up to Global Scope and still does not finds it and errors out. Note that it errors out because its a READ operation
  c = 100; // search for 'c' in myFn scope, its not declared, goes one level up to Global Scope and still does not finds it, instead of erroring out it creates variable 'c' because we are writing to it (NOT READING). Interesting thing is that, as the interpretor went up the scope levels all the way to Global Scope, it creates the variable in Global Scope itself eventhough this is the line responsible for the creation of this variable. Compiler skipped to identify the scope if the variable because it does not have the declaration with 'var'
}

Some surprising JS behaviors

var a = 10;
function outer() {
  var b = a;
  console.log(b);
  function inner() {
    var b = 20;
    var c = b;
    console.log(c);
  }
  inner();
}
outer();

This will have 3 scopes at compilation step and interpretor goes and resolves all variables from the compilation at the time of interpretation and runs the program. Its all good, lets see the same program with some minor modifications.

var a = 10;
function outer() {
  var b = a;
  console.log(b);
  function inner() {
    var c = b;
    console.log(c);
    var b = 20;
  }
  inner();
}
outer();

This will print ‘c’ as ‘undefined’ but NOT ’10’ as a typical programmer thinks. WHY???
#1 – The order of ‘var’ really does not matter in JS because compilation happens prior to interpretation.
#2 – There are two steps involved in every JS program, first step is compilation and the nest is interpretation. The problem here is that, compilation only looks at vars and interpretation does not look at vars at all.

At Interpretation phase
line #: When it looks at var ‘b’, it asks the ‘inner’ scope for this variable and its not initialized by the interpretor YET, its still available in ‘inner’ scope because its declared with var. And hence we are trying access a variable which is declared but not yet initialized, it gives us ‘undefined’. This is also referred to the problem of HOISTING

Problem of Hoisting
All the var declarations in JS code are moved/hoisted to the top in each of the execution scopes no matter where they are declared. Because of this reason we get ‘undefined’ as seen above. This is also the problem with function expressions (NOT WITH FUNCTION DECLARATION)

fnA();
function fnA() {
  console.log('hello')
}
Would run fine, BUT
fnA();
var fnA = function() {
  console.log('hello')
}

would give an error because the function expression is defined after execution command is invoked by the interpretor

Using strict mode
Its introduced in ECMA5 and this will not allow JS to initialize variables without declaring them.

"use strict"; // this should be the first line
var myName = "tekmarathon";
myname = "test"; // this will throw runtime error

Note: Strict mode can be applied to a function as well.

Reference
https://www.youtube.com/watch?v=9T3AIM3JMss&list=PLqq-6Pq4lTTZ_LyvzfrndUOkIvOF4y-_c&index=16
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

Scopes and Closures

Like in other programming languages, variable scope in JavaScript is not created by blocks, instead its created from functions.
Ex:
var x = 1;
if(x === 1) {
var y = 'one';
}
console.log(x);
console.log(y); // prints 'one' as the scope is not block based

For the most part, scopes in JS are created via functions
var x = 1;
function assignValue() {
if(x === 1) {
var y = 'one';
}
}
console.log(x);
console.log(y); // will throw runtime error

Note *** variables ‘x’ from outer scope can be used inside function but not vice versa as in case of ‘y’

Global variables in JS are evil especially from browser perspective because we load everything at once and we dont know if our global variable names are conflicting with others from different libraries. For this reason we put our logic in a function expression and invoke that function but again the problem could be same if some 3rd party library has same global function. Hence we go for IIFE – Immediately Invoked Function Expression
(function () {
var a = 10;
var b = 20;
console.log(a+b);
})();
With IIFEs global namespace is not polluted.

Without declaring and defining a variable, if we try to use it we get and error.
By declaring and without defining a variable we get ‘undefined’

If we declare a variable, we can do both read and write operations fine, but if dont declare a variable then we can do write operation alone (and not read operation)
var x;
x = 10; // write operation
console.log(x); // read operation

console.log(y); // leads to runtime error as we cannot read before declaring
z = 10; // is fine as we can write without declaring a variable

The Window Object
Whenever we declare a variable outside a function then that variable becomes global. All the global variables and functions are wrapped inside a GLOBAL/ROOT object. This global object name depends on which runtime we are using for running JS.
If its the browser then the Global Object name is ‘window’.
If its node, then its called ‘global’

Scopes can be hierarchical: Variables declared inside a function (INNER VARS) can access variables declared outside the function (OUTER VARS)

Introduction to Functions

Functions cannot be overloaded in JS: Function defined with n arguments can be passed with n args where extra args will be ignored.

function foo() {
return "Hello World";
}
foo();

Functions can be created as

  1. Function Expression
  2. Anonymous Function Expression
  3. Functions as arguments
  4. Functions on objects

1. Function Expression
Functions as values (FIRST CLASS CITIZENS)
var myFunc = function foo() {
return "Hello World";
}
myFunc();

2. Anonymous Function Expression
In the below expression function name is not required as we call with assigned variable anyways which is aka AFE
var myFunc = function() {
return "Hello World";
}
myFunc();

3. Functions as Arguments
var myFunc = function() {
return "Hello World";
}
var executorFunc = function(fn) {
fn();
}
executorFunc(myFunc);

4. Functions on Objects
var myObj = {
"prop1": true
}
myObj.myFunc = function() {
console.log("Hello World");
}
console.log(myObj);
myObj.myFunc();

Default Function Arguments
‘arguments’: is an indexed object with list of arguments passed to method
‘this’: Understanding ‘this’ keyword in JS
var person = {
"firstName": "Niranjan",
"lastName": "Tallapalli",
"getFullName": function() {
console.log(person.firstName + ' ' + person.lastName);
}
}

person.getFullName(); // would work fine BUT
// imagine this scenario
var person2 = person; // object address is copied
person = {};
person2.getFullName(); // this would have person reference which is empty hence results in “undefined undefined”
// instead refer to the object on which getFullName is invoked which is done via “this” keyword

Note: *** Functions are objects behind the scenes in JS ***

Array functions
myArr.push(element); // will add element at the end of an array
myArr.pop(); // will remove last element from array
myArr.shift(); // removes element from beginning of array
myArr.unshift(element); // push element at the beginning of array
myArr.forEach(function(item, index, arr) {
console.log(item +' '+index);
})

Arrays and Wrapper Objects in JavaScript

Arrays
Every array in JS behind the scenes is an Object which means array element can be accessed with index as an integer and also as a string
myArr[0] is same as myArr["0"]

As arrays are objects, can we use DOT NOTATION here? No because the property name is a number which is invalid identifier

If array is an object then how does myArray[0] works? Its because JS does Type Coercion behind the scenes and converts number to string.

Since array indexes are just property names in an object, we can assign element to any index, say

myArr[100] = "xyz";
*** myArr.length -> gives 101 because its actually not the length of an array rather its equal to (max_index + 1)
var myArr = ["hello", "how", "are"];
console.log(myArr.length);
myArr[20] = "you";
console.log(myArr.length);

If you try to access a index which is not defined then you get value ‘undefined’ rather than ArrayIndexOutOfBoundsException like in Java
var myArr = [100, 200];
console.log(myArr[0] +';'+ myArr[1] +';'+ myArr[2]);

Note: Additional elements in array can be added dynamically

Wrapper Objects in JS
By default when we create a variables, they are created as primitives but when we use DOT NOTATION on primitive, JS converts primitive into its corresponding wrapper object and performs the DOT OPERATION and then discards the object.
var value = "Hello World";
value.length; // here value primitive is converted into wrapper string object and then performs length
typeof value; // shows "string" which is a primitive

Similar wrappers are available for Number, Boolean and also Symbol(in ES6)

Variables in Javascript

Javascript is type inferenced which mean based on the value it will identify the type and hence we dont have to explicitly specify the type.

There are 3 primitive data types and undefined, null

  • Number: These are double precision 64 bit format (there are no Integers, Short, Float so on)
  • String: Sequqnces of Unicode Characters (no char type)
  • Boolean: It is of type ‘Boolean’ with two possible values ‘true/false’
  • undefined: It is of type ‘undefined’ with two possible values ‘undefined’. Value assigned to every declared variable until its defined.
    • Ex var value; value = 10; //value between these two statements is value ‘undefined’ of type ‘undefined’
  • null: It is of type ‘null’ with two possible values ‘null’.
  • In ECMA6, new variable called Symbol is introduced just like ENUMs

Note: There is no scoping information attached to variable declarations and hence all declared variables are by default global.

Variables and Values can be interrogated using ‘typeof’

typeof <variable>
typeof <value>
var a;
console.log(typeof a);
a = 10;
console.log(typeof a);
a = "hello";
console.log(typeof a);
a = true;
console.log(typeof a);
a = null;
console.log(typeof a);

Null is a typeof Object
* a=null; typeof a – returns object instead of null, it was a bug in early versions of JS but its not fixed in newer versions bcos it breaks backward compatibility and many web applications will break.

Type Coercion: As JS was introduced to be friendly  language with developers and they did type conversion of variables used in the expression and this lead to many confusions and later they fixed it but because of backward compatibility we still live with them. One such issue is ‘==’

  • double equals == and triple equals ===
  • 12 + “4” -> results in “124” because it looks at expression and finds one is string and other is number and hence coerce number into string so that it can do string concatenation
    * JS does a lot of type coercion and hence the behavior is unpredictable lot of times, beware of it
var a = 10;
var b = "10";
a == b -> returns true, whereas
a === b -> returns false

Values of all types have associated boolean value

  • Non zero numbers can be passed to a if loop which returns true
  • Non empty strings can be passed to a if loop which returns true
  • undefined and null are always false
var a = 10;
if(a) {
console.log("a is true");
} else {
console.log("a is false");
}

a = 0;
if(a) {
console.log("a is true");
} else {
console.log("a is false");
}

a = "Hello";
if(a) {
console.log("a is true");
} else {
console.log("a is false");
}

a = "";
if(a) {
console.log("a is true");
} else {
console.log("a is false");
}

Objects in Javascript

Objects in Javascript are free form which means that we can add/remove fields and methods whenever we want. They are not bound to a particular class (like in Java, in fact there is no class concept in JS).

Easiest way to create a object is object inline like – “var obj = {};” Objects can also be created via object literal

 
// create object inline
var myObj = {}; 
// FREE FORM: dynamically attach property to the above object
myObj.prop1 = "Hello"; 
console.log(myObj);
// Prints the above attached property
console.log(myObj1.prop1); 
// If we try to access the property which is not declared in object, we get it as 'undefined'
console.log(myObj1.prop2); 
delete myObj1.prop1; // FREE FORM: delete property from an Object

Properties and Access Specifiers
All properties within object are public as they dont come with any access specifier. Properties of an object can be accessed in 2 ways
– Using dot notation
– Using square brackets
When to use dot notation vs square brackets?

  • Use [] notation
    • when property is a reserved keyword or invalid identifier
    • when property name is dynamic
    •  var myObj1 = {
      "prop1": "Hello",
      "prop2": 10,
      "1": "one"
      }
      console.log(myObj1.1); // will result in error
      var propertyName = "prop2";
      console.log(myObj1.propertyName);
      
  • Prefer DOT NOTATION over [] NOTATION because JS Engine can do some optimizations upfront with DOT NOTATION. And DOT NOTATION is also faster compared to [] approach.

Two objects can be compared with ‘===’ operator
var myObj2 = myObj1;
(myObj1 === myObj2) -> returns true

Objects with undefined and null
If we dont define a property then its gonna be undefined, but if we wanna define a property with empty value then we initialize it with null value.

Introduction to javascript

Javascript is created in early 90s by Brendan Eich at Netscape and is later introduced as a standard specification by ECMA committee. Current version supported by most browsers is ECMA5 and newly released version is ECMA 2015 aka ECMA6

Javascript is a lightweight, interpreted or JIT compiled programming language with first class functions.
It is a prototype based, multi-paradigm, dynamic language, scripting language, supporting object oriented, imperative, declarative and functional programming styles. There are lot of buzz words, and we will see each one of them

  • Lightweight: It has very less foot print in the machine that its running
  • Interpreted: We do not explicitly compile JS programs (like we do in JAVA, instead its compiled on the go)
  • First Class Functions: Functions are first class citizens in JS which means
    • we can assign functions to variables
    • we can pass functions as method params
    • we can return a function as a return type from a method
  • Multi Paradigm: It can support all programming paradigms
  • Object Oriented: model state and behavior around objects to do sth
  • Imperative: step by step instructions on HOW TO DO sth (like C)
  • Declarative: we tell WHAT TO DO rather than HOW TO DO (like scala)
  • Functional: subset of declarative language style (scala)
  • Dynamic Language: Method binding to a object is done at runtime rather than at the compile time and during compilation time, compiler wont report (for example, like Java does)
  • Scripting Language: Instructions written to execute on runtime environment (like unix scripting enables with the deployment of web applications), JS is used with modifying DOM structure at the browser runtime.

Why so many programmers are not comfortable with JS by tagging it as a front end technology?
– Its because of the above traits of the language.
– Because of backward compatibility lot of bugs remained as bugs forever in JS (like == vs === , null typeof object, so on)
– Initially when it was introduced, it was meant to be friendly language and the hence it internally did lot of type coercions

Why learn JS? With NodsJS, Javascript evolved a lot and now it is being used widely across different layers

  • Client side web development
    • Native JS
    • JQuery
    • Angular, React
  • Server side
    • NodeJS
    • Express
    • Browser Extensions
      so on..

Javascript runtime is usually a browser but as we learn this we can either use nodejs or mozilla firefox’s scratchpad to write and execute JS programs.

References:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
https://www.youtube.com/user/koushks

Java8 Streams

Streams are functional programming design pattern for processing of elements of a data structure sequentially or parallely.

Example:

 
List<Order> orders = getOrders();
int qtySum = orders.stream()
                .filter(o -> o.getType().equals("ONLINE"))
                .mapToInt(o -> o.getQuantity())
                .sum();

Above code can be explained as below:

  • Create a stream from source java collection
  • Add a filter operation to the stream “intermediate operations pipeline”
  • Add a map operation to the stream “intermediate operations pipeline”
  • Add a terminal operation that kicks off the stream processing

A Stream has

  • Source: that stream can pull objects from
  • Pipeline: of operations that can execute on the elements of the stream
  • Terminal: operation that pull values down the stream

Streams are lazily evaluated and the stream lifecycle is

  • Creation: from source
  • Configuration: from collection of pipeline operations
  • Execution: (terminal operation is invoked)
  • Cleanup

Few java stream sources

 
// Number Stream
LongStream.range(0, 5).forEach(System.out::println)

// Collection Streams
List<String> cities = Arrays.asList("nyc", "edison", "livingston");
cities.stream().forEach(System.out::println)

// Character Srream
int cnt = "ABC".chars().count()

// File Streams
Path filePath = new Path("/user/ntallapa/test");
Files.list(filePath).forEach(System.out::println);

Stream Terminal Operations

  • Reduction Terminal Operations: results in single result
    • reduce(f(x)), sum(f(x)), min(f(x)), max(f(x)), etc
  • Mutable Reduction Terminal Operations: returns multiple results in a container data structure
    • List integers = Arrays.asList(1,2,3,3);
    • Set integersSet = integers.stream().collect(Collectors.toSet()); // returns 1,2,3
  • Search Terminal Operations: returns result as soon as match is found
    • findFirst(), findAny(), anyMatch(f(x))
  • Generic Terminal Operations: do any kind of processing on every element

Stream Pipeline Rule: Since streams are meant to process elements sequentially/parallely, stream source is not allowed to modify

Intermediate Pipeline operations can be of two types

  • Stateless: filter(f(x)), summaryStatistics()
  • Statefull: distinct(), limit(n), skip(n)

References:
https://www.youtube.com/watch?v=MLksirK9nnE
https://www.youtube.com/watch?v=8pDm_kH4YKY

Java8 Lambdas

Lambdas enable functional programming in Java. Concept of Lambda is available in many languages but the beauty of it in Java is its BACKWARD COMPATIBILITY. In this post we will discuss below areas

  • Concept
  • Syntax
  • Functional Interfaces
  • Variable Capture
  • Method References
  • Default Methods

Concept


Lambda can be defined as

  • a way of defining anonymous functions
  • It can be passed to variables
  • It can be passed to functions
  • Can be returned from functions

What are lambda good for?

  • These are the base for functional programming model
  • Makes parallel programming easier: If we want to make 100s of cores busy then its easier to do with functional programming than that of the object oriented programming
  • Write compact code (Hadoop1 in Java: 200k lines of code VS Spark1 in Scala: 25k Lines of Code)
  • Richer Data Structure Collections
  • Develop Cleaner APIs

Syntax

 
List<Integer> integers = Arrays.asList(1,2,3);
integers.forEach(x -> System.out.println(x));
OR
integers.forEach((x) -> {
    x = x+10;
    System.out.println(x);
});
OR
integers.forEach((Integer x) -> {
    x = x+10;
    System.out.println(x);
});

We can explicitly mention types, but Java8 compiler is able to do Type Inference

Lambda Expression in Java (from video: A Peek Under the Hood by Brian) is converted into a Function and then we call the generated function

Functional Interfaces (FI)


An interface with just one method (one NON-DEFAULT Method) is called a Functional Interface.

Prior to Java8 we use to write the function with signature, open a curly brace and then write body of the function and close it but In Java8:

 
// define FI
@FunctionalInterface 
    // enforces that the interface is FI (it fails compilation if below interface has more than one method)
    // Its optional and can be applied only to interfaces
public interface Consumer<T> {
    void accept(T t);
}

// give the definition
Consumer<Integer> consumer = x -> System.out.println(x);

// use it
List<Integer> integers = Arrays.asList(1,2,3);
integers.forEach(consumer);

Few things to notice here:

  • Here we are separating the body of the function (Line #10) from its signature(Line #6).
  • The method generated from lambda expression must have same signature as that of the FI(see Line#67: lambda takes one arg ‘x’, throws no Exception and returns nothing)
  • In Java8, the type of the lambda expression is same as that of the FI that lambda is assigned to. (see Line#67)

Variable Capture (VC)


Lambdas can interact with variables (local, instance and static) defined outside the body of lambda (aka VC).

 
List<Integer> integers = Arrays.asList(1,2,3);
int vc=10;
integers.forEach(x -> System.out.println(x+vc));

Note: Local variables accessed and used inside the Lambda are final and cannot be modified.

Lambda vs Anonymous Inner Classes

  • Inner classes can have state in the form of class level instance variables whereas lambdas cannot.
  • Inner Classes can have multiple methods whereas Lambda’s cannot
  • ‘this’ points to the object instance of anonymous inner class whereas it points to the enclosing object for lambda

java.util.function.* contains 43 most commonly used functional interfaces

  • Consumer: functions which takes argument of type T and returns void
  • Supplier: functions that takes no argument and returns a result of type T
  • Predicate: functions which takes argument of type T and returns boolean
  • Function<T, R>: function that takes an argument of type T and returns a result of type R

Method References (MRs)


As lambda being a way to define anonymous function, there is a good chance that the function we want to use exists already. In these cases, MRs can be used to pass an existing function in place where lambda is expected

 
@FunctionalInterface 
public interface Consumer<T> {
    void accept(T t);
}

public void doSomething(Integer x) {
    System.out.println(x);
}

Consumer<Integer> cons1 = x -> doSomething(x);
cons1.accept(1);
// Reuse with MR
Consumer<Integer> cons2 = Example::doSomething;
cons2.accept(2);

Note: The signature of the referenced method must match the signature of FI method.

By looking at above definition it is obvious that MR works on method with only one argument and no return type

Referencing a Constructor: Constructor method references are quite handy while working with Streams

 
// Create a new function which has a method that takes 'String' as parameter (LHS to arrow), returns 'Integer' (RHS to arrow as body of method)
Function<String, Integer> mapper1 = x -> new Integer(x);
System.out.println(mapper1.apply("11"));

// Refer a Cons
Function<String, Integer> mapper2 = x -> Integer::new;
System.out.println(mapper2.apply("22"));

References to a specific object instance method:

 
Consumer<Integer> cons1 = x -> doSomething(x);
cons1.accept(1);
// can also be written as: this invokes the println() method on System.out object by passing param '2'
Consumer<Integer> cons2 = System.out::println;
cons2.accept(2);

Default Methods ***


This is very important feature because it addresses Interface Evolution Problem: How a published interface (like List, Iterable, etc) can be evolved without breaking existing implementations (backward compatible)

Default Method: A default method on a java interface has an implementation provided in the interface and is inherited by the classes that implements it.

 
public Iterable<T> { 
    Iterator<T> iterator;
    
    default void forEach(Consumer<? super T> action) {
        for(T t: this) {
            action.accept(t);
        }
    }
}

References:
https://www.youtube.com/watch?v=MLksirK9nnE
https://www.youtube.com/watch?v=8pDm_kH4YKY

Mawazo

Mostly technology with occasional sprinkling of other random thoughts

amintabar

Amir Amintabar's personal page

101 Books

Reading my way through Time Magazine's 100 Greatest Novels since 1923 (plus Ulysses)

Seek, Plunnge and more...

My words, my world...

ARRM Foundation

Do not wait for leaders; do it alone, person to person - Mother Teresa

Executive Management

An unexamined life is not worth living – Socrates

Diabolical or Smart

Nitwit, Blubber, Oddment, Tweak !!

javaproffesionals

A topnotch WordPress.com site

thehandwritinganalyst

Just another WordPress.com site

coding algorithms

"An approximate answer to the right problem is worth a good deal more than an exact answer to an approximate problem." -- John Tukey