PANAYA
kn0wl3d93 sH4RIn'
14-07-2015
Something before we start...
Fun fact of the day
JAVA Stupidity... or not ?
for(int i = 0; i < 1000 ; ++i)
{
Integer x = i;
Integer y = i;
if(x == y) {
System.out.println("True");
} else {
System.out.println("False");
}
}
a "for" loop - assigning same iteration number to two seemingly different objects
Guess ?
So apparently...
for i
What does "cached" means
The same object ("reference") would be returned from "new" operation for those Integers !
Actually - this is a guaranty by the JRE - but it's possible some JRE implementations would cache a bigger portion
-128 < i < 127 : Integers are "cached" by the JRE
128 < i : Integers are not "cached"
Moral
Obviously - use ".equals", or get the int value
Java supports implementation based bugs :)
{CSS}
<html>
(javascript)
$jQuery
Java 8
a small intro into features...
or - How I wish it was c#
Lambda Expressions
λ
So... we have a "Person" Class
- We have a bunch of them in a list
- We want to do something with them - let's say - PRINT :)
public class Person {
public enum Sex {
MALE, FEMALE
}
String name;
LocalDate birthday;
Sex gender;
String emailAddress;
public int getAge() {
// ...
}
public void printPerson() {
// ...
}
}
Approach 1
public static void printPersonsOlderThan(List<Person> roster, int age) {
for (Person p : roster) {
if (p.getAge() >= age) {
p.printPerson();
}
}
}
Method...
- Readability - seems OK
- Extentiability - No
Approach 2
public static void printPersonsWithinAgeRange(List<Person> roster, int low, int high) {
for (Person p : roster) {
if (low <= p.getAge() && p.getAge() < high) {
p.printPerson();
}
}
}
Method - generalized...
- Readability - same as before
- Extentiability - Still no
Approach 3
public static void printPersons(List<Person> roster, CheckPerson tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
Let's Class it (Specify Search Criteria Code in a Local Class)
-
Readability - getting cumbersome
-
So many classes...
-
-
Extentiability - to some extent
-
less rewrite for changes...
-
interface CheckPerson {
boolean test(Person p);
}
class CheckPersonEligibleForService implements CheckPerson {
public boolean test(Person p) {
return p.gender == Person.Sex.MALE &&
p.getAge() >= 18 &&
p.getAge() <= 25;
}
}
printPersons(roster, new CheckPersonEligibleForSelectiveService());
And finally
Approach 4
printPersons(
roster,
new CheckPerson() {
public boolean test(Person p) {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
}
);
Let's Class it (Specify Search Criteria Code in an Anonymous Class)
-
Readability - less code
-
still bulky - remember that the interface has only ONE method
-
-
Extentiability - Still no
interface CheckPerson {
boolean test(Person p);
}
Still need this:
Approach 5
printPersons(
roster,
(Person p) -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
);
The Lambda way (Specify Search Criteria Code with a Lambda Expression)
-
Readability - NO CLASS !!
- but why do we need the interface ?
-
Extentiability - YES
interface CheckPerson {
boolean test(Person p);
}
Still need this:
Approach 6
public static void printPersonsWithPredicate(
List<Person> roster, Predicate<Person> tester) {
for (Person p : roster) {
if (tester.test(p)) {
p.printPerson();
}
}
}
The Lambda way (Use Standard Functional Interfaces with Lambda Expressions)
-
Readability - NO CLASS & no INTERFACE
-
Extentiability - YES, but we can do better
interface Predicate<T> {
boolean test(T t);
}
JDK defines several standard functional interfaces:
look in java.util.function
Change the print method:
use same approach as "5" to invoke
Approach 7
public static void processPersons(
List<Person> roster,
Predicate<Person> tester,
Consumer<Person> block) {
for (Person p : roster) {
if (tester.test(p)) {
block.accept(p);
}
}
}
MORE LAMBDAS (...)
-
Readability - err... ok...
-
Extentiability - over kill ;)
processPersons(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.printPerson()
);
public static void processPersonsWithFunction(
List<Person> roster,
Predicate<Person> tester,
Function<Person, String> mapper,
Consumer<String> block) {
for (Person p : roster) {
if (tester.test(p)) {
String data = mapper.apply(p);
block.accept(data);
}
}
}
processPersonsWithFunction(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.getEmailAddress(),
email -> System.out.println(email)
);
Approach 8
Some Generics (...)
-
Readability - err... yicks...
-
Extentiability - same
public static <X, Y> void processElements(
Iterable<X> source,
Predicate<X> tester,
Function <X, Y> mapper,
Consumer<Y> block) {
for (X p : source) {
if (tester.test(p)) {
Y data = mapper.apply(p);
block.accept(data);
}
}
}
processElements(
roster,
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25,
p -> p.getEmailAddress(),
email -> System.out.println(email)
);
Approach 9
Aggregate Operations
-
Readability - YES
-
Extentiability - YES
roster
.stream()
.filter(
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25)
.map(p -> p.getEmailAddress())
.forEach(email -> System.out.println(email));
The operations filter, map, and forEach are aggregate operations.
Aggregate operations process elements from a stream - a "pipeline" of elements
Parallel Sorting
Speed up sorting !!!
The Concurrent way
// the normal way
Array.sort(myArray);
// the awesome way
Arrays.parallelSort(myArray);
The normal way
What will happen ?
- automatically break up the target collection into several parts
- each part sorted independently across number of cores
- than - group back togeteher
PROS
Use more cores/threads
CONS
In highly multi-threaded environments (App-Server) - context-switch is not a friend...
but in the Utils-Server - this might be cool
Date API
java.util.date
one of the most hated classes...
ever...
adding to the "sasspool" - SimpleDateFormatter, Calander and many more
old API
- No thread safety
- poor API design - confusing
- years start at 1900, months at 1, days at 0
- "Date" class refers to a date ?
- Date is actually a wrapper around number of milliseconds (UNIX epoch) - call ".toString" - the result suggests it has a TZ ?
new API
- Immutable-value classes
- value is saved internally
- API of class does not support change of internal value
- invoking a method - returns new instance
- Domain-Driven design
- "Date"/"Time" class
We'll not go over it
Let's just say
- it's better
- it's functional
- there's a "bridge" from old Date to new Date
Optional References
Optional<User> tryFindUser(int userID) {
...
}
Tired of null-pointer exceptions ?
if(person.isPresent()){
System.out.println(person.get());
}
Default Methods
NEXT LECTURE...
PANAYA - KNLG-SHRNG - 14/07/2015
By Amir Gal-Or
PANAYA - KNLG-SHRNG - 14/07/2015
Java 8 - new Date API - Optional References - Lambda expressions - Virtual Interface - Parallel Ops
- 896