JDK8: encounter of eight kind
@ladislavGazo
gazo@seges.sk
JDK6
(2006 - 2015)
But what were the features?
- Collections framework
- Deployment
- Drag and drop
- Instrumentation
- Internationalization support
- I/O support
- ... blah blah blah
Boring stuff
x -> x + 1
Function<Integer, Integer> add = x -> x + 1;
Integer result = add.apply(4);
And what if one exists?
Function<Integer, Integer> add = MathUtils::add;
java.util.function
notable:
- Consumer<T>
- R accept(T)
- Supplier<R>
- R get()
- Predicate<T>
- boolean test(T), and, or,...
- BiFunction
- BiConsumer
- ...
EX: Functional Setting
- calculate current user and if not empty, set it
- without object hell
- not to repeat everywhere this:
String username = Session.getCurrentUsername();
if(username != null || !username.isEmpty()) {
map.put(key, username);
}
and again, but different
String username = Session.getCurrentUsername();
if(username != null || !username.isEmpty()) {
manager.call(username);
}
WHAT about this?
securityManager.setCurrentUsername(
user -> variables.put(ProcessVariableConstant.USERNAME, user)
);
First Iteration
reminds OO-approach a bit
public class SecurityManager {
...
public void setCurrentUsername(VoidFunction f) {
String username = getCurrentUsername();
if(username != null || !username.isEmpty()) {
f.run(username);
}
}
@FunctionalInterface
public interface VoidFunction {
void run(T input);
}
}
Functional Sugar
public class SecurityManager {
...
public void setCurrentUsername(Consumer f) {
String username = getCurrentUsername();
if(username != null || !username.isEmpty()) {
f.accept(username);
}
}
}
Optionals
- for avoiding NPEs where possible
- use:
- as return type of function
- not as:
- method || constructor parameter
- model objects
Optional<Integer> userId = repository.findOne("john");
Initialization
Optional opt = Optional.of(nonNullInteger);
Optional opt = Optional.ofNullable(possiblyNullInteger);
Optional empty = Optional.empty();
Handy Usage
if ( opt.isPresent() ) {
service.store(opt.orElse(new UserAccount()));
}
or more functional
opt.ifPresent( obj -> service.store(obj.get()) );
TRANSFORMATION
List<FormProcessDefinition> processDefinitions = form.getProcessDefinitions();
a.k.a. MAP
processDefinitions.stream().map((definition) -> {
ProcessDefinition processDefinition = new ProcessDefinition();
processDefinition.setKey(definition.getKey());
processDefinition.setName(definition.getName());
return processDefinition;
}).collect(Collectors.toList());
For each as stream???
Set<String> roleSystemNames = getRequiredRoleNames();
roleSystemNames.
forEach(roleSystemName -> {
...
});
or if function exists for that
Set roleSystemNames = getRequiredRoleNames();
roleSystemNames.forEach(service::store);
& sometimes it's unreadable
Map
For simple For-each
Map<String, JSONObject> jsonVariables = new HashMap<>();
variables.forEach((k, v) -> {
jsonVariables.put(k, createTypedValue(v));
});
but maybe for parallel processing
Stream will be more efficient
!
FILES
with streams
=
more pleasure
Files.list(new File(".").toPath())
.filter(p -> !p.getFileName().toString().startsWith("."))
.limit(3)
.forEach(System.out::println);
... and reduce ... and limit example
FILE PROCESSING is scary
try {
FileInputStream fstream = new FileInputStream("textfile.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
...
}
in.close();
}catch (Exception e) {
...
}
... Not anymore
try (Stream<String> stream = Files.lines(Paths.get("my.json"))) {
stream
.filter(line -> line.contains("name"))
.map(String::trim)
.forEach(System.out::println);
}
... with automatic file closing ...
Strings & Patterns
String.join(":","Java","Group","2015");
// Java:Group:2015
Pattern pattern = Pattern.compile(".*@seges\\.sk");
Stream.of("gazo@seges.sk", "john@hotmail.com")
.filter(pattern.asPredicate())
.count();
// 1
Pattern.compile(";")
.splitAsStream("javagroup;java;group")
.filter(s -> s.contains("group"))
.sorted()
.collect(Collectors.joining(":"));
// => group:javagroup
SQL Parallels
Questions?
@ladislavGazo
gazo@seges.sk
JDK8 encounter of eight kind
By lgazo
JDK8 encounter of eight kind
How the change from JDK6 enlightens developers when they face JDK8 functional approach.
- 1,157