SlideShare a Scribd company logo
Trisha Gee (@trisha_gee)
Developer & Technical Advocate, JetBrains
Refactoring to
Java 8
Why Java 8?
It’s Faster
•Performance Improvements in Common Data
Structures
•Fork/Join Speed Improvements
•Changes to Support Concurrency
•…and more
http://bit.ly/refJ8
Easy to Parallelize
Fewer Lines of Code
New Solutions to Problems
Minimizes Errors
Safety Check
Test Coverage
Performance Tests
Decide on the Goals
•Readability
•Fewer lines of code
•Performance
•Learning
Limit the Scope
Morphia
https://github.com/mongodb/morphia
Refactoring to
Lambda Expressions
Automatic Refactoring
•Predicate
•Comparator
•Runnable
•etc…
Abstract classes
Performance of Lambda Expressions
Anonymous Inner Classes vs Lambdas
public String[] decodeWithAnonymousInnerClass(final BenchmarkState state) {
IterHelper.loopMap(state.values, new IterHelper.MapIterCallback<Integer, String>() {
@Override
public void eval(final Integer key, final String value) {
state.arrayOfResults[key] = value;
}
});
return state.arrayOfResults;
}
public void decodeWithLambda(final BenchmarkState state) {
IterHelper.<Integer, String>loopMap(state.values,
(key, value) -> state.arrayOfResults[key] = value) ;
}
0
20
40
60
80
100
120
140
160
180Ops/ms
Anonymous Inner Classes vs Lambdas
Anonymous Inner Class Lambda
http://www.oracle.com/technetwork/java/jvmls2013kuksen-2014088.pdf
0
2
4
6
8
10
12
14
16
18
20
single thread max threads
nsec/op
Performance of Capture
anonymous(static) anonymous(non-static) lambda
Performance Analysis: Lambdas
Designing for Lambda Expressions
Performance of Lazy Evaluation
Logging Performance
public void loggingConstantMessage(BenchmarkState state) {
log("Logging");
}
public void loggingConstantMessageWithLambda(BenchmarkState state) {
log(() -> "Logging");
}
public void loggingVariableMessage(BenchmarkState state) {
log("Logging: " + state.i);
}
public void loggingVariableMessageWithLambda(BenchmarkState state) {
log(() -> "Logging: " + state.i);
}
0
50,000
100,000
150,000
200,000
250,000
300,000
350,000
400,000
450,000
500,000
Constant message Variable message
Ops/ms Logging Performance
Direct call Lambda
Performance Analysis: Lazy Evaluation
Refactoring using
Collections & Streams
For loop to forEach()
…with and without Streams
EntityScanner– forEach()
public void mapAllClassesAnnotatedWithEntity (Morphia m) {
final Reflections r = new Reflections(conf);
final Set<Class<?>> entities = r.getTypesAnnotatedWith(Entity.class);
for (final Class<?> c : entities) {
m.map(c);
}
}
public void mapAllClassesAnnotatedWithEntity(Morphia m) {
new Reflections(conf).getTypesAnnotatedWith(Entity.class).forEach(m::map);
}
0
0.01
0.02
0.03
0.04
0.05
0.06
Ops/ms
EntityScanner – forEach()
original refactored
DatastoreImpl – filter().flatMap().forEach()
0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
Ops/ms
DatastoreImpl
original refactored
DuplicatedAttributeNames – filter().map().forEach()
0
200
400
600
800
1000
1200
Ops/ms
DuplicatedAttributeNames
original refactored
Performance Analysis: forEach()
For loop to collect()
BasicDAO – map & collect
public List originalIterationCode() {
final List<Object> ids = new ArrayList<>(keys.size() * 2)
for (final Key<Object> key : keys) {
ids.add(key.getId());
}
return ids;
}
public List simplifiedIterationCode() {
final List<Object> ids = new ArrayList<>()
for (final Key<Object> key : keys) {
ids.add(key.getId());
}
return ids;
}
public List refactoredCode() {
return keys.stream()
.map(Key::getId)
.collect(toList());
0
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
Ops/s BasicDAO – map().collect() - 10 elements
original simplified refactored parallel
0
0.5
1
1.5
2
2.5
3
3.5
Ops/s BasicDAO – map().collect() - 10 000 element
original simplified refactored parallel
ReflectionUtils
public static List<Field> original(final Field[] fields, final boolean returnFinalFields) {
final List<Field> validFields = new ArrayList<Field>();
// we ignore static and final fields
for (final Field field : fields) {
if (!Modifier.isStatic(field.getModifiers()) && (returnFinalFields || !Modifier.isFinal(field.getModifiers()))) {
validFields.add(field);
}
}
return validFields;
}
public static List<Field> refactored(final Field[] fields, final boolean returnFinalFields) {
return Arrays.stream(fields)
.filter(field -> isNotStaticOrFinal(returnFinalFields, field))
.collect(Collectors.toList());
}
0
2000
4000
6000
8000
10000
12000
14000
AxisTitle ReflectionUtils – Arrays.stream().map().collect()
original refactored
Performance Analysis: collect()
Collapsing multiple operations
MappingValidator – single stream operation
0
1
2
3
4
5
6
7
8
9
10
EntityWithOneError EntityWith10Errors EntityWith20Errors
Ops/s Mapping Validator - multiple operations
original refactored
QueryImpl – multiple operations
public String[] retrieveKnownFields(org.mongodb.morphia.DatastoreImpl ds, Class clazz) {
final MappedClass mc = ds.getMapper().getMappedClass(clazz);
final List<String> fields = new ArrayList<String>(mc.getPersistenceFields().size() + 1);
for (final MappedField mf : mc.getPersistenceFields()) {
fields.add(mf.getNameToStore());
}
return fields.toArray(new String[fields.size()]);
}
public String[] retrieveKnownFieldsRefactored(org.mongodb.morphia.DatastoreImpl ds, Class clazz) {
final MappedClass mc = ds.getMapper().getMappedClass(clazz);
return mc.getPersistenceFields()
.stream()
.map(MappedField::getNameToStore)
.collect(Collectors.toList())
.toArray(new String[0]);
}
public String[] retrieveKnownFields(org.mongodb.morphia.DatastoreImpl ds, Class clazz) {
final MappedClass mc = ds.getMapper().getMappedClass(clazz);
return mc.getPersistenceFields()
.stream()
.map(MappedField::getNameToStore)
.toArray(String[]::new);
}
0
500
1000
1500
2000
2500
3000
3500
4000
Ops/s QueryImpl - multiple operations
original simplified refactored refactoredMore
Performance Analysis: Multiple Operations
For loop to anyMatch()
TypeConverter – anyMatch()
protected boolean oneOfClasses(final Class f, final Class[] classes) {
for (final Class c : classes) {
if (c.equals(f)) {
return true;
}
}
return false;
}
protected boolean oneOfClasses(final Class f, final Class[] classes) {
return Arrays.stream(classes)
.anyMatch(c -> c.equals(f));
}
protected boolean oneOfClasses(final Class f, final Class[] classes) {
return Arrays.stream(classes)
.parallel()
.anyMatch(c -> c.equals(f));
}
0
10000
20000
30000
40000
50000
60000
70000
Ops/s TypeConverter – anyMatch() – 10 Values
original refactored parallel
0
20
40
60
80
100
120
140
TypeConverter – anyMatch() – 10 000 Values
original refactored parallel
0
2
4
6
8
10
12
14
TypeConverter – anyMatch() – 100 000 Values
original refactored parallel
Performance Analysis: anyMatch()
Performance Analysis: Arrays.stream()
For loop to findFirst()
MapreduceType – IntStream().map().filter().findFirst()
0
5000
10000
15000
20000
25000
30000
AxisTitle MapreduceType - IntStream().map().filter().findFirst()
original refactored
Mapper – findFirst()
public static Class<? extends Annotation> original(final MappedField mf) {
Class<? extends Annotation> annType = null;
for (final Class<? extends Annotation> testType : new Class[]{Property.class, Embedded.class, Serialized.class, Reference.c
if (mf.hasAnnotation(testType)) {
annType = testType;
break;
}
}
return annType;
}
public static Class<? extends Annotation> refactored(final MappedField mf) {
return (Class<? extends Annotation>) Arrays.stream(new Class[]{Property.class, Embedded.class, Serialized.class, Referenc
.filter(mf::hasAnnotation)
.findFirst()
.orElse(null);
}
public static Class<? extends Annotation> refactoredMore(final MappedField mf) {
return (Class<? extends Annotation>) Stream.of(Property.class, Embedded.class, Serialized.class, Reference.class)
.filter(mf::hasAnnotation)
.findFirst()
.orElse(null);
}
0
5000
10000
15000
20000
25000
30000
35000
40000
45000
50000
Ops/s Mapper – Arrays.stream().filter().findFirst()
original refactored more
Converters – stream().findFirst()
0
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
Ops/s Converters - stream().filter().findFirst() – 10 Elements
original refactored parallel
0
0.5
1
1.5
2
2.5
3
3.5
Ops/s Converters – stream().filter().findFirst() – 10 000 elements
original refactored parallel
Performance Analysis: findFirst()
Use removeIf()
EntityScanner – removeIf()
0
10
20
30
40
50
60
Ops/s EntityScanner - removeIf()
original refactored
Performance Analysis: removeIf()
Summary of Findings
Refactoring to use lambda expressions is
easy to automate…
0
20
40
60
80
100
120
140
160
180
Ops/ms …and pretty safe performance-wise
Anonymous Inner Class Lambda
Designing for lambda expressions could
give a big performance benefit
0
50,000
100,000
150,000
200,000
250,000
300,000
350,000
400,000
450,000
500,000
Constant message Variable message
Ops/ms Logging Performance
Direct call Lambda
Generally the new idioms increase
readability
Anonymous Inner Classes vs Lambdas
EntityScanner – forEach()
public List originalIterationCode() {
final List<Object> ids = new ArrayList<>(keys.size() * 2)
for (final Key<Object> key : keys) {
ids.add(key.getId());
}
return ids;
}
public List refactoredCode() {
return keys.stream()
.map(Key::getId)
.collect(toList());
BasicDAO – map().collect()
protected boolean oneOfClasses(final Class f, final Class[] classes) {
for (final Class c : classes) {
if (c.equals(f)) {
return true;
}
}
return false;
}
protected boolean oneOfClasses(final Class f, final Class[] classes) {
return Arrays.stream(classes)
.anyMatch(c -> c.equals(f));
}
TypeConverter – anyMatch()
public static Class<? extends Annotation> original(final MappedField mf) {
Class<? extends Annotation> annType = null;
for (final Class<? extends Annotation> testType : new Class[]{Property.class, Embedded.class, Serialized.class, Reference.c
if (mf.hasAnnotation(testType)) {
annType = testType;
break;
}
}
return annType;
}
public static Class<? extends Annotation> refactoredMore(final MappedField mf) {
return (Class<? extends Annotation>) Stream.of(Property.class, Embedded.class, Serialized.class, Reference.class)
.filter(mf::hasAnnotation)
.findFirst()
.orElse(null);
}
Mapper – findFirst()
EntityScanner – removeIf()
Particularly with multiple operations
MappingValidator – single stream operation
QueryImpl – multiple operations
But be aware of performance
Arrays.stream() is probably
substantially slower than using an array
0
10000
20000
30000
40000
50000
60000
70000
Ops/s TypeConverter - 10 Values
original refactored parallel
Using forEach() or collect() may be
slower than iterating over a collection
0
200
400
600
800
1000
1200
Ops/ms
DuplicatedAttributeNames
original refactored
Parallel is probably not going to give you
speed improvements
Unless your data is very big
0
0.5
1
1.5
2
2.5
3
3.5
Ops/s BasicDAO – map().collect() - 10 000 element
original simplified refactored parallel
Parallel is probably not going to give you
speed improvements
Or your operation is very expensive
But sometimes you get improved
readability and better performance
0
10
20
30
40
50
60
Ops/s EntityScanner - removeIf()
original refactored
Conclusion
Should you migrate your code to Java 8?
It Depends
Always remember what your goal is
And compare results to it
Understand what may impact performance
And if in doubt, measure
Your tools can help you
But you need to apply your brain too
http://bit.ly/refJ8
@trisha_gee

More Related Content

What's hot

Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()daewon jeong
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerMario Fusco
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
 
Java 8 lambda expressions
Java 8 lambda expressionsJava 8 lambda expressions
Java 8 lambda expressionsLogan Chien
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and UtilitiesPramod Kumar
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongMario Fusco
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.David Gómez García
 
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions OCP Java SE 8 Exam - Sample Questions - Lambda Expressions
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions Ganesh Samarthyam
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesGanesh Samarthyam
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Chris Richardson
 
Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.Vadim Dubs
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeletonIram Ramrajkar
 

What's hot (20)

Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Java 8 lambda expressions
Java 8 lambda expressionsJava 8 lambda expressions
Java 8 lambda expressions
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Monadic Java
Monadic JavaMonadic Java
Monadic Java
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
 
Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.Java 8 Stream API. A different way to process collections.
Java 8 Stream API. A different way to process collections.
 
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions OCP Java SE 8 Exam - Sample Questions - Lambda Expressions
OCP Java SE 8 Exam - Sample Questions - Lambda Expressions
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Java 8 Streams
Java 8 StreamsJava 8 Streams
Java 8 Streams
 
Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.
 
Advance Java Programs skeleton
Advance Java Programs skeletonAdvance Java Programs skeleton
Advance Java Programs skeleton
 
Java programming-examples
Java programming-examplesJava programming-examples
Java programming-examples
 

Similar to Refactoring to Java 8 (Devoxx BE)

Creat Shape classes from scratch DETAILS You will create 3 shape cla.pdf
Creat Shape classes from scratch DETAILS You will create 3 shape cla.pdfCreat Shape classes from scratch DETAILS You will create 3 shape cla.pdf
Creat Shape classes from scratch DETAILS You will create 3 shape cla.pdfaromanets
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalUrs Peter
 
Is java8 a true functional programming language
Is java8 a true functional programming languageIs java8 a true functional programming language
Is java8 a true functional programming languageSQLI
 
Is java8a truefunctionallanguage
Is java8a truefunctionallanguageIs java8a truefunctionallanguage
Is java8a truefunctionallanguageSamir Chekkal
 
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Yann-Gaël Guéhéneuc
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...Akaks
 
Java8: Language Enhancements
Java8: Language EnhancementsJava8: Language Enhancements
Java8: Language EnhancementsYuriy Bondaruk
 
Flink Batch Processing and Iterations
Flink Batch Processing and IterationsFlink Batch Processing and Iterations
Flink Batch Processing and IterationsSameer Wadkar
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In JavaAndrei Solntsev
 
Come on, PHP 5.4!
Come on, PHP 5.4!Come on, PHP 5.4!
Come on, PHP 5.4!paulgao
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Codemotion
 
Getting Started with Regular Expressions In MarcEdit
Getting Started with Regular Expressions In MarcEditGetting Started with Regular Expressions In MarcEdit
Getting Started with Regular Expressions In MarcEditTerry Reese
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard LibraryNelson Glauber Leal
 
Functions in C++
Functions in C++Functions in C++
Functions in C++home
 
QTP Automation Testing Tutorial 7
QTP Automation Testing Tutorial 7QTP Automation Testing Tutorial 7
QTP Automation Testing Tutorial 7Akash Tyagi
 

Similar to Refactoring to Java 8 (Devoxx BE) (20)

Java 8 Feature Preview
Java 8 Feature PreviewJava 8 Feature Preview
Java 8 Feature Preview
 
Creat Shape classes from scratch DETAILS You will create 3 shape cla.pdf
Creat Shape classes from scratch DETAILS You will create 3 shape cla.pdfCreat Shape classes from scratch DETAILS You will create 3 shape cla.pdf
Creat Shape classes from scratch DETAILS You will create 3 shape cla.pdf
 
Lambdas and Laughs
Lambdas and LaughsLambdas and Laughs
Lambdas and Laughs
 
Xebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_finalXebicon2013 scala vsjava_final
Xebicon2013 scala vsjava_final
 
Major Java 8 features
Major Java 8 featuresMajor Java 8 features
Major Java 8 features
 
Is java8 a true functional programming language
Is java8 a true functional programming languageIs java8 a true functional programming language
Is java8 a true functional programming language
 
Is java8a truefunctionallanguage
Is java8a truefunctionallanguageIs java8a truefunctionallanguage
Is java8a truefunctionallanguage
 
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
 
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
 
Java8: Language Enhancements
Java8: Language EnhancementsJava8: Language Enhancements
Java8: Language Enhancements
 
Flink Batch Processing and Iterations
Flink Batch Processing and IterationsFlink Batch Processing and Iterations
Flink Batch Processing and Iterations
 
Functional Programming In Java
Functional Programming In JavaFunctional Programming In Java
Functional Programming In Java
 
Come on, PHP 5.4!
Come on, PHP 5.4!Come on, PHP 5.4!
Come on, PHP 5.4!
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Practical cats
Practical catsPractical cats
Practical cats
 
Getting Started with Regular Expressions In MarcEdit
Getting Started with Regular Expressions In MarcEditGetting Started with Regular Expressions In MarcEdit
Getting Started with Regular Expressions In MarcEdit
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
 
Functions in C++
Functions in C++Functions in C++
Functions in C++
 
QTP Automation Testing Tutorial 7
QTP Automation Testing Tutorial 7QTP Automation Testing Tutorial 7
QTP Automation Testing Tutorial 7
 

More from Trisha Gee

Career Advice for Architects
Career Advice for Architects Career Advice for Architects
Career Advice for Architects Trisha Gee
 
Is boilerplate code really so bad?
Is boilerplate code really so bad?Is boilerplate code really so bad?
Is boilerplate code really so bad?Trisha Gee
 
Code Review Best Practices
Code Review Best PracticesCode Review Best Practices
Code Review Best PracticesTrisha Gee
 
Career Advice for Programmers - ProgNET London
Career Advice for Programmers - ProgNET LondonCareer Advice for Programmers - ProgNET London
Career Advice for Programmers - ProgNET LondonTrisha Gee
 
Is Boilerplate Code Really So Bad?
Is Boilerplate Code Really So Bad?Is Boilerplate Code Really So Bad?
Is Boilerplate Code Really So Bad?Trisha Gee
 
Real World Java 9 - JetBrains Webinar
Real World Java 9 - JetBrains WebinarReal World Java 9 - JetBrains Webinar
Real World Java 9 - JetBrains WebinarTrisha Gee
 
Real World Java 9
Real World Java 9Real World Java 9
Real World Java 9Trisha Gee
 
Real World Java 9
Real World Java 9Real World Java 9
Real World Java 9Trisha Gee
 
Career Advice for Programmers
Career Advice for Programmers Career Advice for Programmers
Career Advice for Programmers Trisha Gee
 
Real World Java 9
Real World Java 9Real World Java 9
Real World Java 9Trisha Gee
 
Becoming fully buzzword compliant
Becoming fully buzzword compliantBecoming fully buzzword compliant
Becoming fully buzzword compliantTrisha Gee
 
Real World Java 9 (QCon London)
Real World Java 9 (QCon London)Real World Java 9 (QCon London)
Real World Java 9 (QCon London)Trisha Gee
 
Java 9 Functionality and Tooling
Java 9 Functionality and ToolingJava 9 Functionality and Tooling
Java 9 Functionality and ToolingTrisha Gee
 
Java 8 and 9 in Anger
Java 8 and 9 in AngerJava 8 and 9 in Anger
Java 8 and 9 in AngerTrisha Gee
 
Migrating to IntelliJ IDEA from Eclipse
Migrating to IntelliJ IDEA from EclipseMigrating to IntelliJ IDEA from Eclipse
Migrating to IntelliJ IDEA from EclipseTrisha Gee
 
Code Review Matters and Manners
Code Review Matters and MannersCode Review Matters and Manners
Code Review Matters and MannersTrisha Gee
 
Refactoring to Java 8 (QCon New York)
Refactoring to Java 8 (QCon New York)Refactoring to Java 8 (QCon New York)
Refactoring to Java 8 (QCon New York)Trisha Gee
 
Refactoring to Java 8 (Devoxx UK)
Refactoring to Java 8 (Devoxx UK)Refactoring to Java 8 (Devoxx UK)
Refactoring to Java 8 (Devoxx UK)Trisha Gee
 
Staying Ahead of the Curve
Staying Ahead of the CurveStaying Ahead of the Curve
Staying Ahead of the CurveTrisha Gee
 
Level Up Your Automated Tests
Level Up Your Automated TestsLevel Up Your Automated Tests
Level Up Your Automated TestsTrisha Gee
 

More from Trisha Gee (20)

Career Advice for Architects
Career Advice for Architects Career Advice for Architects
Career Advice for Architects
 
Is boilerplate code really so bad?
Is boilerplate code really so bad?Is boilerplate code really so bad?
Is boilerplate code really so bad?
 
Code Review Best Practices
Code Review Best PracticesCode Review Best Practices
Code Review Best Practices
 
Career Advice for Programmers - ProgNET London
Career Advice for Programmers - ProgNET LondonCareer Advice for Programmers - ProgNET London
Career Advice for Programmers - ProgNET London
 
Is Boilerplate Code Really So Bad?
Is Boilerplate Code Really So Bad?Is Boilerplate Code Really So Bad?
Is Boilerplate Code Really So Bad?
 
Real World Java 9 - JetBrains Webinar
Real World Java 9 - JetBrains WebinarReal World Java 9 - JetBrains Webinar
Real World Java 9 - JetBrains Webinar
 
Real World Java 9
Real World Java 9Real World Java 9
Real World Java 9
 
Real World Java 9
Real World Java 9Real World Java 9
Real World Java 9
 
Career Advice for Programmers
Career Advice for Programmers Career Advice for Programmers
Career Advice for Programmers
 
Real World Java 9
Real World Java 9Real World Java 9
Real World Java 9
 
Becoming fully buzzword compliant
Becoming fully buzzword compliantBecoming fully buzzword compliant
Becoming fully buzzword compliant
 
Real World Java 9 (QCon London)
Real World Java 9 (QCon London)Real World Java 9 (QCon London)
Real World Java 9 (QCon London)
 
Java 9 Functionality and Tooling
Java 9 Functionality and ToolingJava 9 Functionality and Tooling
Java 9 Functionality and Tooling
 
Java 8 and 9 in Anger
Java 8 and 9 in AngerJava 8 and 9 in Anger
Java 8 and 9 in Anger
 
Migrating to IntelliJ IDEA from Eclipse
Migrating to IntelliJ IDEA from EclipseMigrating to IntelliJ IDEA from Eclipse
Migrating to IntelliJ IDEA from Eclipse
 
Code Review Matters and Manners
Code Review Matters and MannersCode Review Matters and Manners
Code Review Matters and Manners
 
Refactoring to Java 8 (QCon New York)
Refactoring to Java 8 (QCon New York)Refactoring to Java 8 (QCon New York)
Refactoring to Java 8 (QCon New York)
 
Refactoring to Java 8 (Devoxx UK)
Refactoring to Java 8 (Devoxx UK)Refactoring to Java 8 (Devoxx UK)
Refactoring to Java 8 (Devoxx UK)
 
Staying Ahead of the Curve
Staying Ahead of the CurveStaying Ahead of the Curve
Staying Ahead of the Curve
 
Level Up Your Automated Tests
Level Up Your Automated TestsLevel Up Your Automated Tests
Level Up Your Automated Tests
 

Recently uploaded

AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...Product School
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlPeter Udo Diehl
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™UiPathCommunity
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...Product School
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualityInflectra
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsDorra BARTAGUIZ
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Product School
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Thierry Lestable
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Product School
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Frank van Harmelen
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaRTTS
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backElena Simperl
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupCatarinaPereira64715
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...Elena Simperl
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonDianaGray10
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingThijs Feryn
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewPrayukth K V
 

Recently uploaded (20)

AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 

Refactoring to Java 8 (Devoxx BE)