notes java 8
notes java 8
===============
==================================================
Introduction to java 8, Why i should care for it?
===================================================
Java 8: why should you care? NOW
----------------------------------
As commodity CPUs have become multicore, Difficult to take advantage with traditional
threads programming
Java 5 added building blocks like thread pools and concurrent collections
Java 7 added the fork/join framework, making parallelism more practical but still difficult
Why Java 8?
==========
more concise code and simpler use of multicore processors
==================================================================================
functional interface
==================================================================================
Funcational Interface?
----------------------
=> Java 8 introduces a new FunctionalInterface annotation type that lets you annotate an interface as being
functional.
For example:
------------
@FunctionalInterface
public interface Runnable
{
public abstract void run();
}
Java DNA
----------
Structured ==> Reflective=> Object Oriented =>Functional => Imperative=>Concurrent => Generic
How vs. What Methods describe how Pure functions describe what
things are done. is done rather than how it is done
Invocation Methods are used imperatively Pure functions are used declaratively
Order order of invocation matters.
Code vs. Data MCollections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return 0;
}
});
ethods are code , i.e., Functions are code-as-data
they are invoked and executed they are not only executable,
but are also passed around like data.
Interface evaluation
===============
=> Problem with java interface?
if we need to change the interface ( ie add new method prototype) the all the
class herarchy is get effected!
=> Java 8 solve these issues by supporting default implementation and static method
to interface
=> Default methods offer greater flexibility because you can implement an interface
at any point in the class hierarchy and access the interface's default methods
from the implementing classes.
Also, it's no longer necessary to create adapter classes for
multi-method event listener interfaces. Instead, you can add a default method for
each listener method to the event listener interface and
override these methods as necessary
Note:
----------------------------------------------------
We cannot use default methods to override any of the non-final methods in the java.lang.Object class
For example:
----------
the java.util.Comparator interface defines the following static method:
Note:
When you implement an interface that contains a static method, the static method is still part of the interface
and not part of the implementing class.
For this reason, you cannot prefix the method with the class name.
Instead, you must prefix the method with the interface name
interface X
{
static void foo()
{
System.out.println("foo");
}
}
class Y implements X
{
}
public class Z
{
public static void main(String[] args)
{
X.foo();
// Y.foo(); // won't compile
}
}
// Expression Y.foo() will not compile because foo() is a static member
// of interface X and not a static member of class Y
==================================================================================
Lambda Expressions
==================================================================================
Lambda Expressions and Functional Interfaces
==================================
f(x)=3x+4
functional programming = immutability+ thread safe + dist programming?
Lambda expression
------------------------
What is lambda expression?
-----------------------------
5. cloure
Example:
Example:
interface Operation {
int apply(int a, int b);
}
class Logic {
public static int operation(int a, int b, Operation operation) {
return operation.apply(a, b);
}
}
Note:
---------------------------------------------
Give me details of all hidden file in a dir
--------------------------------------------
2. Runtime Overhead:
-------------------------
lambda expressions have the potential for optimizations
and reduced runtime overhead compared to anonymous inner classes
3. Variable Binding
-----------------------
variable capture: an inner class has access to all final variables of its enclosing context
void method() {
final int cnt = 16;
Runnable r = new Runnable() {
public void run() {
System.out.println("count: " + cnt );
}
};
Thread t = new Thread(r);
t.start();
cnt ++; // error: cnt is final
}
Difference:
--------------------
ariables from the enclosing context that are used inside a
lambda expression are implicitly final (or effectively final )
==================================================================================
Passing code with behavior parameterization
==================================================================================
=> this programming technique is shorter, clearer, and less error prone than the common
tendency to use copy and paste
=> Experts will here note that behavior parameterization could, prior to Java 8,
be encoded using anonymous classes
Funcational programming?
-------------------------
Behavior parameterization
The Java 8 feature of passing code to methods (and also being able to return it and
incorporate it into data structures) also provides access to a whole range of additional
techniques that are commonly referred to as functional-style programming.
1. green in color
2. having weight more then 150 gm
Attempt 1:
-----------
public class Apple {
private String color;
private int weight;
//getter setter ctr etc
}
Attempt 2;
-------------
=> Java 8 makes it possible to pass the code of the condition as an argument,
thus avoiding code duplication of the filter method
interface Predicate<T>{
boolean test(T t);
}
Problem:
-------------
How to pass predicate?
@Override
public boolean test(Apple t) {
return t.getColor().equals("green");
}
});
===========================================
Steam in Java 8 an introduction
===========================================
=> you express a query rather than code an ad hoc implementation for it
=> For now you can think of them as fancy iterators over a collection of data.
Why Streams?
=> The first design motivator is that there are many data processing patterns
(similar to filterApples in the previous section, or operations familiar from database
query languages such as SQL) that occur over and over again and that would benefit
from forming part of a library: filtering data based on a criterion (for example, heavy
apples), extracting data (for example, extracting the weight field from each apple in a
list), or grouping data (for example, grouping a list of numbers into separate lists of
even and odd numbers), and so on.
=> The second motivator is that such operations can often be parallelized.
-----------------------------------------------------------------------------------
collection Streams
internal iteration vs External iteration
--------------------------------------------------------------------------------------
We have to maintain iteration We don't have to manage iteration.
logic using iterator/for loop Liberary is doing it for us
Example:Sequential processing:
---------------------
List<Apple>heavyApples=list.stream().filter((Apple a)-> a.getWeight()>150).
collect(Collectors.toList());
Parallel processing:
-----------------------
List<Apple> heavyApples =inventory.parallelStream()........;
==================================================================================
functional interfaces defined in Java 8
==================================================================================
//...
}
Example:filter
------------
Predicate<Integer>even=x->x%2==0;
List<Integer>evens2=list.stream().filter(x->x%2==0).collect(Collectors.toList());
Consumer<T>
============
=> consumer interface defines an abstract method named accept that
takes an object of generic type T and returns no result (void).
=> You might use this interface when you need to access an object of type T and
perform some operations on it.
=> For example, you can use it to create a method forEach, which takes a list of Integers
and applies an operation on each element of that list.
@FunctionalInterface
public interface Consumer<T>{
void accept(T t);
}
for(T i:list){
c.accept(i);
}
}
Function<T,R>
==============
Mapping process: Accept object of one type map it to another type
---------
Collectors
---------------
List<String>letter=Arrays.asList("a","b","c","d");
String concat="";
for(String temp:letter)
concat+=temp;
//java 8
String concat2=letter.stream().collect(Collectors.joining());
======================================
Working with streams introduction
======================================
Consider:
public class Dish {
private String name;
private boolean vegetarian;
private int calories;
public enum Type { MEAT, FISH, OTHER }
private Type type;
}
Example: return the names of dishes that are low in calories (<400),
sorted by number of calories
Pre java 8 way:
------------------
List<Dish> lowCaloricDishes = new ArrayList<>();
for(Dish d: menu){
if(d.getCalories() < 400){
lowCaloricDishes.add(d);
}
}
Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
public int compare(Dish d1, Dish d2){
return Integer.compare(d1.getCalories(), d2.getCalories());
}
});
To exploit a multicore architecture and execute this code in parallel, you need only
change stream() to parallelStream():
------------------------------------------------
But streams are about expressing computations such as filter, sorted, and map
that you saw earlier.
=> Source
----------
Streams consume from a data-providing source such as collections,
arrays, or I/O resources.
terminal operations
--------------------
=> collect causes the pipeline to be executed and closes it.
Ref: diagram 1
=>This allows the operations to be connected to form a query. What\92s important is that intermediate
operations don\92t perform any processing until a terminal operation is invoked on the stream
pipeline they re lazy.
To understand whats happening in the stream pipeline, modify the code so each lambda also
prints the current dish its processing (like many demonstration and debugging techniques, this
is appalling programming style for production code but directly explains the order of evaluation
when you are learning....
})
.map(d->{
Sysout("mapping:"+d.getName());
return d.getName();
})
.limit(3)
.collect(toList());
Second, despite the fact that filter and map are two separate operations,
they were merged into the same pass (we call this technique loop fusion).
====================
streams in detail
====================
What we are going to cover in this session:
------------------------------------------------------
=> Filtering, slicing, and matching
=> Finding, matching, and reducing
=> Using numeric streams such as ranges of numbers
=> Creating streams from multiple sources
=> Infinite streams
Filtering
=========
Ex:Getting all veg dishes
---------------------------
List<Dish>vegDishes=menu.stream().filter(Dish::isVegitable).collect(Collector.toList());
gettingBars.forEach(x-> System.out.println(x));
}
}
Truncating a stream
====================
=> Streams support the limit(n) method, which returns another
stream thats no longer than a given size.
=> The requested size is passed as argument to limit. If the stream is ordered,
the first elements are returned up to a maximum of n.
Ex: create a List by selecting the first three dishes that have more than 300 calories as follows:
flatMap
=========
Ex: return a list of all the unique characters for a list of words?
For example, given the list of words ["Hello", "World"]
we like to return the list ["H", "e", "l", "o","W", "r", "d"]
How to do it?
List<String> list=Arrays.asList("foo","bar","jar");
List<String>chars=
list.stream()
.map(s->s.split(" "))
.distinct()
.distinct()
.collect(Collectors.toList());
=> However, if you had a Stream<List<Integer>> then it would make sense and you could do this:
O/P: print 1 to 5
allMatch,
anyMatch,
noneMatch,
findFirst,
findAny
anyMatch
=========
=> method can be used to answer the question
Is there an element in the stream matching the given predicate?
For example, you can use it to find out whether the menu has a vegetarian option:
if(menu.stream().anyMatch(Dish::isVegetarian)){
System.out.println("The menu is (somewhat) vegetarian friendly!!");
}
allMatch
========
Checking to see if a predicate matches all elements
For example, you can use it to find out whether the menu ishealthy
(ie. all dishes are below 1000 calories):
noneMatch
========
opposite of allMatch
boolean isHealthy = menu.stream().noneMatch(d -> d.getCalories() >= 1000);
NullPE?
########
=> pain for developer
=> Tony Hoare 1965
=> Null References: The Billion Dollar Mistake
https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare
findAny
=======
The findAny method returns an arbitrary element of the current stream
Optional<Dish> dish =menu.stream()
.filter(Dish::isVegetarian)
.findAny();
AVOID NULLPOINTEREXCEPTION
========================
=> The Optional<T> class (java.util.Optional) is a container class
to represent the existence or absence of a value.
=> In the previous code, its possible that findAny doesnt find any element.
=> Our code can benefit from using Optional to avoid bugs related to null checking.
=> T get()
returns the value if present; otherwise
it throws a NoSuchElement-Exception
Ex: menu.stream()
.filter(Dish::isVegetarian)
.findAny().ifPresent(d->sysout(d.getName()));
findFirst
==========
Finding the first element
int sum = 0;
for (int x : numbers) {
sum += x;
}
=> The reduce operation can't return a sum because it doesn\92t have an initial value.
=> In that case result would be wrapped in an Optional object to indicate
that the sum may be absent.
Or better use build in method count() on stream object: long count = menu.stream().count();
=> You now process the OptionalInt explicitly to define a default value if theres no maximum
int max=maxCalories.orElse(1);
Numeric ranges
===============
=> A common use case when dealing with numbers is working with ranges of numeric values.
=> Java 8 introduces two static methods available on IntStream and LongStream to help
generate such ranges:
Building streams
================
3 Ways:
1> Streams from values
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
=============================
Optional
=============================
Optional : better alternative to null (NPE)
problem started in 1965:
------------------------
Tony Hoare introduced null references back in 1965
while designing ALGOL (billion-dollar mistake)
Problem?
-----------
class Insurance{
private String companyName;
class Car{
private Insurance insurance;
class Person{
private Car car;
Java 8:
------
Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
Optional<String> name = optInsurance.map(Insurance::getName);
What it does?
----------------
=> The map operation applies the provided function to each element of a stream.
=> If the Optional contains a value, then the function passed as argument to map
transforms that value.
So what to do with
-------------------
public String getCarInsuranceName(Person person) {
return person.getCar().getInsurance().getName();
}
Attempt 1:
------------
Optional<Person> optPerson = Optional.of(person);
Optional<String> name =optPerson.map(Person::getCar).map(Car::getInsurance).map(Insurance::getName);
Will not work
------------
-> The variable optPeople is of type Optional<People>, so it\92s perfectly fine to call
the map method.
-> This means the result of the map operation is an object of type Optional<Optional<Car>>
p.setCar(carOpt);
c.setInsurance(icOpt);
System.out.println(getInsureanceCompany(pOpt));
}
return p.flatMap
(per -> per.getCar()).flatMap(c -> c.getInsurance()).map(i -> i.getCompanyName()).orElse("not
found");
}
http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html
============================
Collecting data with streams
=============================
What is collect operation?
----------------------
=>collect is a reduction operation
=> just like reduce, that takes as argument various recipes for accumulating
the elements of a stream into a summary result
Consider:
=========
enum CaloricLevel { DIET, NORMAL, FAT };
class Dish {
private final String name;
private final boolean vegetarian;
private final int calories;
private final Type type;
Data initilizaton:
----------------
Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT),
new Dish("beef", false, 700, Dish.Type.MEAT),
new Dish("chicken", false, 400, Dish.Type.MEAT),
new Dish("french fries", true, 530, Dish.Type.OTHER),
new Dish("rice", true, 350, Dish.Type.OTHER),
new Dish("season fruit", true, 120, Dish.Type.OTHER),
new Dish("pizza", true, 550, Dish.Type.OTHER),
new Dish("prawns", false, 400, Dish.Type.FISH),
new Dish("salmon", false, 450, Dish.Type.FISH));
===========================
Book Application case study
============================
Domain model:
enum Subject{
JAVA, DOT_NET, ORACLE;
}
class Author {
private String name;
private String lastname;
private String country;
}
class Book {
private String title;
private List<Author> authors;
private int pages;
private Subject subject;
private int year;
private String isbn;
}
Sample data:
-----------------
Author author1=new Author("kathy", "seria", "uk");
Author author2=new Author("abc", "abc", "us");
Problems:
--------
// Find all books that are java books and more then 400 pages
----------------------------------------------------------------
// We want to know if all the books are written by more than one author
--------------------------------------------------------------------------
boolean isAllBooksWrittenBy2Author = books.stream().
allMatch(b -> b.getAuthors().size() > 1);
We want to partition book by hard cover and non hard cover books.
-----------------------------------------------------------------
Map<Boolean, List<Book>>hardCoverBooks=books.stream()
.collect(Collectors.partitioningBy(Book::hasHardCover));
====================================
Refactoring, testing, and debugging
====================================
Refactoring steps:
--------------------
1. Refactoring anonymous classes to lambda expressions
2. Refactoring lambda expressions to method references
3. Refactoring imperative-style data processing to streams
Refactoring: Example
------------------------
//Dishes grouped by caloric level
------------------------------------
private static Map<CaloricLevel, List<Dish>> dishesAsPerCalaroficValue(List<Dish> allDishes){
return allDishes.stream().collect(
Collectors.groupingBy(dish -> {
if (dish.getCalories() <= 400) return CaloricLevel.DIET;
else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT;
} ));
}
}
Refactoring:
------------
=> Extract lambda expression in seperate method in Dish class
public class Dish{
...
public CaloricLevel getCaloricLevel(){
if (this.getCalories() <= 400) return CaloricLevel.DIET;
else if (this.getCalories() <= 700) return CaloricLevel.NORMAL;
else return CaloricLevel.FAT;
}
}
debugging
-------------
Stack trace, logging
Stack trace not be that useful
as lambda expression dont have name :(
What happens ?
-----------------
List<Point> points = Arrays.asList(new Point(12, 2), null);
points.stream().map(p -> p.getX()).forEach(System.out::println);
Logging information
--------------------
Want to know what is going on? peek() method
List<Integer> result = Stream.of(2, 3, 4, 5)
.peek(x -> System.out.println("taking from stream: " + x))
.map(x -> x + 17)
.peek(x -> System.out.println("after map: " + x))
.filter(x -> x % 2 == 0)
.peek(x -> System.out.println("after filter: " + x))
.limit(3)
.peek(x -> System.out.println("after limit: " + x))
.collect(toList());
=================================
Design pattern with java 8
==================================
iterator, strategy, execute around method...
@Override
public void finalize() throws Throwable {
System.out.println("finilized is called....");
}
}
In main
---------
Resource r=new Resource();
r.op1();
r.op2();
@Override
public void close() {
System.out.println("clean the resource ....");
}
main:
-----------
try (Resource r = new Resource()) {
r.op1();
r.op2();
}
Final code:
-----------
class Resource {
private Resource() {
System.out.println("resource is created.....");
}
}
public class ExecuteAroundPattern {
public static void main(String[] args) {
Resource.use(resource -> resource.op1().op2());
}
https://www.mkyong.com/java8/java-8-stream-read-a-file-line-by-line/
http://winterbe.com/blog/
=========================
fork and join example, issues
========================
Fork-Join Framework (Java 7 Stuff)
===================================
What is fork join?
------------------
=> The framework is an implementation of the ExecutorService interface and
provides an easy-to-use concurrent platform in order to exploit multiple processors.
ForkJoinTask:
=> lightweight thread-like entity representing a task that defines
methods such as fork() and join().
RecursiveTask
=> task that can run in a ForkJoinPool
=> its compute() do computation with returning an result of type V
RecursiveAction
=> is a task that can run in a ForkJoinPool
=> its compute() do computation without returning an result
ForkJoinTask
|
________________
| |
RecursiveTask RecursiveAction
Algo:
====
doRecursiveTask(input) {
else {
divide (i.e., fork) the task into two parts
call compute() on first task, join() on second task, return combined results
}
}
When to go for FJ framework?
----------------------------
=> FJ framework is suitable if problem fits this description:
2. The subdivided tasks are independent and can be computed separately without
the need for communication between the tasks when computation is in process
(Of course, after the computation is over, you will need to join them together)
How to code?
---------------
Steps:
1. Define a task class that extends either RecursiveTask or RecursiveAction
If (a task returns a result )
extend from RecursiveTask
otherwise
extend from RecursiveAction
3. The compute() method actually performs the task if the task is small enough to be executed; or
splits the task into subtasks and invoke them.
Hello world ?
-------------
Now lets try solving the problem of how to sum 1..N where N is a large number
class SumOfNUsingForkJoin {
private static long N = 1000_000; // one million - we want to compute sum
private static final int NUM_THREADS = 10;
static class RecursiveSumOfN extends RecursiveTask<Long> {
long from, to;
public RecursiveSumOfN(long from, long to) {
this.from = from;
this.to = to;
}
public Long compute() {
if ((to - from) <= N / NUM_THREADS) {
} else {
// no, the range is too big for a thread to handle, so fork the computation
// we find the mid-point value in the range from..to
// determine the computation for second half with the range mid+1..to
// now, wait for the first half of computing sum to complete, once done, add it to the
remaining part
System.out.println("processor: "+Runtime.getRuntime().availableProcessors());
======================
Basics of Parallle strams
=======================
Basics of Parallle strams
---------------------------
What is streams?
-----------------
-> A stream is not a collection, sequence stream of objects
-> A stream is a abstraction that represent zero or more "values"
-> not (necessarily) a collection: values might not be sorted anywhere
-> not (necessarily) a sequence; order might not matter
-> values, not object; avoid mutation and side effects
Processing Pipeline?
------------------------
A pipeline consist of :
-> a steram source
-> zero or more intermediate results
-> a terminal operation
colllections.stream() //source
.filter(...) //intermediate
.map(...) //intermediate
.collect(...) //terminal opeation
Parallel steams?
-------------------
=> Source starts with steam(), parallelStream() or other stream factory
colllections.stream() //source
.filter(...) //intermediate
.parallel()
.map(...) //intermediate
.sequential()
.collect(...) //terminal opeation
paralled execution:
--------------------
Note:
=> When we call the stream() method of the Collection class,
we will get a sequential stream. When you call parallelStream()
method of the Collection class, you will get a parallel stream.
=> isParallel()
check if the stream is sequential or
parallel by calling the isParallel() method
Example:
class StringConcatenator {
public static String result = "";
Serial execution:
String words[] = "the quick brown fox jumps over the lazy dog".split(" ");
Arrays.stream(words).forEach(StringConcatenator::concatStr);
System.out.println(StringConcatenator.result);
parallel execution:
Arrays.stream(words).parallel().forEach(StringConcatenator::concatStr);
Problem?
--------
=> When the stream is parallel, the task is split into multiple
sub-tasks and different threads execute it.
Solution:
---------
=> get rid of modifying the global state and keep the
reduction localized
=> We can use the reduce() method
Correct way:
-----------
String words[] = "the quick brown fox jumps over the lazy dog".split(" ");
System.out.println(originalString.get());
or
List<String> list=IntStream
.rangeClosed(0, 50)
.filter(i-> i%5==0)
.mapToObj(i-> String.valueOf(i/5))
.collect(Collectors.toList());
System.out.println(list);
List<String> list=IntStream
.rangeClosed(0, 50)
.filter(i-> i%5==0)
.mapToObj(i-> String.valueOf(i/5))
.collect(Collectors.toList());
System.out.println(list);
encounter order vs procesing order:
--------------------------------------
ORDER IS MAINTAINED IN O/P..... HOW TO PROVE.. use peek()
List<String>peek=new ArrayList<String>();
List<String> list=IntStream
.range(0, 50)
.parallel()
.filter(i-> i%5==0)
.mapToObj(i-> String.valueOf(i/5))
.peek(s->peek.add(s))//multiple thread adding to list!
.collect(Collectors.toList());
System.out.println(list);
System.out.println("-----processing -------------");
System.out.println(peek);
ArrayIndexOutOfBoundException:
non thread ds added and manipulated ..so missing info, null etc
Note: order in which data is processed in paralled stream (by multiple threads )can not predictable ....
O/P: resembly of result is not based on processing order but on postion ...(encounter order)
Accumulation vs Reduction
------------------------------------------
Let consider adding numbers from 1 to 1_000_000
long sum=0;
for(long i=0;i<=1_000_000;i++){
sum=sum+i;
}
System.out.println(sum);
O/P: 500000500000
LongStream.rangeClosed(1, 1_000_000).forEach(i->sum[0]+=i);
System.out.println(sum[0]);
Why array?
System.out.println(sum);
What is the problem with Accumulation ?
------------------------------------------------
If we are using an variable like sum for accumulation, all threads accessing it to change it.....
to much memory trafic to that variable.....too slow
System.out.println(sum);
System.out.println(sum);
Identity: demo
------------------
Consider:
static List<String> strings =
Arrays.asList("one", "two", "three","four",
"five", "six", "seven", "eight", "nine", "ten");
......
System.out.println(strings.stream().map(s-> "{"+s+"}").reduce("", (s1, s2)-> s1+s2));
xxxx{one}xxxx{two}xxxx{three}xxxx{four}xxxx{five}xxxx{six}xxxx{seven}xxxx{eight}xxxx{nine}xxxx{ten}
(Result may vary..wrong result)
Using stringbuilder?
---------------------
System.out.println(strings.stream()
.map(string -> new StringBuilder("{" + string + "}"))
.reduce(new StringBuilder(), (s1, s2) -> s1.append(s2)));
Run in parallel
---------------
System.out.println(strings.stream()
.map(string -> new StringBuilder("{" + string + "}"))
.parallel()
.reduce(new StringBuilder(), (s1, s2) -> s1.append(s2)));
Demo: associativity
---------------------
Consider :
static List<String> strings = Arrays.asList("a", "b", "c", "d",
"e", "f", "g", "h", "i", "j");
System.out.println(strings.stream().reduce("", (x,y)->x+y));
Correct associativity: correct output....
Sequential association
---------------------
Incorrect associativity: predictable wrong ans
System.out.println(strings.stream().reduce("", (x,y)->x+y));
parallel association
-----------------------
System.out.println(strings.stream().parallel().reduce("", (x,y)->y+x+y));
Wrong o/p ;(
=============================
Java 8 date and time API
==============================
date and time api java 8
-----------------------
what is the problem?
=> date api is 20 years old50005016 api introduced with JDK 1.0.
=> original authors of Date API is none other than James Gosling himself
}
}
What it print?
0012-12-12 No
it print:
Sun Jan 12 00:00:00 IST 1913 was WTF???
issues?
-------------------
1. What each 12 means? Is it month, year, date or date, month, year or any other combination
2. Date API month index starts at 0. So, December is actually 11.
3. Date API rolls over i.e. 12 will become January.
4. Year starts with 1900. And because month also roll over so year becomes 1900 + 12 + 1 == 1913.
5. Who asked for time? I just asked for date but program prints time as well.
6. Why is there time zone? Who asked for it? The time zone is JVM\92s default time zone, IST
most imp in the new API are LocalDate, LocalTime, and LocalDateTime
----------------------------------------------------------------
LocalDate: It represents a date with no time or timezone.
LocalTime: It represents time with no date or timezone
LocalDateTime: It is the combination of LocalDate and LocalTime i.e. date with time without time zone.
System.out.println(LocalDate.ofYearDay(2015, 1));
System.out.println(LocalDate.ofEpochDay(1));// will give 1970-01-02 as starting value of is 1970-01-
01
System.out.println(LocalDate.now());// create current date from the system clock using now static
factory method
System.out.println(LocalTime.of(1, 15));
System.out.println(LocalTime.now());
===================
Nashorn
===================
Nashorn introduction:
---------------------------
jjs
jjs> print('Hello World');
from an js file:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(new FileReader("script.js"));
//The Invocable
//interface is implemented by the NashornScriptEngine implementation and defines a method
//invokeFunction to call a javascript function for a given name
Now let's call the second function by passing arbitrary java objects
------------------------------------------------------------------
How does Nashorn handle type conversion when calling java methods with native javascript types?
-------------------------------------------------------------------------------------------------
The following java method simply prints the actual class type of the method parameter:
==================
base 64
===================
=> Java 8 now has inbuilt encoder and decoder for Base64 encoding.
imp Classes
---------
static class Base64.Decoder
=> This class implements a decoder for decoding byte data
using the Base64 encoding scheme as specified in RFC 4648 and RFC 2045.
imp Methods
-----------------