SlideShare a Scribd company logo
1 of 51
Effective Java, 3/e: keepin’ it effective1
Effective Java, Third Ed.
Keepin’ it effective
Joshua Bloch
@joshbloch
InfoQ.com: News & Community Site
• 750,000 unique visitors/month
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• News 15-20 / week
• Articles 3-4 / week
• Presentations (videos) 12-15 / week
• Interviews 2-3 / week
• Books 1 / month
Watch the video with slide
synchronization on InfoQ.com!
https://www.infoq.com/presentations/
effective-java-third-edition
Presented at QCon New York
www.qconnewyork.com
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
Effective Java, 3/e: keepin’ it effective2
Effective Java, 3d Ed. is now available!
• One new chapter
• Fourteen new items
• Two retired items
• All existing Items thoroughly revised
Effective Java, 3/e: keepin’ it effective3
The evolution of Effective Java
• First edition: 2001 – 232 pages
─ Java 4 – original language + anonymous classes,
asserts, and tons of new APIs
• Second edition: 2008 – 315 pages
─ Java 6 – generics, enums, autoboxing, for-each,
varargs, concurrency utils
• Third edition: 2017 – 366 pages
─ Java 9 – lambdas, streams, optionals, default
methods, try-with-resources, modules
Effective Java, 3/e: keepin’ it effective4
Outline
I. Prefer lambdas to anonymous classes (42)
II. Prefer method references to lambdas (43)
III. Favor standard functional interfaces (44)
IV. Use streams judiciously (45)
V. Use caution when making streams parallel (48)
Effective Java, 3/e: keepin’ it effective5
I. Prefer lambdas to anonymous classes
Historically, anonymous classes for function objects
// Best practice as of Java 7
Collections.sort(words, new Comparator<String>() {
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
});
Adequate for classic OO design patterns, such
as Strategy and Command
Effective Java, 3/e: keepin’ it effective6
Now there’s a better way
Use a lambda
Collections.sort(words,
(s1, s2) -> Integer.compare(s1.length(), s2.length()));
Effective Java, 3/e: keepin’ it effective7
Now there’s a better way
Use a lambda
Collections.sort(words,
(s1, s2) -> Integer.compare(s1.length(), s2.length()));
Better still – use comparator construction method
Collections.sort(words, comparingInt(String::length));
Effective Java, 3/e: keepin’ it effective8
Now there’s a better way
Use a lambda
Collections.sort(words,
(s1, s2) -> Integer.compare(s1.length(), s2.length()));
Better still – use comparator construction method
Collections.sort(words, comparingInt(String::length));
Even better – also use the sort method on List
words.sort(comparingInt(String::length));
Effective Java, 3/e: keepin’ it effective9
Under the hood – type inference
• When program says:
Collections.sort(words,
(s1, s2) -> Integer.compare(s1.length(), s2.length()));
• It means:
Collections.sort(words, (Comparator<String>)
(String s1, String s2) -> Integer.compare(s1.length(),
s2.length()));
• Type inference is magic
─ No one knows the rules but that’s OK
─ Omit types unless they make program clearer
─ Compiler will tell you if it needs help
Effective Java, 3/e: keepin’ it effective10
A caveat regarding type inference
• Inference relies on generic type information
─ e.g., words being declared a List<String>
─ Code won’t compile if words is a raw List!
• Second edition said “don’t use raw types”
─ Penalty was ugly code and needless runtime bugs
• Third edition says it even more strongly
─ Penalty now includes inability to use lambdas properly
• You must understand generics to use lambdas
Effective Java, 3/e: keepin’ it effective11
Remember this old chestnut?
Enum type with constant-specific class bodies and data
public enum Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x / y; }
};
private final String symbol;
Operation(String symbol) { this.symbol = symbol; }
@Override public String toString() { return symbol; }
public abstract double apply(double x, double y);
}
Effective Java, 3/e: keepin’ it effective12
Now there’s a better way
Enum with function object field – impractical sans lambdas
public enum Operation {
PLUS ("+", (x, y) -> x + y),
MINUS ("-", (x, y) -> x - y),
TIMES ("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
@Override public String toString() { return symbol; }
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
}
Effective Java, 3/e: keepin’ it effective13
Lambda caveats
• Lambdas lack names and documentation
─ They should be self-explanatory
─ They should not exceed a few lines; one is best
• If lambda would be long or complex:
─ Extract it to method and use method reference
─ Or (for enums) use instance-specific class body
• Anonymous classes still have a few uses
─ Lambdas require functional interfaces
─ Lambdas cannot access themselves;
in a lambda, this refers to the enclosing instance
Effective Java, 3/e: keepin’ it effective14
II. Prefer method references to lambdas
• Lambdas are succinct
map.merge(key, 1, (count, incr) -> count + incr);
• But method references can be more so
map.merge(key, 1, Integer::sum);
• The more parameters, the bigger the win
─ But parameter names may provide documentation
─ If you use a lambda, choose param names carefully!
Effective Java, 3/e: keepin’ it effective15
Occasionally, lambdas are more succinct
service.execute(() -> action());
is preferable to
service.execute(GoshThisClassNameIsHumongous::action);
Lambdas can beat function factories too
.flatMap(x -> x);
is preferable to
.flatMap(Function.identity());
Effective Java, 3/e: keepin’ it effective16
Know all five kinds of method references
All are at times preferable to lambdas
Type Example Lambda Equivalent*
Static Integer::parseInt str -> Integer.parseInt(str)
Bound Instant.now()::isAfter Instant then = Instant.now();
t -> then.isAfter(t)
Unbound String::toLowerCase str -> str.toLowerCase()
Class Constructor TreeMap<K,V>::new () -> new TreeMap<K,V>()
Array Constructor int[]::new len -> new int[len]
Effective Java, 3/e: keepin’ it effective17
The bottom line
• (Almost) anything you can do with a method
reference, you can also do with a lambda
• Method references are usually more succinct
• But sometimes lambdas are clearer
• Use your best judgment
─ You can always change your mind
Effective Java, 3/e: keepin’ it effective18
III. Favor standard functional interfaces
Before lambdas, Template Method pattern was common
public class Cache<K,V> extends LinkedHashMap<K,V> {
final int maxSize; // Set by constructor-omitted for brevity
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return size() > maxSize;
}
}
Now, Strategy pattern is generally preferable
public LinkedHashMap(EldestEntryRemovalFunction<K,V> fn) { ... }
// Unnecessary functional interface; use standard one instead!
@FunctionalInterface interface EldestEntryRemovalFunction<K,V> {
boolean remove(Map<K,V> map, Map.Entry<K,V> eldest);
}
Map<K,V> cache =
new LinkedHashMap((map, eldestEntry) -> map.size() > maxSize);
Effective Java, 3/e: keepin’ it effective19
Java has 43 standard functional interfaces
Luckily, there is a fair amount of structure
BiConsumer<T,U>
BiFunction<T,U,R>
BinaryOperator<T>
BiPredicate<T,U>
BooleanSupplier
Consumer<T>
DoubleBinaryOperator
DoubleConsumer
DoubleFunction<R>
DoublePredicate
DoubleSupplier
DoubleToIntFunction
DoubleToLongFunction
DoubleUnaryOperator
Function<T,R>
IntBinaryOperator
IntConsumer
IntFunction<R>
IntPredicate
IntSupplier
IntToDoubleFunction
IntToLongFunction
IntUnaryOperator
LongBinaryOperator
LongConsumer
LongFunction<R>
LongPredicate
LongSupplier
LongToDoubleFunction
LongToIntFunction
LongUnaryOperator
ObjDoubleConsumer<T>
ObjIntConsumer<T>
ObjLongConsumer<T>
Predicate<T>
Supplier<T>
ToDoubleBiFunction<T,U>
ToDoubleFunction<T>
ToIntBiFunction<T,U>
ToIntFunction<T>
ToLongBiFunction<T,U>
ToLongFunction<T>
UnaryOperator<T>
Effective Java, 3/e: keepin’ it effective20
The 6 basic standard functional interfaces
Interface Function Signature Example
UnaryOperator<T> T apply(T t) String::toLowerCase
BinaryOperator<T> T apply(T t1, T t2) BigInteger::add
Predicate<T> boolean test(T t) Collection::isEmpty
Function<T,R> R apply(T t) Arrays::asList
Supplier<T> T get() Instant::now
Consumer<T> void accept(T t) System.out::println
Most of the remaining 37 interfaces provide support
for primitive types. Use them or pay the price!
Effective Java, 3/e: keepin’ it effective21
Advantages of using a standard
functional interface
• Makes APIs easier to learn by reducing
conceptual surface area
• Provides interoperability benefits
─ Many SFIs provide useful default methods
─ For example, Predicate provides methods to
combine and negate predicates
• In our LinkedHashMap example:
─ BiPredicate<Map<K,V>, Map.Entry<K,V>>
should be used in place of a
EldestEntryRemovalFunction<K,V>
Effective Java, 3/e: keepin’ it effective22
When shouldn’t you use a standard
functional interface?
• When none of the standard interfaces apply
• But consider Comparator<T>
─ Structurally identical to ToIntBiFunction<T,T>
─ Seems clear that it would have been wrong to use it
─ Why?
Effective Java, 3/e: keepin’ it effective23
What's so special about Comparator?
• Name provides doc every time it’s used in an API
─ And it's used a lot!
• Strong requirements on valid instances
─ Requirements comprise general contract
─ By implementing the interface, you pledge to adhere
• Many useful default methods to combine and
transform instances
─ Six forms of thenComparing, and reversed
Effective Java, 3/e: keepin’ it effective24
Criteria for writing a purpose-built
functional interface
• Interface should share one or more of these
characteristics with Comparator
1. Likely to be commonly used
2. Has a good descriptive name
3. Has a strong contract associated with it
4. Would benefit from default methods
• If you write a functional interface, remember,
it’s an interface!
─ All interfaces require great care (Item 21)
Effective Java, 3/e: keepin’ it effective25
IV. Use streams judiciously
Quick review – What is a stream?
• A bunch of data objects from a collection, array,
input device, etc., for bulk data processing
• Processed by a pipeline
─ A single stream generator (data source)
─ Zero or more intermediate stream operations
─ A single terminal stream operation
• Supports mostly-functional data processing
• Enables painless parallelism
─ Simply replace stream with parallelStream
─ You may or may not see a performance improvement
Effective Java, 3/e: keepin’ it effective26
Example – first twenty Mersenne Primes
Mersenne number is a number of the form 2p − 1
If p is prime, the corresponding Mersenne number may be prime
If it is, it’s a Mersenne prime
static Stream<BigInteger> primes() {
return Stream.iterate(TWO, BigInteger::nextProbablePrime);
}
public static void main(String[] args) {
primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
.filter(mersenne -> mersenne.isProbablePrime(50))
.limit(20)
.forEach(System.out::println);
}
Effective Java, 3/e: keepin’ it effective27
An iterative program to compute all the
anagram groups in a dictionary
public static void main(String[] args) throws IOException {
File dictionary = new File(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
Map<String, Set<String>> groups = new HashMap<>();
try (Scanner s = new Scanner(dictionary)) { // Item 9
while (s.hasNext()) {
String word = s.next();
groups.computeIfAbsent(alphabetize(word),
(unused) -> new TreeSet<>()).add(word);
}
}
for (Set<String> group : groups.values())
if (group.size() >= minGroupSize)
System.out.println(group.size() + ": " + group);
}
Effective Java, 3/e: keepin’ it effective28
Helper function to alphabetize a word
Word nerds call the result an alphagram
private static String alphabetize(String s) {
char[] a = s.toCharArray();
Arrays.sort(a);
return new String(a);
}
Effective Java, 3/e: keepin’ it effective29
Streams gone crazy
Just because you can doesn’t mean you should!
public class Anagrams {
public static void main(String[] args) throws IOException {
Path dictionary = Paths.get(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
try (Stream<String> words = Files.lines(dictionary)) {
words.collect(
groupingBy(word -> word.chars().sorted()
.collect(StringBuilder::new,
(sb, c) -> sb.append((char) c),
StringBuilder::append).toString()))
.values().stream()
.filter(group -> group.size() >= minGroupSize)
.map(group -> group.size() + ": " + group)
.forEach(System.out::println);
}
}
}
Effective Java, 3/e: keepin’ it effective30
A happy medium
Tasteful use of streams enhances clarity and conciseness
public static void main(String[] args) throws IOException {
Path dictionary = Paths.get(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
try (Stream<String> words = Files.lines(dictionary)) {
words.collect(groupingBy(word -> alphabetize(word)))
.values().stream()
.filter(group -> group.size() >= minGroupSize)
.forEach(g -> System.out.println(g.size() + ": " + g));
}
}
Effective Java, 3/e: keepin’ it effective31
Why shouldn’t we use streams to
implement alphabetize?
• Streams do not offer direct support for char
• Resulting implementation would have been
─ more difficult to read
─ more difficult to write correctly
─ probably slower
Effective Java, 3/e: keepin’ it effective32
A minipuzzler - what does this print?
"Hello world!".chars()
.forEach(System.out::print);
Effective Java, 3/e: keepin’ it effective33
Puzzler solution
"Hello world!".chars()
.forEach(System.out::print);
Prints 721011081081113211911111410810033
Why does it do this?
Effective Java, 3/e: keepin’ it effective34
Puzzler Explanation
"Hello world!".chars()
.forEach(System.out::print);
Prints 721011081081113211911111410810033
String’s chars method returns an IntStream
Effective Java, 3/e: keepin’ it effective35
How do you fix it?
"Hello world!".chars()
.forEach(x -> System.out.print((char) x));
Now prints Hello world
Moral
Streams only for object ref types, int, long, and double
Minor primitive types are missing
Type inference can be confusing
Avoid using streams for char processing
Effective Java, 3/e: keepin’ it effective36
A conundrum – Cartesian product
Which is better?
// Iterative Cartesian product computation
private static List<Card> newDeck() {
List<Card> result = new ArrayList<>();
for (Suit suit : Suit.values())
for (Rank rank : Rank.values())
result.add(new Card(suit, rank));
return result;
}
// Stream-based Cartesian product computation
private static List<Card> newDeck() {
return Stream.of(Suit.values())
.flatMap(suit -> Stream.of(Rank.values())
.map(rank -> new Card(suit, rank)))
.collect(toList());
}
Effective Java, 3/e: keepin’ it effective37
The bottom line
• Streams are great for many things…
─ But they’re not a panacea
• When you first learn streams, you may want to
convert all of your loops. Don’t!
─ It may make your code shorter, but not clearer
• Exercise judgment
─ Properly used, streams increase brevity and clarity
─ Most programs should combine iteration and streams
• It’s not always clear at the outset
─ If you don’t know, take a guess and start hacking
─ If it doesn’t feel right, try the other approach
Effective Java, 3/e: keepin’ it effective38
V. Use caution making streams parallel
Remember our Mersenne primes program?
static Stream<BigInteger> primes() {
return Stream.iterate(TWO, BigInteger::nextProbablePrime);
}
public static void main(String[] args) {
primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
.filter(mersenne -> mersenne.isProbablePrime(50))
.limit(20)
.forEach(System.out::println);
}
Runs in 12.5s on my quad-core, 8-thread core i7
Effective Java, 3/e: keepin’ it effective39
How fast do you think this program runs?
static Stream<BigInteger> primes() {
return Stream.iterate(TWO, BigInteger::nextProbablePrime);
}
public static void main(String[] args) {
primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
.parallel()
.filter(mersenne -> mersenne.isProbablePrime(50))
.limit(20)
.forEach(System.out::println);
}
Effective Java, 3/e: keepin’ it effective40
How fast do you think this program runs?
static Stream<BigInteger> primes() {
return Stream.iterate(TWO,
BigInteger::nextProbablePrime);
}
public static void main(String[] args) {
primes().map(p ->
TWO.pow(p.intValueExact()).subtract(ONE))
.parallel()
.filter(mersenne -> mersenne.isProbablePrime(50))
.limit(20)
.forEach(System.out::println);
}
Very, very slowly. I gave up after half an hour.
Effective Java, 3/e: keepin’ it effective41
Why did the program run so slowly?
• Streams library has no idea how to parallelize it
─ And the heuristics fail miserably
• In the best case, parallel unlikely to help if:
─ Stream source is Stream.iterate, or
─ Intermediate limit operation is used
• This isn’t the best case
─ Default strategy for limit computes excess elements
─ Each Mersenne prime takes twice as long as last one
• Moral: do not parallelize indiscriminately!
Effective Java, 3/e: keepin’ it effective42
What does parallelize well?
• Arrays, ArrayList, HashMap, HashSet,
ConcurrentHashMap, int and long ranges…
• What do these sources have in common?
─ Predictably splittable
─ Good locality of reference
• Terminal operation also matters
─ Must be quick, or easily parallelizable
─ Best are reductions, e.g., min, max, count, sum
─ Collectors (AKA mutable reductions) not so good
• Intermediate operations matter too
─ Mapping and filtering good, limit bad
Effective Java, 3/e: keepin’ it effective43
Example – number of primes ≤ n, π(n)
static long pi(long n) {
return LongStream.rangeClosed(2, n)
.mapToObj(BigInteger::valueOf)
.filter(i -> i.isProbablePrime(50))
.count();
}
Takes 31s to compute π(108) on my machine
Effective Java, 3/e: keepin’ it effective44
Example – number of primes ≤ n, π(n)
static long pi(long n) {
return LongStream.rangeClosed(2, n)
.parallel()
.mapToObj(BigInteger::valueOf)
.filter(i -> i.isProbablePrime(50))
.count();
}
In parallel, it takes 9.2s, which is 3.7 times as fast!
Effective Java, 3/e: keepin’ it effective45
.parallel() is merely an optimization
• Optimize Judiciously (Item 67)
• Don’t parallelize unless you can prove it
maintains correctness
• Don’t parallelize unless you have a good
reason to believe it will run faster
• Measure performance before and after
Effective Java, 3/e: keepin’ it effective46
Conclusion
• Java is larger and more complex than it once was
• Now a multiparadigm language
• Not just how to use features, but which to use
• Lambdas and streams can be a big win
─ But you must use them judiciously
• With great power comes great responsibility
Effective Java, 3/e: keepin’ it effective47
Ask me anything!
informit.com Promo Codes
• 35% off - BLOCH991
• But check Amazon!
Effective Java, 3/e: keepin’ it effective48
Effective Java, Third Ed.
Keepin’ it effective
Joshua Bloch
@joshbloch
Watch the video with slide
synchronization on InfoQ.com!
https://www.infoq.com/presentations/
effective-java-third-edition

More Related Content

What's hot

Security in PHP - 那些在滲透測試的小技巧
Security in PHP - 那些在滲透測試的小技巧Security in PHP - 那些在滲透測試的小技巧
Security in PHP - 那些在滲透測試的小技巧Orange Tsai
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Phil Calçado
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVMSylvain Wallez
 
Java 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & StreamsJava 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & StreamsNewCircle Training
 
Enterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeEnterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeScott Wlaschin
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event LoopDesignveloper
 
Java Input Output and File Handling
Java Input Output and File HandlingJava Input Output and File Handling
Java Input Output and File HandlingSunil OS
 
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)Scott Wlaschin
 
Converting Scikit-Learn to PMML
Converting Scikit-Learn to PMMLConverting Scikit-Learn to PMML
Converting Scikit-Learn to PMMLVillu Ruusmann
 
Java nio ( new io )
Java nio ( new io )Java nio ( new io )
Java nio ( new io )Jemin Patel
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 
What the CRaC - Superfast JVM startup
What the CRaC - Superfast JVM startupWhat the CRaC - Superfast JVM startup
What the CRaC - Superfast JVM startupGerrit Grunwald
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8Knoldus Inc.
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of CompositionScott Wlaschin
 
Java Course 8: I/O, Files and Streams
Java Course 8: I/O, Files and StreamsJava Course 8: I/O, Files and Streams
Java Course 8: I/O, Files and StreamsAnton Keks
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOJorge Vásquez
 

What's hot (20)

Security in PHP - 那些在滲透測試的小技巧
Security in PHP - 那些在滲透測試的小技巧Security in PHP - 那些在滲透測試的小技巧
Security in PHP - 那些在滲透測試的小技巧
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)Lisp Macros in 20 Minutes (Featuring Clojure)
Lisp Macros in 20 Minutes (Featuring Clojure)
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
Java 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & StreamsJava 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & Streams
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
Enterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeEnterprise Tic-Tac-Toe
Enterprise Tic-Tac-Toe
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Java Input Output and File Handling
Java Input Output and File HandlingJava Input Output and File Handling
Java Input Output and File Handling
 
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)
 
