java 8 revealed
Post on 13-Aug-2015
46 Views
Preview:
TRANSCRIPT
Who We are Bazlur Rahman Rokon
Associate Software Engineer, Therap Services, LLC
Sazzadur Rahman
Software Engineer, Kona Software Lab Ltd.
What’s new in Java 8 1. Lambda Expressions
2. Method references
3. Default methods
4. Bulk Data Operation → Stream API
5. Date-Time
6. And a lot more ……
Assumption1. We really love abstraction
2. We Actually Build cool Stuffs
3. We are programmers and lazy
4. We work only day time and go home early (Well, we have life, right :/ )
5. Users want too many features
6. As we are lazy, we don’t want to do too much work.
7. So we love “Less code, do more” philosophy
The Best Code is No Code At All1. Code is bad
2. It rots
3. It requires periodic maintenance
4. But the fact is, we love coding, more specifically less coding
Lambda in Action cont.
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("JUGBD Meetup 3.0");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("JUGBD Meetup 3.0");
}
}).start();
Code I’m interested in
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("JUGBD Meetup 3.0");
}
}).start();
Ceremony
Let’s have a situation public class Person {
private String name;
private LocalDate birthday;
private Sex gender;
private String emailAddress;
private String cellNo;
// getters and setters//
What we want to do1. Search based on characteristics and
send email/call 1. find older than 60 -> then need Elderly
allowance2. find voters1. kids -> less than 18 -> they are not allowed
to vote, so ignore them
2. sort by name, by age
Take # 1 public void findPersonOlder(List<Person> persons) {
for (Person p : persons) {
if (p.getAge() > 60) {
sendEmail(p.getEmailAddress());
}
}
}
Take #2 public void findEligibleVoters(List<Person> persons) {
for (Person p : persons) {
if (p.getAge() > 18) {
sendEmail(p.getEmailAddress());
}
}
}
Take # 3 public void findTargetAudienceForAd(List<Person> persons) {
for (Person p : persons) {
if (p.getAge() > 25 &&
p.getGender() == Sex.MALE) {
sendEmail(p.getEmailAddress());
}
}
}
Lets parameterize the behavior
public interface PersonPredicate { public boolean testPerson(Person p); }
public void processPerson(List<Person> persons,
PersonPredicate predicate) {
for (Person p : persons) {
if (predicate.testPerson(p)) {
sendEmail(p.getEmailAddress());
}
}
}
Revisit Take #2 processPerson(persons, new PersonPredicate() {
@Override
public boolean testPerson(Person p) {
return p.getAge() > 18;
}
});
Revisit Take #3 processPerson(persons, new PersonPredicate() {
@Override
public boolean testPerson(Person p) {
return p.getAge() > 25 &&
p.getGender() == Sex.MALE;
}
});
We want to call as well
public interface PersonConsumer {
public void accept (String phoneNumber);
}
public void processPerson(List<Person> persons,
PersonPredicate predicate,
PersonConsumer consumer) {
for (Person p : persons) {
if (predicate.testPerson(p)) {
String cellNo = p.getCellNo();
consumer.accept(cellNo);
}
}
}
Lets put it a bit harder public void processPerson(List<Person> persons,
PersonPredicate predicate,
PersonConsumer consumer) {
for (Person p : persons) {
if (predicate.testPerson(p)) {
String cellNo = p.getCellNo();
consumer.accept(cellNo);
}
}
}
public void processPerson(List<Person> persons,
PersonPredicate predicate,
PersonMapper mapper,
PersonConsumer consumer) {
for (Person p : persons) {
if (predicate.testPerson(p)) {
String value = mapper.map(p);
consumer.accept(value);
}
}
}
Good going .. processPerson(persons,new PersonPredicate() {
@Override
public boolean testPerson(Person p) {
return p.getAge() > 18;
}
}, new PersonMapper() {
@Override
public String map(Person p) {
return p.getCellNo();
}
}, new PersonConsumer() {
@Override
public void accept(String value) {
call(value);
}
});
Revisit the AgainprocessPerson(persons, new PersonPredicate() { @Override public boolean testPerson(Person p) { return p.getAge() > 18; } });
Boilerplate code processPerson(persons, new PersonPredicate() { @Override public boolean testPerson(Person p) { return p.getAge() > 18; } });
We are in the age of Java 8 , lets throw away boilerplate code processPerson(persons,
p return p.getAge() > 18; );
Functional Interface @FunctionalInterface
public interface PersonMapper {
public String map(Person p);
}
public interface PersonPredicate {
public boolean testPerson(Person p);
}
@FunctionalInterface
public interface PersonMapper {
public String map(Person p);
}
Stream API persons
.stream() .filter(p-> p.getAge()>19) .map(p-> p.getCellNo()) .forEach( c-> call(c));
What is Stream?•A sequence of elements from a source supporting sequential and parallel aggregate operations, While completely abstracting the details of low level multi threading logic.
•Sources can be Any type of Collection, Array, or any I/O operation who provides data to the Stream.
•Aggregate operations are operations to collect or extract necessary information from a stream or collection.
What is Stream?persons
.stream() .filter(p-> p.getAge()>19) .map(p-> p.getCellNo()) .forEach( c-> call(c));
Intermdediate Operation
Terminal Operation
Get Stream
Source
PipeliningIntermdediate Operation
Map and flatMapList<Integer> numbers = Arrays.asList(1, 2, 3, 4);List<List<Integer>> mapped = numbers.stream() .map(number -> Arrays.asList(number -1, number, number +1)) .collect(Collectors.toList());System.out.println(mapped); //:> [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5]] List<Integer> flattened = numbers.stream() .flatMap(number -> Arrays.asList(number -1, number, number +1).stream()) .collect(Collectors.toList());System.out.println(flattened); //:> [0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5]
allMatch and noneMatch//Check if All of the students have distinctionBoolean hasAllStudentsWithDistinction = students.stream() .allMatch(student -> student.getScore() > 80);
//Return true if None of the students are over distinctionBoolean hasAllStudentsBelowDistinction = students.stream() .noneMatch(student -> student.getScore() > 80);
Reduce Reduces the whole stream into a single value
//Summing all elements of a stream Integer sum = numbers.stream() .reduce(0, (x, y) -> x + y); //reduce(identity, accumulator)
Integer min = numbers.stream() .reduce(0, Integer::min);
What about having no terminal Operation?persons
.stream() .filter(p-> p.getAge()>19) .map(p-> p.getCellNo())
Intermdediate Operation
Get Stream
Source
Pipelining Intermdediate Operation
Laziness of Stream operations• Current era is of Big Data, Parallel Processing and being real time.
• When dealing with Big Data Laziness is a big deal.
• Stream API is inherently Lazy and based on “Process on Demand” behavior.
Laziness of Stream operationsStream<String> streamOfNames = students.stream() .map(student -> { System.out.println("In Map - " + student.getName()); return student.getName(); });//Just to add some delayfor (int i = 1; i <= 5; i++) { Thread.sleep(1000); System.out.println(i + " sec");}//Called a terminal operation on the streamstreamOfNames.collect(Collectors.toList());
Output:1 sec2 sec3 sec4 sec5 secIn Map - TomIn Map - ChrisIn Map - Dave
Short Circuit//List of first 3 students who have age > 20students.stream() .filter(s -> s.getAge() > 20) .map(Student::getName) .limit(3) .collect(Collectors.toList());
top related