public class AnonymousInnerClassTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("A thread created and running ...");
}
}).start();
}
}
public class AnonymousInnerClassTest {
public static void main(String[] args) {
new Thread(() ->
System.out.println("A thread created and running ..."))
.start();
}
}
public class Program {
public static void main(String[] args) {
new Thread(Program::printThreadCreatedMessage).start();
}
public static void printThreadCreatedMessage() {
System.out.println("A thread created and running ...");
}
}
Divided the water under the dome from the water above
@FunctionalInterface
public interface Runnable {
void run();
}
Any interface with just one method unimplemented (do'nt forget there are default methods now) will work
public class Program {
public static void main(String[] args) {
Arrays.asList("Saar", "Efes", ";)").stream()
.map(String::length).forEach(System.out::println);
}
}
of an arbitrary object of a particular type
public class Program {
public static void main(String[] args) {
Program program = new Program();
new Thread(program::aRunnablePossibleMethod).start();
}
public void aRunnablePossibleMethod() {
System.out.println("A thread created and running ...");
}
}
of a particular object
public class Program {
public static void main(String[] args) {
Arrays.asList("Saar", "Efes", ";)").stream()
.map(Integer::valueOf).forEach(System.out::println);
}
}
public class Program {
public static void main(String[] args) {
Integer willReturnOne = Optional.of(1)
.orElseThrow(IllegalAccessException::new);
}
}
public class AnonymousInnerClassTest {
public static void main(String[] args) {
Integer willReturnOne = Optional.of(1)
.orElseThrow(() -> new IllegalAccessException());
}
}
104 lines including imports
public final class Optional<T> {
private final T value;
public static <T> Optional<T> empty();
public static <T> Optional<T> of(T arg);
public static <T> Optional<T> ofNullable(T arg);
public T get();
public boolean isPresent();
public void ifPresent(Consumer<? super T> arg0);
public Optional<T> filter(Predicate<? super T> arg0);
public <U> Optional<U> map(Function<? super T, ? extends U> arg0);
public <U> Optional<U> flatMap(Function<? super T, Optional<U>> arg0);
public T orElse(T arg0);
public T orElseGet(Supplier<? extends T> arg0);
public <X extends Throwable> T orElseThrow(Supplier<? extends X> arg0) throws X;
}
Any reader or consumer of an API will be beaten over the head with the fact that there might be nothing there and that a check is necessary before accessing the value.
public class Program {
private static MeshekService meshekService;
public static void main(String[] args) {
Optional<Meshek> aMeshek = meshekService.findOne(meshekId);
return aMeshek.orElseThrow(WrongIdGivenException::new);
}
}
Without Optional the meaning of a null occurrence is unclear:
Now nothing can be null anymore. Whether with annotations, assertions or plain checks, you never have to think about whether this argument or that return type can be null. It can't!
String version = "UNKNOWN";
if(computer != null){
Soundcard soundcard = computer.getSoundcard();
if(soundcard != null){
USB usb = soundcard.getUSB();
if(usb != null){
version = usb.getVersion();
}
}
}
String usbVersion = computer
.flatMap(Computer::getSoundcard)
.flatMap(Soundcard::getUSB)
.map(USB::getVersion)
.orElse("UNKNOWN");
String usbVersion =
computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";
C#
C#
C#
C#
C#
C#
C#
C#
C#
C#
C#
C#
Arrays.asList("a1", "a2", "b1", "c2", "c1")
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
// Prints:
// C1
// C2
Stream.of("d2", "a2", "b1", "b3", "c")
.map(s -> {
System.out.println("map: " + s);
return s.toUpperCase();
})
.anyMatch(s -> {
System.out.println("anyMatch: " + s);
return s.startsWith("A");
});
// Prints:
// map: d2
// anyMatch: D2
// map: a2
// anyMatch: A2
Stream.of("d2", "a2", "b1", "b3", "c")
.sorted((s1, s2) -> {
System.out.printf("sort: %s; %s\n", s1, s2);
return s1.compareTo(s2);
})
.filter(s -> {
System.out.println("filter: " + s);
return s.startsWith("a");
})
.map(s -> {
System.out.println("map: " + s);
return s.toUpperCase();
})
.forEach(s -> System.out.println("forEach: " + s));
// sort: a2; d2
// sort: b1; a2
// sort: b1; d2
// sort: b1; a2
// sort: b3; b1
// sort: b3; d2
// sort: c; b3
// sort: c; d2
// filter: a2
// map: a2
// forEach: A2
// filter: b1
// filter: b3
// filter: c
// filter: d2
Streams can be executed in parallel to increase runtime performance on large amount of input elements. Parallel streams use a common ForkJoinPool...
Arrays.asList("a1", "a2", "b1", "c2", "c1")
.parallelStream()
.filter(s -> {
System.out.format("filter: %s [%s]\n",
s, Thread.currentThread().getName());
return true;
})
.map(s -> {
System.out.format("map: %s [%s]\n",
s, Thread.currentThread().getName());
return s.toUpperCase();
})
.forEach(s -> System.out.format("forEach: %s [%s]\n",
s, Thread.currentThread().getName()));
filter: b1 [main]
filter: a2 [ForkJoinPool.commonPool-worker-1]
map: a2 [ForkJoinPool.commonPool-worker-1]
filter: c2 [ForkJoinPool.commonPool-worker-3]
map: c2 [ForkJoinPool.commonPool-worker-3]
filter: c1 [ForkJoinPool.commonPool-worker-2]
map: c1 [ForkJoinPool.commonPool-worker-2]
forEach: C2 [ForkJoinPool.commonPool-worker-3]
forEach: A2 [ForkJoinPool.commonPool-worker-1]
map: b1 [main]
forEach: B1 [main]
filter: a1 [ForkJoinPool.commonPool-worker-3]
map: a1 [ForkJoinPool.commonPool-worker-3]
forEach: A1 [ForkJoinPool.commonPool-worker-3]
forEach: C1 [ForkJoinPool.commonPool-worker-2]
IntSummaryStatistics ageSummary =
persons
.stream()
.collect(Collectors.summarizingInt(p -> p.age));
System.out.println(ageSummary);
// Prints:
// IntSummaryStatistics{count=4, sum=76, min=12,
// average=19.000000, max=23}
Map<Integer, List<Person>> personsByAge = persons
.stream()
.collect(Collectors.groupingBy(p -> p.age));
personsByAge
.forEach((age, p) ->
System.out.format("age %s: %s\n", age, p));
// Prints:
// age 18: [Max]
// age 23: [Peter, Pamela]
// age 12: [David]
String phrase = persons
.stream()
.filter(p -> p.age >= 18)
.map(p -> p.name)
.collect(Collectors.joining(" and ", "In Germany ",
" are of legal age."));
System.out.println(phrase);
// Prints:
// In Germany Max and Peter and Pamela are of legal age.
String phrase = persons
.stream()
.filter(p -> p.age >= 18)
.map(p -> p.name)
.collect(Collectors.joining(" and ", "In Germany ",
" are of legal age."));
System.out.println(phrase);
// Prints:
// In Germany Max and Peter and Pamela are of legal age.
Collector<Person, StringJoiner, String> personNameCollector =
Collector.of(
() -> new StringJoiner(" | "), // supplier
(j, p) -> j.add(p.name.toUpperCase()), // accumulator
(j1, j2) -> j1.merge(j2), // combiner
StringJoiner::toString); // finisher
String names = persons
.stream()
.collect(personNameCollector);
System.out.println(names); // MAX | PETER | PAMELA | DAVID