Converting Scikit-Learn to PMML
Converting Scikit-Learn to PMMLConverting Scikit-Learn to PMML
Converting Scikit-Learn to PMML
 
Java nio ( new io )
Java nio ( new io )Java nio ( new io )
Java nio ( new io )
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 
Java I/o streams
Java I/o streamsJava I/o streams
Java I/o streams
 
What the CRaC - Superfast JVM startup
What the CRaC - Superfast JVM startupWhat the CRaC - Superfast JVM startup
What the CRaC - Superfast JVM startup
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8
 
Core Java Tutorial
Core Java TutorialCore Java Tutorial
Core Java Tutorial
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of Composition
 
Java Course 8: I/O, Files and Streams
Java Course 8: I/O, Files and StreamsJava Course 8: I/O, Files and Streams
Java Course 8: I/O, Files and Streams
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
 

Similar to Effective Java, Third Edition - Keepin' it Effective

Lambdas & Streams
Lambdas & StreamsLambdas & Streams
Lambdas & StreamsC4Media
 
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...jaxLondonConference
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play frameworkFelipe
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Martin Odersky
 
Interface in java By Dheeraj Kumar Singh
Interface in java By Dheeraj Kumar SinghInterface in java By Dheeraj Kumar Singh
Interface in java By Dheeraj Kumar Singhdheeraj_cse
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java ProgrammersEric Pederson
 
