Last active
August 29, 2015 13:57
-
-
Save athieriot/9749375 to your computer and use it in GitHub Desktop.
Java 8 features overview
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.script.ScriptEngine; | |
import javax.script.ScriptEngineManager; | |
import javax.script.ScriptException; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.math.BigInteger; | |
import java.nio.file.Files; | |
import java.nio.file.Paths; | |
import java.time.*; | |
import java.time.format.DateTimeFormatter; | |
import java.time.temporal.ChronoUnit; | |
import java.time.temporal.TemporalField; | |
import java.time.temporal.TemporalUnit; | |
import java.util.*; | |
import java.util.function.Function; | |
import java.util.function.Predicate; | |
import java.util.function.Supplier; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
import static java.time.LocalTime.now; | |
import static java.util.Arrays.asList; | |
public class Java8 { | |
public static Object samples() { | |
/* ************** */ | |
/* Project Lambda */ | |
/* ************** */ | |
/* Lambda expressions */ | |
// Shortcut for Anonymous Classes (But use InvokeDynamics on the background) | |
// Declaring the types of the parameters is optional. (Inference !!!) | |
// Using parentheses around the parameter is optional if you have only one parameter. | |
// Using curly braces is optional (unless you need multiple statements). | |
// The “return” keyword is optional if you have a single expression that returns a value. | |
// Lambdas can refer to final or "effectively final" variables */ | |
/* | |
() -> System.out.println(this) | |
(String str) -> System.out.println(str) | |
str -> System.out.println(str) | |
(String s1, String s2) -> { return s2.length() - s1.length(); } | |
(s1, s2) -> s2.length() - s1.length() | |
*/ | |
List<String> wordList = Arrays.<String>asList("word", "letter", "a", "big sentence"); | |
/* Before */ | |
Collections.sort(wordList, new Comparator<String>() { | |
@Override | |
public int compare(String s1, String s2) { | |
return s1.length() - s2.length(); | |
} | |
}); | |
/* After */ | |
Collections.sort(wordList, | |
(s1, s2) -> s1.length() - s2.length() | |
); | |
/* Proof */ | |
Comparator<String> byLength = (String s1, String s2) -> s1.length() - s2.length(); | |
Collections.sort(wordList, byLength); | |
return wordList; | |
/* Method references */ | |
// // You can refer to existing methods | |
// // Static methods. | |
// // Instance methods. | |
// // Methods on particular instances. | |
// // Constructors (ie. TreeSet::new). | |
// | |
// try { | |
// Files.lines(Paths.get("/tmp/test")).forEach(System.out::println); | |
// | |
// } catch (IOException e) { | |
// return e.getLocalizedMessage(); | |
// } | |
// | |
// return "End of file"; | |
/* Functional Interfaces (What can be use for Lambda) */ | |
// // Defined any Interfaces with exactly one (non default) method | |
// // It can be any Interface, not only Java 8 | |
// // But can by enforced at compile time by annotation: @FunctionalInterface | |
// | |
// Supplier<String> get = () -> "A string"; | |
// Predicate<String> test = s2 -> true; | |
// Function<String, Integer> length = String::length; | |
// | |
// return get.get(); | |
/* Default Methods */ | |
// // Needed to create Streams and necessary methods while keeping backward compatibility | |
// // Allows to write default implementation (Actual code) in an Interface | |
// // If you implements several interfaces with the same default, you will have to override | |
// | |
// // Drawback: Careful to when to use default methods! | |
// | |
// // interface Example { | |
// // default String test2() {return "MOUHAHAH";} | |
// // } | |
// | |
// return new Example() {}.test2(); | |
/* Static Methods on interfaces */ | |
// // private interface Example2 { | |
// // public static<T> String stringOf(T value) { | |
// // return String.valueOf(value); | |
// // } | |
// // } | |
// | |
// return Example2.stringOf(true); | |
/* Map, Filter, Reduce */ | |
// One of the most useful use of lambdas are for Collections | |
// class Character { | |
// public String name; | |
// public String type; | |
// public Integer drNo; | |
// | |
// public String getName() { return name; } | |
// | |
// Character(String name, String type, Integer drNo) { | |
// this.name = name; | |
// this.type = type; | |
// this.drNo = drNo; | |
// } | |
// } | |
// | |
// List<Character> whos = Arrays.asList( | |
// new Character("Matt Smith", "Doctor", 11), | |
// new Character("David Tennant", "Doctor", 10), | |
// new Character("Amy Pond", "Companion", 11), | |
// new Character("Sarah Jane Smith", "Companion", 3) | |
// ); | |
// | |
// return whos.stream() | |
// .filter(c -> c.type.equals("Doctor")) | |
// .sorted((c1, c2) -> c1.drNo - c2.drNo) | |
// .map(c -> c.drNo + "th: " + c.name + " ") | |
// .reduce("BIM -> ", (s1, s2) -> s1 + s2); | |
/* ***************** */ | |
/* CompletableFuture */ | |
/* ***************** */ | |
// CompletableFuture<String> future = new CompletableFuture<>() | |
// | |
// try { Thread.sleep(123456L); } catch (InterruptedException e) { e.printStackTrace(); } | |
// finally { future.complete("Yo") } | |
// // finally { future.completeExceptionally(new Exception("Not Yo")) } | |
// | |
// future.thenAcceptAsync(System.out::println) | |
// .whenComplete((s, error) -> { | |
// LOGGER.error(error); | |
// }); | |
/* ******* */ | |
/* Streams */ | |
/* ******* */ | |
/* What are Streams really about */ | |
// // They do not store anything. They know how to compute the next value | |
// // Streams produce a result but never modify the source (Immutability) | |
// // Stream are lazy evaluated objects. Real computation will happen as late as possible | |
// // (Difference between Intermediate and Terminal operations) | |
// // Which allows infinite streams | |
// | |
// Stream.iterate(0, n -> n + 1) | |
// .forEach(System.out::println); | |
// | |
// return "no limit"; | |
/* Other examples */ | |
// // You can generate a stream from almost everything | |
// // And there is a lot of methods available. Check the documentation ! | |
// | |
// return new Random().ints() | |
// .limit(1000) | |
// .sum(); | |
// //.min(); | |
// //.average(); | |
// //.distinct(); | |
// //.allMatch(Predicate); | |
// //.skip(n); | |
// //.distinct(); | |
/* Parallel Array */ | |
// Programming the "what" instead of "how" allows you to easily optimise/change underlying implementation | |
// Remember the complexity Fork/Join of Java 7 ? | |
// (Can be slower on a small amount of data) | |
// return asList(4, 19, 8, 0, 23).parallelStream() | |
// .sorted() | |
// .collect(Collectors.toList()); | |
/* Grouping */ | |
// return Arrays.asList("one", "two", "three", "four", "five").stream() | |
// .collect( | |
// Collectors.groupingBy(name -> name.charAt(0)) | |
// ); | |
/* Partitioning */ | |
// return Arrays.asList("one", "two", "three", "four", "five").stream() | |
// .collect( | |
// Collectors.partitioningBy(s -> s.length() <= 3) | |
// ); | |
/* Statistics */ | |
// IntSummaryStatistics stats = | |
// Arrays.asList("one", "two ", "three", "four", "five ", "").stream() | |
// .map(String::trim) | |
// .filter(s -> !s.isEmpty()) | |
// .mapToInt(String::length) | |
// .summaryStatistics(); | |
// | |
// return "Number of elements: " + stats | |
// .getCount(); | |
// //.getMin(); | |
// //.getMax(); | |
// //... | |
/* The Maybe Monad (let's flatMap that shit) */ | |
// A giant step forward to the end of NullPointerException | |
// Some of Stream methods return Optional (Such as findFirst()) | |
// Boolean TRUE = Optional.of(true).orElse(false); | |
// String other = Optional.<String>ofNullable(null).orElse("other"); | |
// | |
// Optional<String> EMPTY = Optional.empty(); | |
// | |
// Optional.of("Something").ifPresent(System.out::println); | |
// | |
// // More importantly, Optional can be used like a stream | |
// | |
// return Arrays.<String>asList(/*"capitalizeMe"*/).stream() | |
// .findFirst() | |
// .map(String::toUpperCase) | |
// .orElse("This collection is empty"); | |
/* Date & Time */ | |
// Very similar to JodaTime | |
// In fact, development as been leaded by Stephen Colebourne (Creator of JodaTime (I met him ;))) | |
/* Instant (UTC, Relative to Epoch Time)*/ | |
// Instant.now(); | |
// | |
// /* LocalDate and Period (No TimeZone) */ | |
// | |
// LocalDate inTwoWeeks = | |
// LocalDate.now() | |
// .plus(2, ChronoUnit.WEEKS); | |
// | |
// Period p = Period.ofDays(14); | |
// LocalDate inFourteenDays = LocalDate.now().plus(p); | |
// inFourteenDays.isLeapYear(); | |
// | |
// inFourteenDays.isAfter(inTwoWeeks); | |
// | |
// LocalDate.now(Clock.systemDefaultZone()); | |
// LocalDate.now(Clock.systemUTC()); | |
// | |
// /* LocalTime and Duration */ | |
// | |
// LocalTime date = now().minus(2, ChronoUnit.SECONDS); | |
// LocalTime noon = LocalTime.NOON; | |
// | |
// Duration.parse("PT2H5M30.345S"); | |
// Duration duration = Duration.between(LocalTime.now(), date); | |
// duration.toMillis(); | |
// | |
// /* Combined (with TimeZone information) */ | |
// | |
// LocalDateTime firstApril2PM = LocalDate.of(2014, 4, 1).atTime(LocalTime.of(2, 0)); | |
// | |
// boolean TRUE = ZoneId.systemDefault().toString().equals("Europe/Paris"); | |
// ZoneOffset.of("+06:00"); | |
// | |
// /* Formatter */ | |
// | |
// DateTimeFormatter format = | |
// DateTimeFormatter.ofPattern("dd MM YYY hh mm ss"); | |
// //DateTimeFormatter.BASIC_ISO_DATE; | |
// | |
// return format.format(firstApril2PM); | |
/* Nashorn */ | |
// // Replacement of Rhino to execute Javascript inside the JVM | |
// // Now use InvokeDynamics ! | |
// // Includes "jjs" command line to execute Javascript directly | |
// | |
// ScriptEngineManager engineManager = new ScriptEngineManager(); | |
// ScriptEngine engine = engineManager.getEngineByName("nashorn"); | |
// | |
// try { | |
// engine.eval("function p(s) { print(s) }"); | |
// // engine.eval(new FileReader('library.js')); | |
// | |
// engine.eval("" + | |
// "var imports = new JavaImporter(java.util, java.io, java.nio.file);\n" + | |
// "with (imports) {\n" + | |
// " var paths = new LinkedList();\n" + | |
// " print(paths instanceof LinkedList); //true\n" + | |
// " paths.add(Paths.get(\"file1\"));\n" + | |
// " paths.add(Paths.get(\"file2\"));\n" + | |
// " paths.add(Paths.get(\"file3\"));\n" + | |
// " print(paths) // [file1, file2, file3]\n" + | |
// "}"); | |
// | |
// } catch (ScriptException e) { | |
// return e.getLocalizedMessage(); | |
// } | |
// | |
// return ""; | |
/* Misc | |
* | |
* - No more Permanent Generation in Garbage Collector (Please read: http://mechanical-sympathy.blogspot.co.uk/2013/07/java-garbage-collection-distilled.html) | |
* - java.util.Base64 | |
* - Cryptography upgrades (lots) | |
* - JDBC 4.2 | |
* - Annotations on types (notNullString = (@NonNull String) str;) | |
* - Repeatable Annotations: | |
* + @Schedule(dayOfMonth="first") | |
* + @Schedule(dayOfWeek="Monday", hour=7) | |
*/ | |
} | |
public static void main(String[] args) { | |
System.out.println(samples().toString()); | |
} | |
private interface Example { | |
default String test2() {return "MOUHAHAH";} | |
} | |
private interface Example2 { | |
public static<T> String stringOf(T value) { | |
return String.valueOf(value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment