KEMBAR78
Java8lambda | PPTX
Java8 Lambdas
• Presented By:Isuru Samaraweera
Agenda
• Why change Java again?
• What is FP & Lambda?
• Functional Interfaces
• Streams
• Reduction
• Overloading Lambdas
• Advanced Collections and collectors
• Partioning and Grouping data
• Data Parrellelism
• Testing Lambdas
Why change java again
• Rise of the multicore CPUS
• Algorithms involves locks error-prone time
consuming
• Util.concurrent libraries have limititaions
• Lack of efficient parrelel operations on a
collection
• Java8 allows complex collection-processing
algorithms
What is fp
• Oop data abstraction/side efects
• Functional focuses on side effect free
• Pure functions/lambdas
• Pass functions around easeir to write lazy code
which initialises values when necessary
• n -> n % 2 != 0;
• (char c) -> c == 'y';
• (x, y) -> x + y;
• (int a, int b) -> a * a + b * b;
Functional Interfaces
• How does lambda expressions fit into Javas
type system?
• Each lambda corresponds to a given type,
specified by an interface
• exactly one abstract method declaration
• Interface with single abstract method used as
type
• Multiple optional default methods
Define a functional interface
@FunctionalInterface
public interface Calculator {
abstract int calculate(int x,int y);
}
public class FPDemo {
public static void main(String[] args) {
Calculator f=(x,y)->(x+y);
int z = f.calculate(3, 4);
System.out.println(z);
test((p,q)->p*q);
}
public static int test(Calculator cal) {
Return cal.calculate(4, 8);
}
Lambda Scopes
• int k=0;
• Calculator c1=
• (int x, int y)->
• {System.out.println(k);return x+y;};
• k=8;//fail to compile
• K is implicitly final
• Final is optional
Important functional interfaces in Java
• public interface Predicate<T> {
boolean test(T t);
}
• public interface Function<T,R> {
R apply(T t);
}
• public interface BinaryOperator<T> {
T apply(T left, T right);
}
public interface Consumer<T> {
void accept(T t);
}
• public interface Supplier<T> {
T get();
}
Predicate
• package com.java8.general;
• import java.util.Objects;
• import java.util.function.Predicate;
• public class PredicateTest {
• public static void main(String[] args) {
• Predicate<String> predicate = (s) -> s.length() > 0;
• boolean s=predicate.test("foo"); // true
• predicate.negate().test("foo");
• Predicate<Boolean> nonNull = Objects::nonNull;
• Predicate<Boolean> isNull = Objects::isNull;
• Predicate<String> isEmpty = String::isEmpty;
• Predicate<String> isNotEmpty = isEmpty.negate();
• }
• }
Functions
• Functions accept one argument and produce a
result.
• Function<String, Integer> toInteger =
Integer::valueOf;
• Function<String, Integer> toInteger=(s-
>Integer.valueOf(s);
Suppliers
• Suppliers produce a result of a given generic type.
Unlike Functions, Suppliers don't accept arguments.
• public class SupplierTest {
• public static void main(String[] args) {
• Supplier<SupplierTest> personSupplier =
SupplierTest::new;
• personSupplier.get(); // new Person
• }
• }
Consumers
• consumers represents operations to be
performed on a single input argument.
• Consumer<Person> greeter = (p) ->
System.out.println("Hello, " + p.firstName);
• greeter.accept(new Person("Luke",
"Skywalker"));
Comparators
• Comparator<Person> comparator = (p1, p2) ->
p1.firstName.compareTo(p2.firstName);
Person p1 = new Person("John", "Doe");
Person p2 = new Person("Alice",
"Wonderland");
• comparator.compare(p1, p2); // > 0
Type inference
• Predicate<Integer> atleast5=x->x>5;
• BinaryOperator<Long> addlngs=(x,y)->x+y;
• BinaryOperator add=(x,y)->x+y;
Streams
• A stream represents a sequence of elements
and supports different kind of operations to
perform computations upon those elements:
• List<String> myList =
• Arrays.asList("a1", "a2", "b1", "c2", "c1");
• myList.stream().filter(s -> s.startsWith("c"))
• .map(String::toUpperCase) .sorted()
• .forEach(System.out::println);
Traditional external iteration
• Int count=0;
• Iterator<Artist> iterator=allartists.iterator()
• While(iterator.hasNext())
• {Artist artist=iterator.next();
• If(artist.isForm(“NY”)
• Count++
• }
• Lot of boilerplate code and difficult concurrency
• Serial drawback
Internal Iterator with streams
• Long count=allartists.stream().filter(artist-
>artist.isFrom(“NY”)).count();
• Stream is tool for building up complex operations
on collections using functional approach
• If return is a stream its lazy-Intermediete stream
• If returns a value or void then its eager-Terminal
value
Terminal vs Lazy operations
• //does nothing
• artlist.stream().filter(artist->artist.isFrom("India"));
• //does nothing lazy inilitation
• artlist.stream().filter(artist-
>{System.out.println(artist.getName());
• return artist.isFrom("India");});
• long x=artlist.stream().filter(artist-
>{System.out.println(artist.getName());
• return artist.isFrom("India");}).count();
• System.out.println("x is"+x);
Common stream operations
• Collect(toList())
• Eager operation that genertes a list from the
values in a stream
• List<String>
collected=Stream.of("A","b","c").collect(Collec
tors.toList());
• Streams are lazy so u need eager operation
like collect
map
• Traditional uppercase conversion
• List<String> collected=new ArrayList<>();
• For(String string:asList(“a”,”b”,”c”)){
• String upper=string.toUpperCase();
• Collected.add(upper);
• }
• List<String>
mapped=Stream.of("A","b","c").map(string-
>string.toUpperCase()).collect(Collectors.toList());
filter
• Assume search strings start with a digit
• Traditional style-For loop and iterate
• Functional style
• List<String>
begwithn=Stream.of(“a”,”1abc”,”abc1”).filter(v
alue->isDigit(value.charAt(0))).collect(toList());
• Predicate interface returns true/false
sorted
• stringCollection .stream() .sorted() .filter((s) ->
s.startsWith("a"))
.forEach(System.out::println);
• Sorted is an intermediate operation which
returns a sorted view of the stream. The
elements are sorted in natural order unless
you pass a custom Comparator.
Map and Match
• stringCollection .stream()
.map(String::toUpperCase) .sorted((a, b) ->
b.compareTo(a)) .forEach(System.out::println);
• boolean anyStartsWithA = stringCollection
.stream() .anyMatch((s) -> s.startsWith("a"));
flatmap
• Replace a value with a stream and
concantenate all streams together
• List<Integer>
together=Stream.of(Arrays.asList(1,2),Arrays.a
sList(3,4)).flatMap(numbers-
>numbers.stream()).collect(toList());
• Flatmap return type is a stream
Max and min
• List<Track> tracks=Arrays.asList(new
Track("track1",524),new
Track("track2",454),new
Track("track3",444));
• Track
shortesttrack=tracks.stream().min(Comparator
.comparing(track->track.getLength())).get();
• Comparing builds a comparator using keys
Reduction Operations
• Terminal operations ( average, sum, min, max,
and count) that return one value by combining
the contents of a stream
• reduction operations that return a collection
instead of a single value.
• general-purpose reduction operations reduce
and collect
Reduce
Optional<T> reduce(BinaryOperator<T> accumulator)Performs a reduction on the elements of this stream, using
an associative accumulation function, and returns an Optional describing the reduced value, if any.
T reduce(T identity, BinaryOperator<T> accumulator)Performs a reduction on the elements of this stream, using
the provided identity value and an associative accumulation function, and returns the reduced value.
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)Performs a reduction on
the elements of this stream, using the provided identity, accumulation and combining functions.
Reduce with BinaryOperator
• persons
• .stream()
• .reduce((p1, p2) -> p1.age > p2.age ? p1 :
p2)
• .ifPresent(System.out::println);
• // Pamela
• Returns Optional
Reduce with identity and accumilator
• Integer totalAgeReduce = roster
• .stream()
• .map(Person::getAge)
• .reduce(
• 0,
• (a, b) -> a + b);
• identity: The identity element is both the initial value of the reduction and
the default result if there are no elements in the stream
• accumulator: The accumulator function takes two parameters: a partial
result of the reduction (in this example, the sum of all processed integers
so far) and the next element of the stream (in this example, an integer).
(a, b) -> a + b
Generic reduce
• a reduce operation on elements of type <T> yielding a
result of type <U>
• <U> U reduce(U identity, BiFunction<U, ? super T, U>
accumulator, BinaryOperator<U> combiner);
• identity element is both an initial seed value for the
reduction and a default result if there are no input
elements
• The accumulator function takes a partial result and the
next element, and produces a new partial result
• The combiner function combines two partial results to
produce a new partial result.
• List<String> test= new ArrayList<String>();
• test.add("isuru");
• test.add("sam");
• test.add("silva");
• int s = test.stream().reduce(0, (x, y) -> x + y.length(), (x, y) -> x + y);
• - identity - identity value for the combiner function
- reducer - function for combining two results
- combiner - function for adding an additional element into a result.
• When you run the stream in parallel, the task is spanned into
multiple threads. So for example the data in the pipeline is
partitioned into chunks that evaluate and produce a result
independently. Then the combiner is used to merge this results.
Putting all together
• Get all artists for album
• Figure out which artists are bands
• Find the nationalities for each band
• Put together a set of these values
• Set<String>
origins=album.getMusicians().filter(artist-
>artist.getName().startsWith(“The”)).map(arti
st->artist.getNationality()).collect(toSet());
• Filter,map are lazy operations
• Collect is eager
Stream misuse
• List<Artist>
musicians=album.getMusicians().collect(toList());
• List<Artist> bands=musicians.stream().filter(artist-
>artist.getName().startsWith(“The”)).collect(toList());
• Set<String> origins=bands.stream.map(artist-
>artist.getNationality().collect(toSet());
• Its harder to read /boiler plate code
• Less efficient because it requires eagerly creating new
collection objects in each intermediate step
• Clutters the code with intermediate variables
• Multithreading/parrelllism issues
• Chain them
Overloading
• private interface IntegerBiFunction extends
BinaryOperator<Integer>{}
• public void overloadedm1(BinaryOperator<Integer>
lambda)
• {
• System.out.println("Binaryoperator");
• }
• public void overloadedm1(IntegerBiFunction lambda)
• {
• System.out.println("Bifunction");
• }
• public void test()
• {
• overloadedm1( (y,x)->x+1);
• }
• If there are several possible target types the
most specific type is inferred
• private interface IntPredicate
• {
• public boolean test(int value);
• }
• public void overloadp1(Predicate<Integer> predicate)
• {
• System.out.println("Predicate");
• }
• public void overloadp1(IntPredicate predicate)
• {
• System.out.println("Intpredicate");
• }
• If there are several possible target types and there is no specific type you have to
manually provid the type
Binary interface compatibility
• Backward binary compatibility-If you compile
app in Java1 to 7 it will run out of the box in
Java8
• Stream method added to java8 Collection
iface
• Breaks the binary compatibility
• Not compile or Exception by Calssloader
Advanced Collections and Collectors
• Method references
• Artist:getName
• Artist:new
• String[] new
Element Ordering
• List<Integer> numbers=Arrays.asList(2,3,4);
• List<Integer>
sameOrder=numbers.stream().collect(Collectors.t
oList());
• Set<Integer> numberset=new
HashSet<>(Arrays.asList(3,4,5,6));
• List<Integer>
ntsameOrderset=numberset.stream().collect(Coll
ectors.toList());
Collector
• toList ,toSet you done give the complete
implementation
• Colelcting values into a collection of specific
type
• Stream.collec(toCollection(TreeSet ::new))
To Values
• Collect into a single value using collector
• Finding the band with most numbers
• public Optional<Artist>
biggestGroup(Stream<Artist> artists)
• {
• Funtion<Artist,Long> getCount=artist-
>artist.getMembers().count();
• Return
artists.collect(maxBy(comparing(getCount)));
• minBy also there
Partioning the data
• Split out a list
• Public Map<Boolean,List<Artist>>
bandsAndsolo(Stream<Artist> artists)
• {
• return artists.collect(partitionBy(artist-
>artist.isSolo()));
• }
• Or partitionBy(Artist::isSolo) method reference
Grouping the data
• Grouping albums by main artist
• Public Map<Artist,List<Album>>
albumsByArtists(Stream<Album> albums)
• {
• Return albums.collect(groupingBy(album-
>album.getMainMusician()));
• }
String
• Traditional String handling
• StringBuilder builder=new StringBuilder(“[“);
• For(Artist artist:artists)
• {
• If(builder.length()>1)
• Builder.apppend(“, “);
• }
• String name=artist.getName();
• Builder.append(name);
• }
• Builder.append(“]”);
• String result=builder.toString();
• String result=artists.stream().map(Artist::getName).collect(Collectors.joiniing(“, “,
“[“,”]”));
Composing collectors
• Naïve approach
• Map<Artist,List<Album>>
albumByArtist=albums.collect(groupingBy(album-
>album.getMainMusician())));
• Map<Artist,Integer> numberofalbums=new
HashMap<>();
• For(Entry<Artist,List<Album>
entry:albumsByArtist.entrySet()){
• Numberofalbums.put(entry.getKey(),entry.getVal
ue().size());
Using collectors to count the number
of albums for each artist
• Public Map<Artist,Long>
numberOfalbums(Stream<Album> albums)
• {Return albums.collect(groupingBy(album-
>album.getMusician(),counting())));
• }
• This grouping devides elements into buckets
• Reduction as a collector
Data paralleism
• Parellism vs Concurrency
• Concurrency arises when 2 tasks are making
progress at overlapping time periods
• Parrellism arises 2 tasks are hapenning at
same time –multicore cpu
• In single cpu-concurrency
• Multi core-concurrent/parrellel
Data parellism..contd
• Splitting up the data to be operated on and
assigning single processing unit to each chunk
of data
• Perform same operation on a large dataset
• Task parellism-each individual thread of
execution can be doing totally different task
• Java EE container TP
Parellel stream operations
• Serial summing of album trak lengths
• Public int serialArraySum(){
• Return
album.stream().flatmap(Album::gettracks).mapToInt(tr
ack:getLength).sum();
• }
• Public int parreelelArraySum(){
• Return
albums.parallelstream().flatMap(Album::gettracks).ma
pToInt(Track::getLength).sum();
• When 10000 albums are hit parrel code is faster
Testing Lambdas
• Public static List<String>
allToUppercase(List<String> words)
• {
• Return words.stream().map(string-
>string.toUpperCase()).collect(Collectors.<Stri
ng>.toList());
• }
• @Test
• Public void multiplewordsToUpperCase()
• {
• List<String> input=Arrays.asList(“a”,”b”,”hello”);
• List<String> result=Testing.allToUppercase(input);
• assertEquals(asList(“A”,”B”,”HELLO”),result);
• }

Java8lambda

  • 1.
    Java8 Lambdas • PresentedBy:Isuru Samaraweera
  • 2.
    Agenda • Why changeJava again? • What is FP & Lambda? • Functional Interfaces • Streams • Reduction • Overloading Lambdas • Advanced Collections and collectors • Partioning and Grouping data • Data Parrellelism • Testing Lambdas
  • 3.
    Why change javaagain • Rise of the multicore CPUS • Algorithms involves locks error-prone time consuming • Util.concurrent libraries have limititaions • Lack of efficient parrelel operations on a collection • Java8 allows complex collection-processing algorithms
  • 4.
    What is fp •Oop data abstraction/side efects • Functional focuses on side effect free • Pure functions/lambdas • Pass functions around easeir to write lazy code which initialises values when necessary • n -> n % 2 != 0; • (char c) -> c == 'y'; • (x, y) -> x + y; • (int a, int b) -> a * a + b * b;
  • 5.
    Functional Interfaces • Howdoes lambda expressions fit into Javas type system? • Each lambda corresponds to a given type, specified by an interface • exactly one abstract method declaration • Interface with single abstract method used as type • Multiple optional default methods
  • 6.
    Define a functionalinterface @FunctionalInterface public interface Calculator { abstract int calculate(int x,int y); } public class FPDemo { public static void main(String[] args) { Calculator f=(x,y)->(x+y); int z = f.calculate(3, 4); System.out.println(z); test((p,q)->p*q); } public static int test(Calculator cal) { Return cal.calculate(4, 8); }
  • 7.
    Lambda Scopes • intk=0; • Calculator c1= • (int x, int y)-> • {System.out.println(k);return x+y;}; • k=8;//fail to compile • K is implicitly final • Final is optional
  • 8.
    Important functional interfacesin Java • public interface Predicate<T> { boolean test(T t); } • public interface Function<T,R> { R apply(T t); } • public interface BinaryOperator<T> { T apply(T left, T right); } public interface Consumer<T> { void accept(T t); } • public interface Supplier<T> { T get(); }
  • 9.
    Predicate • package com.java8.general; •import java.util.Objects; • import java.util.function.Predicate; • public class PredicateTest { • public static void main(String[] args) { • Predicate<String> predicate = (s) -> s.length() > 0; • boolean s=predicate.test("foo"); // true • predicate.negate().test("foo"); • Predicate<Boolean> nonNull = Objects::nonNull; • Predicate<Boolean> isNull = Objects::isNull; • Predicate<String> isEmpty = String::isEmpty; • Predicate<String> isNotEmpty = isEmpty.negate(); • } • }
  • 10.
    Functions • Functions acceptone argument and produce a result. • Function<String, Integer> toInteger = Integer::valueOf; • Function<String, Integer> toInteger=(s- >Integer.valueOf(s);
  • 11.
    Suppliers • Suppliers producea result of a given generic type. Unlike Functions, Suppliers don't accept arguments. • public class SupplierTest { • public static void main(String[] args) { • Supplier<SupplierTest> personSupplier = SupplierTest::new; • personSupplier.get(); // new Person • } • }
  • 12.
    Consumers • consumers representsoperations to be performed on a single input argument. • Consumer<Person> greeter = (p) -> System.out.println("Hello, " + p.firstName); • greeter.accept(new Person("Luke", "Skywalker"));
  • 13.
    Comparators • Comparator<Person> comparator= (p1, p2) -> p1.firstName.compareTo(p2.firstName); Person p1 = new Person("John", "Doe"); Person p2 = new Person("Alice", "Wonderland"); • comparator.compare(p1, p2); // > 0
  • 14.
    Type inference • Predicate<Integer>atleast5=x->x>5; • BinaryOperator<Long> addlngs=(x,y)->x+y; • BinaryOperator add=(x,y)->x+y;
  • 15.
    Streams • A streamrepresents a sequence of elements and supports different kind of operations to perform computations upon those elements: • List<String> myList = • Arrays.asList("a1", "a2", "b1", "c2", "c1"); • myList.stream().filter(s -> s.startsWith("c")) • .map(String::toUpperCase) .sorted() • .forEach(System.out::println);
  • 16.
    Traditional external iteration •Int count=0; • Iterator<Artist> iterator=allartists.iterator() • While(iterator.hasNext()) • {Artist artist=iterator.next(); • If(artist.isForm(“NY”) • Count++ • } • Lot of boilerplate code and difficult concurrency • Serial drawback
  • 17.
    Internal Iterator withstreams • Long count=allartists.stream().filter(artist- >artist.isFrom(“NY”)).count(); • Stream is tool for building up complex operations on collections using functional approach • If return is a stream its lazy-Intermediete stream • If returns a value or void then its eager-Terminal value
  • 18.
    Terminal vs Lazyoperations • //does nothing • artlist.stream().filter(artist->artist.isFrom("India")); • //does nothing lazy inilitation • artlist.stream().filter(artist- >{System.out.println(artist.getName()); • return artist.isFrom("India");}); • long x=artlist.stream().filter(artist- >{System.out.println(artist.getName()); • return artist.isFrom("India");}).count(); • System.out.println("x is"+x);
  • 19.
    Common stream operations •Collect(toList()) • Eager operation that genertes a list from the values in a stream • List<String> collected=Stream.of("A","b","c").collect(Collec tors.toList()); • Streams are lazy so u need eager operation like collect
  • 20.
    map • Traditional uppercaseconversion • List<String> collected=new ArrayList<>(); • For(String string:asList(“a”,”b”,”c”)){ • String upper=string.toUpperCase(); • Collected.add(upper); • } • List<String> mapped=Stream.of("A","b","c").map(string- >string.toUpperCase()).collect(Collectors.toList());
  • 21.
    filter • Assume searchstrings start with a digit • Traditional style-For loop and iterate • Functional style • List<String> begwithn=Stream.of(“a”,”1abc”,”abc1”).filter(v alue->isDigit(value.charAt(0))).collect(toList()); • Predicate interface returns true/false
  • 22.
    sorted • stringCollection .stream().sorted() .filter((s) -> s.startsWith("a")) .forEach(System.out::println); • Sorted is an intermediate operation which returns a sorted view of the stream. The elements are sorted in natural order unless you pass a custom Comparator.
  • 23.
    Map and Match •stringCollection .stream() .map(String::toUpperCase) .sorted((a, b) -> b.compareTo(a)) .forEach(System.out::println); • boolean anyStartsWithA = stringCollection .stream() .anyMatch((s) -> s.startsWith("a"));
  • 24.
    flatmap • Replace avalue with a stream and concantenate all streams together • List<Integer> together=Stream.of(Arrays.asList(1,2),Arrays.a sList(3,4)).flatMap(numbers- >numbers.stream()).collect(toList()); • Flatmap return type is a stream
  • 25.
    Max and min •List<Track> tracks=Arrays.asList(new Track("track1",524),new Track("track2",454),new Track("track3",444)); • Track shortesttrack=tracks.stream().min(Comparator .comparing(track->track.getLength())).get(); • Comparing builds a comparator using keys
  • 26.
    Reduction Operations • Terminaloperations ( average, sum, min, max, and count) that return one value by combining the contents of a stream • reduction operations that return a collection instead of a single value. • general-purpose reduction operations reduce and collect
  • 27.
    Reduce Optional<T> reduce(BinaryOperator<T> accumulator)Performsa reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any. T reduce(T identity, BinaryOperator<T> accumulator)Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. <U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions.
  • 28.
    Reduce with BinaryOperator •persons • .stream() • .reduce((p1, p2) -> p1.age > p2.age ? p1 : p2) • .ifPresent(System.out::println); • // Pamela • Returns Optional
  • 29.
    Reduce with identityand accumilator • Integer totalAgeReduce = roster • .stream() • .map(Person::getAge) • .reduce( • 0, • (a, b) -> a + b); • identity: The identity element is both the initial value of the reduction and the default result if there are no elements in the stream • accumulator: The accumulator function takes two parameters: a partial result of the reduction (in this example, the sum of all processed integers so far) and the next element of the stream (in this example, an integer). (a, b) -> a + b
  • 30.
    Generic reduce • areduce operation on elements of type <T> yielding a result of type <U> • <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner); • identity element is both an initial seed value for the reduction and a default result if there are no input elements • The accumulator function takes a partial result and the next element, and produces a new partial result • The combiner function combines two partial results to produce a new partial result.
  • 31.
    • List<String> test=new ArrayList<String>(); • test.add("isuru"); • test.add("sam"); • test.add("silva"); • int s = test.stream().reduce(0, (x, y) -> x + y.length(), (x, y) -> x + y); • - identity - identity value for the combiner function - reducer - function for combining two results - combiner - function for adding an additional element into a result. • When you run the stream in parallel, the task is spanned into multiple threads. So for example the data in the pipeline is partitioned into chunks that evaluate and produce a result independently. Then the combiner is used to merge this results.
  • 32.
    Putting all together •Get all artists for album • Figure out which artists are bands • Find the nationalities for each band • Put together a set of these values
  • 33.
  • 34.
    Stream misuse • List<Artist> musicians=album.getMusicians().collect(toList()); •List<Artist> bands=musicians.stream().filter(artist- >artist.getName().startsWith(“The”)).collect(toList()); • Set<String> origins=bands.stream.map(artist- >artist.getNationality().collect(toSet()); • Its harder to read /boiler plate code • Less efficient because it requires eagerly creating new collection objects in each intermediate step • Clutters the code with intermediate variables • Multithreading/parrelllism issues • Chain them
  • 35.
    Overloading • private interfaceIntegerBiFunction extends BinaryOperator<Integer>{} • public void overloadedm1(BinaryOperator<Integer> lambda) • { • System.out.println("Binaryoperator"); • } • public void overloadedm1(IntegerBiFunction lambda) • { • System.out.println("Bifunction"); • }
  • 36.
    • public voidtest() • { • overloadedm1( (y,x)->x+1); • } • If there are several possible target types the most specific type is inferred
  • 37.
    • private interfaceIntPredicate • { • public boolean test(int value); • } • public void overloadp1(Predicate<Integer> predicate) • { • System.out.println("Predicate"); • } • public void overloadp1(IntPredicate predicate) • { • System.out.println("Intpredicate"); • } • If there are several possible target types and there is no specific type you have to manually provid the type
  • 38.
    Binary interface compatibility •Backward binary compatibility-If you compile app in Java1 to 7 it will run out of the box in Java8 • Stream method added to java8 Collection iface • Breaks the binary compatibility • Not compile or Exception by Calssloader
  • 39.
    Advanced Collections andCollectors • Method references • Artist:getName • Artist:new • String[] new
  • 40.
    Element Ordering • List<Integer>numbers=Arrays.asList(2,3,4); • List<Integer> sameOrder=numbers.stream().collect(Collectors.t oList()); • Set<Integer> numberset=new HashSet<>(Arrays.asList(3,4,5,6)); • List<Integer> ntsameOrderset=numberset.stream().collect(Coll ectors.toList());
  • 41.
    Collector • toList ,toSetyou done give the complete implementation • Colelcting values into a collection of specific type • Stream.collec(toCollection(TreeSet ::new))
  • 42.
    To Values • Collectinto a single value using collector • Finding the band with most numbers • public Optional<Artist> biggestGroup(Stream<Artist> artists) • { • Funtion<Artist,Long> getCount=artist- >artist.getMembers().count(); • Return artists.collect(maxBy(comparing(getCount))); • minBy also there
  • 43.
    Partioning the data •Split out a list • Public Map<Boolean,List<Artist>> bandsAndsolo(Stream<Artist> artists) • { • return artists.collect(partitionBy(artist- >artist.isSolo())); • } • Or partitionBy(Artist::isSolo) method reference
  • 44.
    Grouping the data •Grouping albums by main artist • Public Map<Artist,List<Album>> albumsByArtists(Stream<Album> albums) • { • Return albums.collect(groupingBy(album- >album.getMainMusician())); • }
  • 45.
    String • Traditional Stringhandling • StringBuilder builder=new StringBuilder(“[“); • For(Artist artist:artists) • { • If(builder.length()>1) • Builder.apppend(“, “); • } • String name=artist.getName(); • Builder.append(name); • } • Builder.append(“]”); • String result=builder.toString(); • String result=artists.stream().map(Artist::getName).collect(Collectors.joiniing(“, “, “[“,”]”));
  • 46.
    Composing collectors • Naïveapproach • Map<Artist,List<Album>> albumByArtist=albums.collect(groupingBy(album- >album.getMainMusician()))); • Map<Artist,Integer> numberofalbums=new HashMap<>(); • For(Entry<Artist,List<Album> entry:albumsByArtist.entrySet()){ • Numberofalbums.put(entry.getKey(),entry.getVal ue().size());
  • 47.
    Using collectors tocount the number of albums for each artist • Public Map<Artist,Long> numberOfalbums(Stream<Album> albums) • {Return albums.collect(groupingBy(album- >album.getMusician(),counting()))); • } • This grouping devides elements into buckets • Reduction as a collector
  • 48.
    Data paralleism • Parellismvs Concurrency • Concurrency arises when 2 tasks are making progress at overlapping time periods • Parrellism arises 2 tasks are hapenning at same time –multicore cpu • In single cpu-concurrency • Multi core-concurrent/parrellel
  • 49.
    Data parellism..contd • Splittingup the data to be operated on and assigning single processing unit to each chunk of data • Perform same operation on a large dataset • Task parellism-each individual thread of execution can be doing totally different task • Java EE container TP
  • 50.
    Parellel stream operations •Serial summing of album trak lengths • Public int serialArraySum(){ • Return album.stream().flatmap(Album::gettracks).mapToInt(tr ack:getLength).sum(); • } • Public int parreelelArraySum(){ • Return albums.parallelstream().flatMap(Album::gettracks).ma pToInt(Track::getLength).sum(); • When 10000 albums are hit parrel code is faster
  • 51.
    Testing Lambdas • Publicstatic List<String> allToUppercase(List<String> words) • { • Return words.stream().map(string- >string.toUpperCase()).collect(Collectors.<Stri ng>.toList()); • }
  • 52.
    • @Test • Publicvoid multiplewordsToUpperCase() • { • List<String> input=Arrays.asList(“a”,”b”,”hello”); • List<String> result=Testing.allToUppercase(input); • assertEquals(asList(“A”,”B”,”HELLO”),result); • }