Improved Developer Productivity In JDK8
Improved Developer Productivity In JDK8Improved Developer Productivity In JDK8
Improved Developer Productivity In JDK8Simon Ritter
 
1 Project 2 Introduction - the SeaPort Project seri.docx
1  Project 2 Introduction - the SeaPort Project seri.docx1  Project 2 Introduction - the SeaPort Project seri.docx
1 Project 2 Introduction - the SeaPort Project seri.docxhoney725342
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and StreamsIntroduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and StreamsEmiel Paasschens
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with ScalaNeelkanth Sachdeva
 
Java8: what's new and what's hot
Java8: what's new and what's hotJava8: what's new and what's hot
Java8: what's new and what's hotSergii Maliarov
 
Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8IndicThreads
 
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?Chuk-Munn Lee
 
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVMVoxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVMManuel Bernhardt
 

Similar to Effective Java, Third Edition - Keepin' it Effective (20)

Lambdas & Streams
Lambdas & StreamsLambdas & Streams
Lambdas & Streams
 
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
 
Short intro to scala and the play framework
Short intro to scala and the play frameworkShort intro to scala and the play framework
Short intro to scala and the play framework
 
Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009Scala Talk at FOSDEM 2009
Scala Talk at FOSDEM 2009
 
Colloquium Report
Colloquium ReportColloquium Report
Colloquium Report
 
