Bagian kapindho terjemahan artikel Java 8 Features – The ULTIMATE Guide . Bagian pisanan ana ing kene (link bisa diganti).
5. Fitur anyar ing Jawa 8 perpustakaan
Java 8 wis nambahake akeh kelas anyar lan nambah kelas sing wis ana kanggo ndhukung konkurensi modern, program fungsional, tanggal / wektu, lan liya-liyane.5.1. Kelas Opsional
NullPointerException sing misuwur minangka panyebab kegagalan aplikasi Java sing paling umum. Ing wektu sing suwe, proyek Google Guava sing apik banget ditampilakeOptional
minangka solusi NullPointerException
, saéngga nyegah kode supaya ora dicemari dening pamriksan null, lan minangka asil nyengkuyung nulis kode sing luwih resik. Kelas Jambu sing diilhami Google Optional
saiki dadi bagéan saka Jawa 8. Optional
Iku mung wadhah: bisa ngemot nilai utawa sawetara jinis Т
, utawa mung null. Nyedhiyakake akeh cara sing migunani supaya pamriksan null sing jelas ora bisa ditrapake maneh. Deleng dokumentasi resmi kanggo informasi sing luwih rinci. Ayo goleki rong conto panggunaan cilik Optional
: nganggo lan tanpa null.
Optional<String> fullName = Optional.ofNullable( null );
System.out.println( "Full Name is set? " + fullName.isPresent() );
System.out.println( "Full Name: " + fullName.orElseGet( () -> "[none]" ) );
System.out.println( fullName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) );
Cara kasebut isPresent()
ngasilake bener yen conto kasebut Optional
ngemot nilai non-null lan palsu . Cara kasebut orElseGet()
ngemot mekanisme mundur kanggo asil yen Optional
ngemot null, nrima fungsi kanggo ngasilake nilai standar. Cara map () ngowahi nilai saiki Optional
lan ngasilake conto anyar Optional
. Cara iki orElse()
padha karo orElseGet()
, nanging tinimbang fungsi njupuk nilai standar. Mangkene output saka program iki:
Full Name is set? false
Full Name: [none]
Hey Stranger!
Ayo goleki conto liyane:
Optional<String> firstName = Optional.of( "Tom" );
System.out.println( "First Name is set? " + firstName.isPresent() );
System.out.println( "First Name: " + firstName.orElseGet( () -> "[none]" ) );
System.out.println( firstName.map( s -> "Hey " + s + "!" ).orElse( "Hey Stranger!" ) );
System.out.println();
Asil bakal kaya iki:
First Name is set? true
First Name: Tom
Hey Tom!
Kanggo informasi sing luwih rinci, waca dokumentasi resmi .
5.2. Aliran
Stream API ( ) sing mentas ditambahakejava.util.stream
ngenalake pemrograman gaya fungsional nyata ing Jawa. Iki minangka tambahan paling lengkap kanggo perpustakaan Jawa lan ngidini pangembang Jawa dadi luwih efisien lan uga bisa nggawe kode sing efisien, resik lan ringkes. Stream API nggawe pangolahan koleksi luwih gampang (nanging ora diwatesi, kaya sing bakal kita deleng mengko). Ayo njupuk kelas prasaja minangka conto Task
.
public class Streams {
private enum Status {
OPEN, CLOSED
};
private static final class Task {
private final Status status;
private final Integer points;
Task( final Status status, final Integer points ) {
this.status = status;
this.points = points;
}
public Integer getPoints() {
return points;
}
public Status getStatus() {
return status;
}
@Override
public String toString() {
return String.format( "[%s, %d]", status, points );
}
}
}
Tugas duwe sawetara raos (utawa pseudo-angel) lan bisa uga OPEN utawa CLOSE . Ayo dadi introduce koleksi cilik saka masalah kanggo muter karo.
final Collection<Task> tasks = Arrays.asList(
new Task( Status.OPEN, 5 ),
new Task( Status.OPEN, 13 ),
new Task( Status.CLOSED, 8 )
);
Pitakonan pisanan sing arep digoleki yaiku pira poin sing saiki ana ing tugas OPEN ? Sadurunge Java 8, solusi sing biasa kanggo iki yaiku nggunakake iterator foreach
. Nanging ing Jawa 8, jawabane yaiku stream: urutan unsur sing ndhukung operasi agregat sekuensial lan paralel.
// Подсчет общего количества очков всех активных задач с использованием sum()
final long totalPointsOfOpenTasks = tasks
.stream()
.filter( task -> task.getStatus() == Status.OPEN )
.mapToInt( Task::getPoints )
.sum();
System.out.println( "Total points: " + totalPointsOfOpenTasks );
Lan output console bakal katon kaya:
Total points: 18
Ayo ndeleng apa sing kedadeyan ing kene. Kaping pisanan, koleksi tugas diowahi dadi perwakilan streaming. Operasi banjur filter
nyaring kabeh tugas kanthi status TUTUP . Ing langkah sabanjure, operasi mapToInt
ngowahi stream Task
s menyang stream Integer
nggunakake cara Task::getPoints
kanggo saben Kayata Task
. Pungkasan, kabeh poin disimpulake kanthi nggunakake metode sum
, sing menehi asil pungkasan. Sadurunge pindhah menyang conto sabanjure, ana sawetara cathetan babagan benang sing kudu dielingi (rincian liyane ing kene ). Operasi stream
dipérang dadi operasi penengah lan pungkasan . Operasi penengah ngasilake aliran anyar. Dheweke tansah kesed; nalika nindakake operasi penengah kayata filter
, dheweke ora nindakake nyaring, nanging nggawe stream anyar, sing, yen wis rampung, ngemot unsur-unsur aliran asli sing cocog karo predikat sing diwenehake. Operasi winates , kayata forEach
lan sum
, bisa dilewati liwat stream kanggo ngasilake asil utawa efek samping. Sawise operasi pungkasan rampung, stream kasebut dianggep digunakake lan ora bisa digunakake maneh. Ing meh kabeh kasus, operasi pungkasan cenderung ngrampungake traversal liwat sumber data dhasar. Fitur penting liyane saka benang yaiku dhukungan kanggo proses paralel saka kothak. Ayo goleki conto iki, sing nemokake jumlah skor kabeh masalah.
// Calculate total points of all tasks
final double totalPoints = tasks
.stream()
.parallel()
.map( task -> task.getPoints() ) // or map( Task::getPoints )
.reduce( 0, Integer::sum );
System.out.println( "Total points (all tasks): " + totalPoints );
Iki meh padha karo conto pisanan, kajaba kita nyoba ngolah kabeh tugas kanthi podo karo lan ngetung asil pungkasan nggunakake metode kasebut reduce
. Mangkene output konsol:
Total points (all tasks): 26.0
Asring ana perlu kanggo klompok unsur miturut kritéria tartamtu. Conto nuduhake carane thread bisa mbantu iki.
// Группировка задач по их статусу
final Map<Status, List<Task>> map = tasks
.stream()
.collect( Collectors.groupingBy( Task::getStatus ) );
System.out.println( map );
Output konsol bakal kaya ing ngisor iki:
{CLOSED=[[CLOSED, 8]], OPEN=[[OPEN, 5], [OPEN, 13]]}
Kanggo ngrampungake conto masalah, ayo ngetung persentase sakabèhé (utawa bobot) saben masalah ing koleksi adhedhasar total poin:
// Подсчет веса каждой задачи (How процент от общего количества очков)
final Collection<String> result = tasks
.stream() // Stream<String>
.mapToInt( Task::getPoints ) // IntStream
.asLongStream() // LongStream
.mapToDouble( points -> points / totalPoints ) // DoubleStream
.boxed() // Stream<Double>
.mapToLong( weigth -> ( long )( weigth * 100 ) ) // LongStream
.mapToObj( percentage -> percentage + "%" ) // Stream<String>
.collect( Collectors.toList() ); // List<String>
System.out.println( result );
Output konsol bakal kaya iki:
[19%, 50%, 30%]
Pungkasan, kaya sing wis dingerteni sadurunge, Stream API ora mung kanggo koleksi Java. Operasi I / O sing khas, kayata maca file teks baris demi baris, minangka calon sing apik banget kanggo nggunakake pangolahan stream. Punika conto cilik kanggo mbuktekaken iki.
final Path path = new File( filename ).toPath();
try( Stream<String> lines = Files.lines( path, StandardCharsets.UTF_8 ) ) {
lines.onClose( () -> System.out.println("Done!") ).forEach( System.out::println );
}
Cara kasebut onConsole
, sing diarani benang, ngasilake benang sing padha karo panangan pribadi tambahan. Pawang pribadi diarani nalika metode close()
diarani ing benang. Stream API bebarengan karo lambdas lan cara referensi bebarengan karo standar lan cara statis ing Jawa 8 minangka jawaban kanggo paradigma pangembangan piranti lunak modern. Kanggo informasi sing luwih rinci, waca dokumentasi resmi .
5.3. API Tanggal/Wektu (JSR 310)
Java 8 nggawa tampilan anyar kanggo manajemen tanggal lan wektu kanthi nyedhiyakake API Tanggal lan Wektu anyar (JSR 310) . Manipulasi tanggal lan wektu minangka salah sawijining titik nyeri paling awon kanggo pangembang Jawa.java.util.Date
Ing ngisor iki standar java.util.Calendar
ora umume nambah kahanan (bisa uga luwih mbingungake). Mangkono uga Joda-Time lair : alternatif API tanggal/wektu sing apik kanggo Java . Tanggal / Wektu API anyar ing Jawa 8 (JSR 310) dipengaruhi banget dening Joda-Time lan njupuk sing paling apik saka iku. Paket anyar java.time
ngemot kabeh kelas kanggo tanggal, wektu, tanggal / wektu, zona wektu, durasi, lan manipulasi wektu . Desain API njupuk immutability banget serius: owah-owahan ora diijini (pawulangan hard sinau saka java.util.Calendar
). Yen modifikasi dibutuhake, conto anyar saka kelas sing cocog bakal bali. Ayo goleki kelas utama lan conto panggunaane. Kelas kapisan Clock
, sing nyedhiyakake akses menyang saiki, tanggal lan wektu kanthi nggunakake zona wektu. Clock
bisa digunakake tinimbang System.currentTimeMillis()
lan TimeZone.getDefault()
.
// Получить системное время How смещение UTC
final Clock clock = Clock.systemUTC();
System.out.println( clock.instant() );
System.out.println( clock.millis() );
Conto output konsol:
2014-04-12T15:19:29.282Z
1397315969360
Kelas anyar liyane sing bakal kita deleng yaiku LocaleDate
lan LocalTime
. LocaleDate
mung ngemot bagean tanggal tanpa zona wektu ing sistem tanggalan ISO-8601. Dadi, LocalTime
mung ngemot bagean saka kode wektu>.
// получить местную date и время время
final LocalDate date = LocalDate.now();
final LocalDate dateFromClock = LocalDate.now( clock );
System.out.println( date );
System.out.println( dateFromClock );
// получить местную date и время время
final LocalTime time = LocalTime.now();
final LocalTime timeFromClock = LocalTime.now( clock );
System.out.println( time );
System.out.println( timeFromClock );
Conto output konsol:
2014-04-12
2014-04-12
11:25:54.568
15:25:54.568
LocalDateTime
concatenates LocaleDate
lan LocalTime
lan ngemot tanggal lan wektu, nanging ora zona wektu, ing sistem tanggalan ISO-8601. Conto prasaja diwenehi ing ngisor iki.
// Get the local date/time
final LocalDateTime datetime = LocalDateTime.now();
final LocalDateTime datetimeFromClock = LocalDateTime.now( clock );
System.out.println( datetime );
System.out.println( datetimeFromClock );
Conto output konsol:
2014-04-12T11:37:52.309
2014-04-12T15:37:52.309
Yen sampeyan butuh tanggal / wektu kanggo zona wektu tartamtu, ZonedDateTime
. Isine tanggal lan wektu ing sistem tanggalan ISO-8601. Ing ngisor iki sawetara conto kanggo zona wektu sing beda.
// Получение даты/времени для временной зоны
final ZonedDateTime zonedDatetime = ZonedDateTime.now();
final ZonedDateTime zonedDatetimeFromClock = ZonedDateTime.now( clock );
final ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) );
System.out.println( zonedDatetime );
System.out.println( zonedDatetimeFromClock );
System.out.println( zonedDatetimeFromZone );
Conto output konsol:
2014-04-12T11:47:01.017-04:00[America/New_York]
2014-04-12T15:47:01.017Z
2014-04-12T08:47:01.017-07:00[America/Los_Angeles]
Lan pungkasane, ayo deleng kelas Duration
: rentang wektu sajrone detik lan nanodetik. Iki ndadekake pitungan antarane rong tanggal banget prasaja. Ayo ndeleng carane nindakake iki:
// Получаем разницу между двумя датами
final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 );
final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 );
final Duration duration = Duration.between( from, to );
System.out.println( "Duration in days: " + duration.toDays() );
System.out.println( "Duration in hours: " + duration.toHours() );
Conto ing ndhuwur ngitung durasi (ing dina lan jam) antarane rong tanggal, 16 April 2014 lan 16 April 2015 . Punika conto output console:
Duration in days: 365
Duration in hours: 8783
Kesan sakabèhé saka tanggal / wektu anyar ing Jawa 8 banget, banget positif. Sebagéyan amarga owah-owahan kasebut adhedhasar dhasar sing diuji perang (Joda-Time), sebagian amarga wektu iki masalah kasebut dipikirake maneh lan swara para pangembang dirungokake. Kanggo rincian, waca dokumentasi resmi .
5.4. Nashorn JavaScript engine
Java 8 dilengkapi mesin JavaScript Nashorn anyar , sing ngidini sampeyan ngembangake lan mbukak jinis aplikasi JavaScript tartamtu ing JVM. Mesin JavaScript Nashorn minangka implementasine liyane saka javax.script.ScriptEngine sing ngetutake aturan sing padha supaya Java lan JavaScript bisa sesambungan. Punika conto cilik.ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName( "JavaScript" );
System.out.println( engine.getClass().getName() );
System.out.println( "Result:" + engine.eval( "function f() { return 1; }; f() + 1;" ) );
Conto output konsol:
jdk.nashorn.api.scripting.NashornScriptEngine
Result: 2
5.5. dhasar64
Pungkasan, dhukungan kanggo enkoding Base64 ditemokake ing perpustakaan standar Jawa kanthi rilis Java 8. Gampang banget digunakake, contone nduduhake iki.package com.javacodegeeks.java8.base64;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Base64s {
public static void main(String[] args) {
final String text = "Base64 finally in Java 8!";
final String encoded = Base64
.getEncoder()
.encodeToString( text.getBytes( StandardCharsets.UTF_8 ) );
System.out.println( encoded );
final String decoded = new String(
Base64.getDecoder().decode( encoded ),
StandardCharsets.UTF_8 );
System.out.println( decoded );
}
}
Output konsol program nuduhake teks sing dienkode lan didekode:
QmFzZTY0IGZpbmFsbHkgaW4gSmF2YSA4IQ==
Base64 finally in Java 8!
Ana uga kelas kanggo ngodhe/dekoder sing ramah-URL, uga encoder/dekoder sing ramah-MIMI ( Base64.getUrlEncoder()
/ Base64.getUrlDecoder()
, Base64.getMimeEncoder()
/ Base64.getMimeDecoder()
).
5.6. Parallel Arrays
Rilis Java 8 nambahake akeh cara anyar kanggo pangolahan array paralel. Mbok sing paling penting ikiparallelSort()
, kang bisa nemen nyepetake ngurutake ing mesin multi-inti. Conto cilik ing ngisor iki nuduhake kulawarga metode anyar ( parallelXxx
) ing tumindak.
package com.javacodegeeks.java8.parallel.arrays;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
public class ParallelArrays {
public static void main( String[] args ) {
long[] arrayOfLong = new long [ 20000 ];
Arrays.parallelSetAll( arrayOfLong,
index -> ThreadLocalRandom.current().nextInt( 1000000 ) );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );
System.out.println();
Arrays.parallelSort( arrayOfLong );
Arrays.stream( arrayOfLong ).limit( 10 ).forEach(
i -> System.out.print( i + " " ) );
System.out.println();
}
}
Potongan kode cilik iki nggunakake cara parallelSetAll()
kanggo ngisi array kanthi 20.000 nilai acak. Sawise iki ditrapake parallelSort()
. Program kasebut nyithak 10 unsur pisanan sadurunge lan sawise ngurutake kanggo nuduhake yen array kasebut bener-bener diurutake. Output program conto bisa katon kaya iki (Elinga yen unsur-unsur array kasebut acak).
Unsorted: 591217 891976 443951 424479 766825 351964 242997 642839 119108 552378
Sorted: 39 220 263 268 325 607 655 678 723 793
5.7. Paralelisme
Cara anyar wis ditambahake ing kelasjava.util.concurrent.ConcurrentHashMap
kanggo ndhukung operasi agregat adhedhasar obyek stream sing mentas ditambahake lan ekspresi lambda. Uga cara anyar wis ditambahake ing kelas java.util.concurrent.ForkJoinPool
kanggo ndhukung pooling sing dienggo bareng (ndeleng uga kursus gratis babagan konkurensi Jawa ). A kelas anyar java.util.concurrent.locks.StampedLock
wis ditambahaké kanggo nyedhiyani ngunci basis kemampuan karo telung mode akses kanggo diwaca / nulis kontrol (bisa dianggep minangka alternatif sing luwih apik kanggo sing ora dadi apik java.util.concurrent.locks.ReadWriteLock
). Kelas anyar sing wis ditambahake menyang paket java.util.concurrent.atomic
:
- DoubleAccumulator
- DoubleAdder
- LongAccumulator
- LongAdder
6. Fitur anyar ing lingkungan runtime Java (JVM)
Wilayah kasebutPermGen
wis pensiun lan diganti dening Metaspace (JEP 122). opsi JVM -XX:PermSize
lan -XX:MaxPermSize
wis diganti dening -XX:MetaSpaceSize
lan -XX:MaxMetaspaceSize
mungguh.
7. Kesimpulan
Masa depan ana ing kene: Java 8 wis mindhah platform kasebut maju kanthi menehi fitur sing ngidini pangembang dadi luwih produktif. Isih banget awal kanggo mindhah sistem produksi menyang Java 8, nanging adopsi kudu alon-alon wiwit tuwuh sajrone sawetara wulan sabanjure. Nanging, saiki iki wektu kanggo miwiti nyiapake basis kode kanggo kompatibilitas Java 8 lan siyap nggabungake owah-owahan Java 8 yen wis aman lan cukup stabil. Minangka bukti nrima masyarakat Jawa 8, Pivotal bubar ngrilis Spring Framework kanthi dhukungan produksi kanggo Java 8 . Sampeyan bisa menehi masukan babagan fitur anyar sing nyenengake ing Jawa 8 ing komentar.8. Sumber
Sawetara sumber daya tambahan sing mbahas macem-macem aspek fitur Java 8 kanthi jero:- Apa Anyar ing JDK 8
- Tutorial Basa Jawa
- WildFly 8, JDK 8, NetBeans 8, Java EE 7
- Jawa 8 Tutorial
- JDK 8 Command-line Static Dependency Checker
- The Illuminating Javadoc saka JDK 8
- Sisih Peteng Jawa 8
- Nginstal Dhukungan Java™ 8 ing Eclipse Kepler SR2
- Jawa 8
- Oracle Nashorn. Mesin JavaScript Generasi Sabanjure kanggo JVM
GO TO FULL VERSION