2016/05/26 | Feature Complete | |
2016/08/11 | All Tests Run | |
2016/09/01 | Rampdown Start | |
2016/10/20 | Zero Bug Bounce | |
2016/12/01 | Rampdown Phase 2 | |
2017/01/26 | Final Release Candidate | |
2017/03/23 | General Availability |
Process API Updates
HTTP 2 Client
Improve Contended Locking
Unified JVM Logging
Compiler Control
Variable Handles
Segmented Code Cache
Smart Java Compilation, Phase Two
The Modular JDK
Modular Source Code
Elide Deprecation Warnings on Import Statements
Resolve Lint and Doclint Warnings
Milling Project Coin
Remove GC Combinations Deprecated in JDK 8
Tiered Attribution for javac
Process Import Statements Correctly
Annotations Pipeline 2.0
Datagram Transport Layer Security (DTLS)
Modular Run-Time Images
Simplified Doclet API
jshell: The Java Shell (Read-Eval-Print Loop)
New Version-String Scheme
HTML5 Javadoc
Javadoc Search
UTF-8 Property Files
Unicode 7.0
Add More Diagnostic Commands
Create PKCS12 Keystores by Default
Remove Launch-Time JRE Version Selection
Improve Secure Application Performance
Generate Run-Time Compiler Tests Automatically
Test Class-File Attributes Generated by javac
Parser API for Nashorn
Linux/AArch64 Port
Multi-Release JAR Files
Remove the JVM TI hprof Agent
Remove the jhat Tool
Java-Level JVM Compiler Interface
TLS Application-Layer Protocol Negotiation Extension
Validate JVM Command-Line Flag Arguments
Leverage CPU Instructions for GHASH and RSA
Compile for Older Platform Versions
Make G1 the Default Garbage Collector
OCSP Stapling for TLS
Store Interned Strings in CDS Archives
Multi-Resolution Images
Use CLDR Locale Data by Default
Prepare JavaFX UI Controls & CSS APIs for Modularization
Compact Strings
Merge Selected Xerces 2.11.0 Updates into JAXP
BeanInfo Annotations
Update JavaFX/Media to Newer Version of GStreamer
HarfBuzz Font-Layout Engine
Stack-Walking API
Encapsulate Most Internal APIs
Module System
TIFF Image I/O
HiDPI Graphics on Windows and Linux
Platform Logging API and Service
Marlin Graphics Renderer
More Concurrency Updates
Unicode 8.0
XML Catalogs
Convenience Factory Methods for Collections
Reserved Stack Areas for Critical Sections
Unified GC Logging
Platform-Specific Desktop Features
DRBG-Based SecureRandom Implementations
Enhanced Method Handles
Modular Java Application Packaging
Dynamic Linking of Language-Defined Object Models
Enhanced Deprecation
Additional Tests for Humongous Objects in G1
Improve Test-Failure Troubleshooting
Indify String Concatenation
HotSpot C++ Unit-Test Framework
jlink: The Java Linker
Enable GTK 3 on Linux
New HotSpot Build System
Spin-Wait Hints
Artık Garbage First Çöp Toplayıcısı (G1GC) varsayılan çöp toplayıcı:
bool UseG1GC := true {product}
- DefNew + CMS
- ParNew + SerialOld
- Incremental CMS
Stream API ile birlikte torbalar üzerinde seri ya da paralel çalışabilen iç döngü oluşturabiliyoruz. Bu döngülerde neler yapılacığını ise Stream arayüzünün metodları ve bu metodlara parametre olarak geçtiğimiz fonksiyonlar aracılığı tanımlıyoruz. Fonksiyonları ise Lambda ifadeleri ya da Metod referansları ile tanımlıyoruz. Java 9'da Stream arayüzünde yeni misafirlerimiz var: takeWhile ve dropWhile. Scala ya da C# programlama dilini kullanarak uygulama geliştirenlerin bildikleri metodlar bunlar. Şimdi bu iki metodun davranışını örnek uygulama üzerinden çalışalım. Elimizde her bir satırında bir Türkçe kelimenin olduğu yirmi beş bin satırdan oluşan dictionary.txt isimli bir dosya bulunuyor. Şimdi sadece A harfinden M harfine kadar olan harflerle başlayan kelimeleri listeleyelim:
Files.lines(Paths.get("src","dictionary.txt")) .takeWhile( line -> line.matches("^[a-m].*$") ) .forEach(System.out::println);
Şimdi ise N harfinden itibaren sözlüğün sonuna kadar tüm kelimeleri listeleyelim:
Files.lines(Paths.get("src","dictionary.txt")) .dropWhile( line -> line.matches("[a-m].*$") ) .forEach(System.out::println);
Stream<Integer> oddNumbers = Stream.iterate(1, n -> n <= 100, n -> n + 2 ); System.out.println(oddNumbers.reduce(0, (acc,num) -> acc + num ));
Stream API Örnekleri
Şimdi dilerseniz, elimizdeki problem için Stream API, Lambda ifadeleri ve Java 8+ ile gelen yenilikleri çalışacağımız bir kaç problem çözelim.
Topaklanmış İndeks
İlk olarak sözlükteki kelimeleri ilk üç karakterine göre gruplayalım. Bu işleme ilişkisel veri tabanlarında "indeks topaklama" (=clustered index) adını veriyoruz. Bu teknik, karakter katarı (=String) alanlar üzerinde yapılan aramaları indeks boyunu sabit ve aynı indeks değerine sahip kayıtları aynı sayfada tutarak hızlandırmayı amaçlıyor. Java 8+'da bu indekslemeyi aşağıdaki gibi gerçekleştiriyoruz:
Stream<String> words = Files.lines(Paths.get("src", "dictionary.txt")); final Function<String, String> first3CharsLambda = word -> word.length() >= 3 ? word.substring(0, 3) : word.substring(0, word.length()); final Collector<String, ?, Map<String, List<String>>> groupByFirstThreeChars = Collectors.groupingBy(first3CharsLambda); Map<String,List<String>> clusteredIndex= words.collect(groupByFirstThreeChars); for (Entry<String,List<String>> entry: clusteredIndex.entrySet()){ System.out.println(entry.getKey()+": "+entry.getValue()); }
Palindrom
Tersten okunuşu aynı olan kelimelere palindrom adını veriyoruz. Şimdi
sözlüğümüzdeki palindormların listesini veren çözümü Java 8+'de kodlayalım:
package com.example.java9; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.function.Function; /** * * @author bkurt */ public class Palindrome { public static void main(String[] args) throws IOException { List<String> words = Files.readAllLines(Paths.get("src", "dictionary.txt")); Function<String, String> reverse = word -> new StringBuilder(word).reverse().toString(); words.stream().filter(word -> words.contains(reverse.apply(word))) .distinct() .forEach(System.out::println); } }
Sesli Harf Sayma
Bu örnek uygulamada hangi sesli harf kelimelerde toplam kaç defa kullanılıyor? bunu bulmaya çalışalım:
package com.example.java9; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.AbstractMap; import java.util.List; import static java.util.Map.Entry; import java.util.stream.Collectors; import static java.util.stream.Collectors.groupingBy; /** * * @author Binnur Kurt (binnur.kurt@gmail.com) */ public class Vowel { public static void main(String[] args) throws IOException { List<String> words = Files.readAllLines(Paths.get("src", "dictionary.txt")); words.stream().flatMap(word -> word.chars().boxed().map(c -> pair(c, word))) .collect(groupingBy(Entry::getKey, Collectors.mapping(Entry::getValue, Collectors.toList()))) .forEach((key, value) -> System.out.format("%c : %d\n", key, value.size())); } private static <T, U> AbstractMap.SimpleEntry<T, U> pair(T t, U u) { return new AbstractMap.SimpleEntry<T, U>(t, u); } }
Düzenli İfade Arama
Bu örnek uygulamada ise sözlükte düzenli ifade arayacağız. a ile başlayan z ile biten ilk kelimeyi bulmaya çalışalım:
Stream<String> words = Files.lines(Paths.get("src", "dictionary.txt")); Optional<String> found= words.filter(word -> word.matches("^a.*z$")) .findFirst(); System.out.println(found.orElse("Not found!"));
Stream<String> words = Files.lines(Paths.get("src", "dictionary.txt")); List<String> searchResult= words.filter(word -> word.matches("^a.*z$")) .collect(Collectors.toList()); System.out.println(searchResult);
package com.example.java9; import java.io.IOException; import java.nio.file.Paths; import java.util.List; import java.util.Scanner; import java.util.regex.MatchResult; import java.util.stream.Collectors; /** * * @author binnur kurt (binnur.kurt@gmail.com) */ public class SearchInFile { public static void main(String[] args) throws IOException { List<String> searchResult = new Scanner(Paths.get("src", "dictionary.txt")) .findAll("\\ba.*z\\b") .map(MatchResult::group) .collect(Collectors.toList()); searchResult.forEach(System.out::println); } }