Java 8
Java 8Java 8
Java 8
 
Interface in java By Dheeraj Kumar Singh
Interface in java By Dheeraj Kumar SinghInterface in java By Dheeraj Kumar Singh
Interface in java By Dheeraj Kumar Singh
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Improved Developer Productivity In JDK8
Improved Developer Productivity In JDK8Improved Developer Productivity In JDK8
Improved Developer Productivity In JDK8
 
1 Project 2 Introduction - the SeaPort Project seri.docx
1  Project 2 Introduction - the SeaPort Project seri.docx1  Project 2 Introduction - the SeaPort Project seri.docx
1 Project 2 Introduction - the SeaPort Project seri.docx
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and StreamsIntroduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
Java8: what's new and what's hot
Java8: what's new and what's hotJava8: what's new and what's hot
Java8: what's new and what's hot
 
Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8
 
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
NUS Hackers Club Mar 21 - Whats New in JavaSE 8?
 
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVMVoxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
 

More from C4Media

Streaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoStreaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoC4Media
 
Next Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileNext Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileC4Media
 
Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020C4Media
 
Understand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsUnderstand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsC4Media
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No KeeperC4Media
 
High Performing Teams Act Like Owners
High Performing Teams Act Like OwnersHigh Performing Teams Act Like Owners
High Performing Teams Act Like OwnersC4Media
 
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaDoes Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaC4Media
 
Service Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideService Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideC4Media
 
Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDC4Media
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine LearningC4Media
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at SpeedC4Media
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsC4Media
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsC4Media
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerC4Media
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleC4Media
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeC4Media
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereC4Media
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing ForC4Media
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data EngineeringC4Media
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreC4Media
 

More from C4Media (20)

Streaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoStreaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live Video
 
Next Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileNext Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy Mobile
 
Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020
 
Understand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsUnderstand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java Applications
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No Keeper
 
High Performing Teams Act Like Owners
High Performing Teams Act Like OwnersHigh Performing Teams Act Like Owners
High Performing Teams Act Like Owners
 
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaDoes Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
 
Service Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideService Meshes- The Ultimate Guide
Service Meshes- The Ultimate Guide
 
Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CD
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine Learning
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at Speed
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep Systems
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.js
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly Compiler
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix Scale
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's Edge
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home Everywhere
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing For
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data Engineering
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
 

Recently uploaded

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 

Recently uploaded (20)

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 

Effective Java, Third Edition - Keepin' it Effective

  • 1. Effective Java, 3/e: keepin’ it effective1 Effective Java, Third Ed. Keepin’ it effective Joshua Bloch @joshbloch
  • 2. InfoQ.com: News & Community Site • 750,000 unique visitors/month • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • News 15-20 / week • Articles 3-4 / week • Presentations (videos) 12-15 / week • Interviews 2-3 / week • Books 1 / month Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ effective-java-third-edition
  • 3. Presented at QCon New York www.qconnewyork.com Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide
  • 4. Effective Java, 3/e: keepin’ it effective2 Effective Java, 3d Ed. is now available! • One new chapter • Fourteen new items • Two retired items • All existing Items thoroughly revised
  • 5. Effective Java, 3/e: keepin’ it effective3 The evolution of Effective Java • First edition: 2001 – 232 pages ─ Java 4 – original language + anonymous classes, asserts, and tons of new APIs • Second edition: 2008 – 315 pages ─ Java 6 – generics, enums, autoboxing, for-each, varargs, concurrency utils • Third edition: 2017 – 366 pages ─ Java 9 – lambdas, streams, optionals, default methods, try-with-resources, modules
  • 6. Effective Java, 3/e: keepin’ it effective4 Outline I. Prefer lambdas to anonymous classes (42) II. Prefer method references to lambdas (43) III. Favor standard functional interfaces (44) IV. Use streams judiciously (45) V. Use caution when making streams parallel (48)
  • 7. Effective Java, 3/e: keepin’ it effective5 I. Prefer lambdas to anonymous classes Historically, anonymous classes for function objects // Best practice as of Java 7 Collections.sort(words, new Comparator<String>() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } }); Adequate for classic OO design patterns, such as Strategy and Command
  • 8. Effective Java, 3/e: keepin’ it effective6 Now there’s a better way Use a lambda Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
  • 9. Effective Java, 3/e: keepin’ it effective7 Now there’s a better way Use a lambda Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length())); Better still – use comparator construction method Collections.sort(words, comparingInt(String::length));
  • 10. Effective Java, 3/e: keepin’ it effective8 Now there’s a better way Use a lambda Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length())); Better still – use comparator construction method Collections.sort(words, comparingInt(String::length)); Even better – also use the sort method on List words.sort(comparingInt(String::length));
  • 11. Effective Java, 3/e: keepin’ it effective9 Under the hood – type inference • When program says: Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length())); • It means: Collections.sort(words, (Comparator<String>) (String s1, String s2) -> Integer.compare(s1.length(), s2.length())); • Type inference is magic ─ No one knows the rules but that’s OK ─ Omit types unless they make program clearer ─ Compiler will tell you if it needs help
  • 12. Effective Java, 3/e: keepin’ it effective10 A caveat regarding type inference • Inference relies on generic type information ─ e.g., words being declared a List<String> ─ Code won’t compile if words is a raw List! • Second edition said “don’t use raw types” ─ Penalty was ugly code and needless runtime bugs • Third edition says it even more strongly ─ Penalty now includes inability to use lambdas properly • You must understand generics to use lambdas
  • 13. Effective Java, 3/e: keepin’ it effective11 Remember this old chestnut? Enum type with constant-specific class bodies and data public enum Operation { PLUS("+") { public double apply(double x, double y) { return x + y; } }, MINUS("-") { public double apply(double x, double y) { return x - y; } }, TIMES("*") { public double apply(double x, double y) { return x * y; } }, DIVIDE("/") { public double apply(double x, double y) { return x / y; } }; private final String symbol; Operation(String symbol) { this.symbol = symbol; } @Override public String toString() { return symbol; } public abstract double apply(double x, double y); }
  • 14. Effective Java, 3/e: keepin’ it effective12 Now there’s a better way Enum with function object field – impractical sans lambdas public enum Operation { PLUS ("+", (x, y) -> x + y), MINUS ("-", (x, y) -> x - y), TIMES ("*", (x, y) -> x * y), DIVIDE("/", (x, y) -> x / y); private final String symbol; private final DoubleBinaryOperator op; Operation(String symbol, DoubleBinaryOperator op) { this.symbol = symbol; this.op = op; } @Override public String toString() { return symbol; } public double apply(double x, double y) { return op.applyAsDouble(x, y); } }
  • 15. Effective Java, 3/e: keepin’ it effective13 Lambda caveats • Lambdas lack names and documentation ─ They should be self-explanatory ─ They should not exceed a few lines; one is best • If lambda would be long or complex: ─ Extract it to method and use method reference ─ Or (for enums) use instance-specific class body • Anonymous classes still have a few uses ─ Lambdas require functional interfaces ─ Lambdas cannot access themselves; in a lambda, this refers to the enclosing instance
  • 16. Effective Java, 3/e: keepin’ it effective14 II. Prefer method references to lambdas • Lambdas are succinct map.merge(key, 1, (count, incr) -> count + incr); • But method references can be more so map.merge(key, 1, Integer::sum); • The more parameters, the bigger the win ─ But parameter names may provide documentation ─ If you use a lambda, choose param names carefully!
  • 17. Effective Java, 3/e: keepin’ it effective15 Occasionally, lambdas are more succinct service.execute(() -> action()); is preferable to service.execute(GoshThisClassNameIsHumongous::action); Lambdas can beat function factories too .flatMap(x -> x); is preferable to .flatMap(Function.identity());
  • 18. Effective Java, 3/e: keepin’ it effective16 Know all five kinds of method references All are at times preferable to lambdas Type Example Lambda Equivalent* Static Integer::parseInt str -> Integer.parseInt(str) Bound Instant.now()::isAfter Instant then = Instant.now(); t -> then.isAfter(t) Unbound String::toLowerCase str -> str.toLowerCase() Class Constructor TreeMap<K,V>::new () -> new TreeMap<K,V>() Array Constructor int[]::new len -> new int[len]
  • 19. Effective Java, 3/e: keepin’ it effective17 The bottom line • (Almost) anything you can do with a method reference, you can also do with a lambda • Method references are usually more succinct • But sometimes lambdas are clearer • Use your best judgment ─ You can always change your mind
  • 20. Effective Java, 3/e: keepin’ it effective18 III. Favor standard functional interfaces Before lambdas, Template Method pattern was common public class Cache<K,V> extends LinkedHashMap<K,V> { final int maxSize; // Set by constructor-omitted for brevity protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { return size() > maxSize; } } Now, Strategy pattern is generally preferable public LinkedHashMap(EldestEntryRemovalFunction<K,V> fn) { ... } // Unnecessary functional interface; use standard one instead! @FunctionalInterface interface EldestEntryRemovalFunction<K,V> { boolean remove(Map<K,V> map, Map.Entry<K,V> eldest); } Map<K,V> cache = new LinkedHashMap((map, eldestEntry) -> map.size() > maxSize);
  • 21. Effective Java, 3/e: keepin’ it effective19 Java has 43 standard functional interfaces Luckily, there is a fair amount of structure BiConsumer<T,U> BiFunction<T,U,R> BinaryOperator<T> BiPredicate<T,U> BooleanSupplier Consumer<T> DoubleBinaryOperator DoubleConsumer DoubleFunction<R> DoublePredicate DoubleSupplier DoubleToIntFunction DoubleToLongFunction DoubleUnaryOperator Function<T,R> IntBinaryOperator IntConsumer IntFunction<R> IntPredicate IntSupplier IntToDoubleFunction IntToLongFunction IntUnaryOperator LongBinaryOperator LongConsumer LongFunction<R> LongPredicate LongSupplier LongToDoubleFunction LongToIntFunction LongUnaryOperator ObjDoubleConsumer<T> ObjIntConsumer<T> ObjLongConsumer<T> Predicate<T> Supplier<T> ToDoubleBiFunction<T,U> ToDoubleFunction<T> ToIntBiFunction<T,U> ToIntFunction<T> ToLongBiFunction<T,U> ToLongFunction<T> UnaryOperator<T>
  • 22. Effective Java, 3/e: keepin’ it effective20 The 6 basic standard functional interfaces Interface Function Signature Example UnaryOperator<T> T apply(T t) String::toLowerCase BinaryOperator<T> T apply(T t1, T t2) BigInteger::add Predicate<T> boolean test(T t) Collection::isEmpty Function<T,R> R apply(T t) Arrays::asList Supplier<T> T get() Instant::now Consumer<T> void accept(T t) System.out::println Most of the remaining 37 interfaces provide support for primitive types. Use them or pay the price!
  • 23. Effective Java, 3/e: keepin’ it effective21 Advantages of using a standard functional interface • Makes APIs easier to learn by reducing conceptual surface area • Provides interoperability benefits ─ Many SFIs provide useful default methods ─ For example, Predicate provides methods to combine and negate predicates • In our LinkedHashMap example: ─ BiPredicate<Map<K,V>, Map.Entry<K,V>> should be used in place of a EldestEntryRemovalFunction<K,V>
  • 24. Effective Java, 3/e: keepin’ it effective22 When shouldn’t you use a standard functional interface? • When none of the standard interfaces apply • But consider Comparator<T> ─ Structurally identical to ToIntBiFunction<T,T> ─ Seems clear that it would have been wrong to use it ─ Why?
  • 25. Effective Java, 3/e: keepin’ it effective23 What's so special about Comparator? • Name provides doc every time it’s used in an API ─ And it's used a lot! • Strong requirements on valid instances ─ Requirements comprise general contract ─ By implementing the interface, you pledge to adhere • Many useful default methods to combine and transform instances ─ Six forms of thenComparing, and reversed
  • 26. Effective Java, 3/e: keepin’ it effective24 Criteria for writing a purpose-built functional interface • Interface should share one or more of these characteristics with Comparator 1. Likely to be commonly used 2. Has a good descriptive name 3. Has a strong contract associated with it 4. Would benefit from default methods • If you write a functional interface, remember, it’s an interface! ─ All interfaces require great care (Item 21)
  • 27. Effective Java, 3/e: keepin’ it effective25 IV. Use streams judiciously Quick review – What is a stream? • A bunch of data objects from a collection, array, input device, etc., for bulk data processing • Processed by a pipeline ─ A single stream generator (data source) ─ Zero or more intermediate stream operations ─ A single terminal stream operation • Supports mostly-functional data processing • Enables painless parallelism ─ Simply replace stream with parallelStream ─ You may or may not see a performance improvement
  • 28. Effective Java, 3/e: keepin’ it effective26 Example – first twenty Mersenne Primes Mersenne number is a number of the form 2p − 1 If p is prime, the corresponding Mersenne number may be prime If it is, it’s a Mersenne prime static Stream<BigInteger> primes() { return Stream.iterate(TWO, BigInteger::nextProbablePrime); } public static void main(String[] args) { primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) .filter(mersenne -> mersenne.isProbablePrime(50)) .limit(20) .forEach(System.out::println); }
  • 29. Effective Java, 3/e: keepin’ it effective27 An iterative program to compute all the anagram groups in a dictionary public static void main(String[] args) throws IOException { File dictionary = new File(args[0]); int minGroupSize = Integer.parseInt(args[1]); Map<String, Set<String>> groups = new HashMap<>(); try (Scanner s = new Scanner(dictionary)) { // Item 9 while (s.hasNext()) { String word = s.next(); groups.computeIfAbsent(alphabetize(word), (unused) -> new TreeSet<>()).add(word); } } for (Set<String> group : groups.values()) if (group.size() >= minGroupSize) System.out.println(group.size() + ": " + group); }
  • 30. Effective Java, 3/e: keepin’ it effective28 Helper function to alphabetize a word Word nerds call the result an alphagram private static String alphabetize(String s) { char[] a = s.toCharArray(); Arrays.sort(a); return new String(a); }
  • 31. Effective Java, 3/e: keepin’ it effective29 Streams gone crazy Just because you can doesn’t mean you should! public class Anagrams { public static void main(String[] args) throws IOException { Path dictionary = Paths.get(args[0]); int minGroupSize = Integer.parseInt(args[1]); try (Stream<String> words = Files.lines(dictionary)) { words.collect( groupingBy(word -> word.chars().sorted() .collect(StringBuilder::new, (sb, c) -> sb.append((char) c), StringBuilder::append).toString())) .values().stream() .filter(group -> group.size() >= minGroupSize) .map(group -> group.size() + ": " + group) .forEach(System.out::println); } } }
  • 32. Effective Java, 3/e: keepin’ it effective30 A happy medium Tasteful use of streams enhances clarity and conciseness public static void main(String[] args) throws IOException { Path dictionary = Paths.get(args[0]); int minGroupSize = Integer.parseInt(args[1]); try (Stream<String> words = Files.lines(dictionary)) { words.collect(groupingBy(word -> alphabetize(word))) .values().stream() .filter(group -> group.size() >= minGroupSize) .forEach(g -> System.out.println(g.size() + ": " + g)); } }
  • 33. Effective Java, 3/e: keepin’ it effective31 Why shouldn’t we use streams to implement alphabetize? • Streams do not offer direct support for char • Resulting implementation would have been ─ more difficult to read ─ more difficult to write correctly ─ probably slower
  • 34. Effective Java, 3/e: keepin’ it effective32 A minipuzzler - what does this print? "Hello world!".chars() .forEach(System.out::print);
  • 35. Effective Java, 3/e: keepin’ it effective33 Puzzler solution "Hello world!".chars() .forEach(System.out::print); Prints 721011081081113211911111410810033 Why does it do this?
  • 36. Effective Java, 3/e: keepin’ it effective34 Puzzler Explanation "Hello world!".chars() .forEach(System.out::print); Prints 721011081081113211911111410810033 String’s chars method returns an IntStream
  • 37. Effective Java, 3/e: keepin’ it effective35 How do you fix it? "Hello world!".chars() .forEach(x -> System.out.print((char) x)); Now prints Hello world Moral Streams only for object ref types, int, long, and double Minor primitive types are missing Type inference can be confusing Avoid using streams for char processing
  • 38. Effective Java, 3/e: keepin’ it effective36 A conundrum – Cartesian product Which is better? // Iterative Cartesian product computation private static List<Card> newDeck() { List<Card> result = new ArrayList<>(); for (Suit suit : Suit.values()) for (Rank rank : Rank.values()) result.add(new Card(suit, rank)); return result; } // Stream-based Cartesian product computation private static List<Card> newDeck() { return Stream.of(Suit.values()) .flatMap(suit -> Stream.of(Rank.values()) .map(rank -> new Card(suit, rank))) .collect(toList()); }
  • 39. Effective Java, 3/e: keepin’ it effective37 The bottom line • Streams are great for many things… ─ But they’re not a panacea • When you first learn streams, you may want to convert all of your loops. Don’t! ─ It may make your code shorter, but not clearer • Exercise judgment ─ Properly used, streams increase brevity and clarity ─ Most programs should combine iteration and streams • It’s not always clear at the outset ─ If you don’t know, take a guess and start hacking ─ If it doesn’t feel right, try the other approach
  • 40. Effective Java, 3/e: keepin’ it effective38 V. Use caution making streams parallel Remember our Mersenne primes program? static Stream<BigInteger> primes() { return Stream.iterate(TWO, BigInteger::nextProbablePrime); } public static void main(String[] args) { primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) .filter(mersenne -> mersenne.isProbablePrime(50)) .limit(20) .forEach(System.out::println); } Runs in 12.5s on my quad-core, 8-thread core i7
  • 41. Effective Java, 3/e: keepin’ it effective39 How fast do you think this program runs? static Stream<BigInteger> primes() { return Stream.iterate(TWO, BigInteger::nextProbablePrime); } public static void main(String[] args) { primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) .parallel() .filter(mersenne -> mersenne.isProbablePrime(50)) .limit(20) .forEach(System.out::println); }
  • 42. Effective Java, 3/e: keepin’ it effective40 How fast do you think this program runs? static Stream<BigInteger> primes() { return Stream.iterate(TWO, BigInteger::nextProbablePrime); } public static void main(String[] args) { primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) .parallel() .filter(mersenne -> mersenne.isProbablePrime(50)) .limit(20) .forEach(System.out::println); } Very, very slowly. I gave up after half an hour.
  • 43. Effective Java, 3/e: keepin’ it effective41 Why did the program run so slowly? • Streams library has no idea how to parallelize it ─ And the heuristics fail miserably • In the best case, parallel unlikely to help if: ─ Stream source is Stream.iterate, or ─ Intermediate limit operation is used • This isn’t the best case ─ Default strategy for limit computes excess elements ─ Each Mersenne prime takes twice as long as last one • Moral: do not parallelize indiscriminately!
  • 44. Effective Java, 3/e: keepin’ it effective42 What does parallelize well? • Arrays, ArrayList, HashMap, HashSet, ConcurrentHashMap, int and long ranges… • What do these sources have in common? ─ Predictably splittable ─ Good locality of reference • Terminal operation also matters ─ Must be quick, or easily parallelizable ─ Best are reductions, e.g., min, max, count, sum ─ Collectors (AKA mutable reductions) not so good • Intermediate operations matter too ─ Mapping and filtering good, limit bad
  • 45. Effective Java, 3/e: keepin’ it effective43 Example – number of primes ≤ n, π(n) static long pi(long n) { return LongStream.rangeClosed(2, n) .mapToObj(BigInteger::valueOf) .filter(i -> i.isProbablePrime(50)) .count(); } Takes 31s to compute π(108) on my machine
  • 46. Effective Java, 3/e: keepin’ it effective44 Example – number of primes ≤ n, π(n) static long pi(long n) { return LongStream.rangeClosed(2, n) .parallel() .mapToObj(BigInteger::valueOf) .filter(i -> i.isProbablePrime(50)) .count(); } In parallel, it takes 9.2s, which is 3.7 times as fast!
  • 47. Effective Java, 3/e: keepin’ it effective45 .parallel() is merely an optimization • Optimize Judiciously (Item 67) • Don’t parallelize unless you can prove it maintains correctness • Don’t parallelize unless you have a good reason to believe it will run faster • Measure performance before and after
  • 48. Effective Java, 3/e: keepin’ it effective46 Conclusion • Java is larger and more complex than it once was • Now a multiparadigm language • Not just how to use features, but which to use • Lambdas and streams can be a big win ─ But you must use them judiciously • With great power comes great responsibility
  • 49. Effective Java, 3/e: keepin’ it effective47 Ask me anything! informit.com Promo Codes • 35% off - BLOCH991 • But check Amazon!
  • 50. Effective Java, 3/e: keepin’ it effective48 Effective Java, Third Ed. Keepin’ it effective Joshua Bloch @joshbloch
  • 51. Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ effective-java-third-edition