JavaRush /Java Blog /Random-TK /Java 8 aýratynlyklary - Iň soňky gollanma (2-nji bölüm)
0xFF
Dereje
Донецк

Java 8 aýratynlyklary - Iň soňky gollanma (2-nji bölüm)

Toparda çap edildi
Makalanyň terjimesiniň ikinji bölümi Java 8 aýratynlyklary - ULTIMATE gollanmasy . Birinji bölüm şu ýerde (baglanyşyk üýtgäp biler). Java 8 aýratynlyklary - Iň soňky gollanma (2-nji bölüm) - 1

5. Java 8 kitaphanalarynda täze aýratynlyklar

Java 8 häzirki zaman ylalaşygyny, funksional programmirlemegi, senäni / wagty we başgalary has gowy goldamak üçin köp sanly täze synp goşdy we bar bolanlary giňeltdi.

5.1. Meýletin synp

Meşhur NullPointerException , Java programmasynyň şowsuzlygynyň iň köp ýaýran sebäbi. Köp wagt mundan ozal Google-yň ajaýyp taslamasy GuavaOptional çözgüt hökmünde hödürledi NullPointerException, şeýlelik bilen koduň null barlaglar bilen hapalanmagynyň öňüni aldy we netijede has arassa kod ýazmagy höweslendirdi. Google tarapyndan ylhamlanan Guava synpy Optionalindi Java 8-iň bir bölegi. Diňe bir konteýner: bahasy ýa-da haýsydyr bir görnüşi Optionalbolup biler ýa-da ýönekeý bolup biler. Açyk null barlaglaryň indi aklanmazlygy üçin köp peýdaly usullary üpjün edýär. Has giňişleýin maglumat üçin resmi resminamalara serediň . Ulanyşyň iki sany kiçijik mysalyna seredeliň : null we ýok. ТOptional
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!" ) );
Eger mysalda gymmaty ýok bolsa we başgaça ýalan bolsa , usul dogryisPresent() gaýdyp gelýär . Usul , asyl bahany döretmek üçin funksiýalary kabul edip, netijesi ýok bolsa, netijäniň yza gaýdyş mehanizmini öz içine alýar . Karta () usuly häzirki bahany üýtgedýär we täze mysal getirýär . Usul meňzeýär , ýöne funksiýanyň ýerine deslapky bahany alýar. Ine, bu programmanyň netijesi: OptionalorElseGet()OptionalOptionalOptionalorElse()orElseGet()
Full Name is set? false
Full Name: [none]
Hey Stranger!
Başga bir mysala gysga göz aýlalyň:
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();
Netije şeýle bolar:
First Name is set? true
First Name: Tom
Hey Tom!
Has giňişleýin maglumat üçin resmi resminamalara ýüz tutmagyňyzy haýyş edýäris .

5.2. Akymlar

Täze goşulan Stream API ( java.util.stream) Java-da hakyky funksional stil programmirlemesini hödürleýär. Bu wagta çenli Java kitaphanasyna iň giňişleýin goşundy bolup, Java döredijilere has täsirli bolmaga mümkinçilik berýär, şeýle hem täsirli, arassa we gysga kod döretmäge mümkinçilik berýär. “Stream API” kolleksiýalary gaýtadan işlemegi has aňsatlaşdyrýar (ýöne soň görşümiz ýaly olar bilen çäklenmeýär). Mysal hökmünde ýönekeý synp alalyň 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 );
        }
    }
}
Taslamanyň käbir nokatlary bar (ýa-da ýasama kynçylyklar) we AÇYLMAK ýa-da OSapylmak bolup biler . Oýun etmek üçin kiçijik meseleleriň ýygyndysyny hödürläliň.
final Collection<Task> tasks = Arrays.asList(
    new Task( Status.OPEN, 5 ),
    new Task( Status.OPEN, 13 ),
    new Task( Status.CLOSED, 8 )
);
Açmak isleýän ilkinji soragymyz, häzirki wagtda Açyk meselelerde näçe nokat bar? Java 8-den öň munuň adaty çözgüdi iterator ulanmak bolardy foreach. Javaöne Java 8-de jogap akymlar: yzygiderli we parallel jemleýji amallary goldaýan elementleriň yzygiderliligi.
// Подсчет общего количества очков всех активных задач с использованием sum()
final long totalPointsOfOpenTasks = tasks
    .stream()
    .filter( task -> task.getStatus() == Status.OPEN )
    .mapToInt( Task::getPoints )
    .sum();

System.out.println( "Total points: " + totalPointsOfOpenTasks );
Konsol çykyşy bolsa şeýle bolar:
Total points: 18
Geliň, bu ýerde nämeleriň bolup geçýändigine seredeliň. Ilki bilen, ýumuş ýygyndysy akym görnüşine öwrülýär. Soňra amal, ýapykfilter statusly ähli meseleleri süzýär . Indiki ädimde, amal her mysal üçin usul ulanyp, akym akymlaryny akymlara öwürýär . Netijede, ähli nokatlar ahyrky netijäni berýän usul bilen jemlenýär . Indiki mysallara geçmezden ozal ýatda saklamaly sapaklar barada käbir bellikler bar (has giňişleýin maglumat şu ýerde ). Amallar aralyk we ahyrky amallara bölünýär . Aralyk amallar täze akym getirýär. Elmydama ýalta bolýarlar; ýaly aralyk amallary ýerine ýetirenlerinde , süzgüç ýerine ýetirenoklar, tersine, täze akym döredýärler, ol gutarandan soň berlen akymyň elementlerine laýyk gelýär. Netije ýa-da ters täsir etmek üçin akym ýaly we ahyrky amallar akymdan geçip biler. Iň soňky amal gutaransoň, akym ulanylan hasaplanýar we gaýtadan ulanyp bolmaýar. Caseshli halatlarda diýen ýaly ahyrky amallar esasy maglumat çeşmesiniň üsti bilen öz gezelençlerini tamamlaýarlar. Saplaryň ýene bir gymmatly aýratynlygy, gutujykdan paralel proseslere goldaw. Problemshli meseleleriň ballarynyň jemini tapýan bu mysala seredeliň. mapToIntTaskIntegerTask::getPointsTasksumstreamfilterforEachsum
// 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 );
Bu, ilkinji meselä gaty meňzeýär, ähli meseleleri paralel gaýtadan işlemäge we usul bilen iň soňky netijäni hasaplamaga synanyşýarys reduce. Ine, konsolyň çykyşy:
Total points (all tasks): 26.0
Köplenç elementleri belli bir kriteriýa görä toparlamak zerurlygy ýüze çykýar. Mysal sapaklaryň munuň bilen nädip kömek edip biljekdigini görkezýär.
// Группировка задач по их статусу
final Map<Status, List<Task>> map = tasks
    .stream()
    .collect( Collectors.groupingBy( Task::getStatus ) );
System.out.println( map );
Konsol çykyşy aşakdaky ýaly bolar:
{CLOSED=[[CLOSED, 8]], OPEN=[[OPEN, 5], [OPEN, 13]]}
Mesele mysallary bilen gutarmak üçin, kolleksiýadaky her meseläniň umumy göterimine (ýa-da agramyna) umumy ballary hasaplap göreliň:
// Подсчет веса каждой задачи (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 );
Konsol çykyşy şeýle bolar:
[19%, 50%, 30%]
Ahyrynda, öň belläp geçişimiz ýaly, “Stream API” diňe Java kolleksiýalary üçin däl. Adaty I / O amaly, tekst faýllaryny setir boýunça okamak ýaly, akymlary gaýtadan işlemek üçin gaty gowy kandidat. Muny subut etmek üçin kiçijik bir mysal.
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 );
}
onConsoleBir sapak diýilýän usul , goşmaça hususy işleýji bilen ekwiwalent sapagy yzyna getirýär. close()Hususy işleýji sapakda usul çagyrylanda çagyrylýar . “Stream API” lambdalar we salgylanma usullary bilen birlikde Java 8-de standart we statiki usullar bilen häzirki zaman programma üpjünçiligini ösdürmegiň paradigmalaryna jogap bolup durýar. Has giňişleýin maglumat üçin resmi resminamalara ýüz tutmagyňyzy haýyş edýäris .

5.3. Sene / Wagt API (JSR 310)

Java 8 täze Sene we Wagt API (JSR 310) bermek arkaly senä we wagt dolandyryşyna täze görnüş getirýär . Sene we wagt manipulýasiýasy Java döredijiler üçin iň erbet agyry nokatlaryndan biridir. java.util.DateAşakdaky adaty java.util.Calendarýagdaý ýagdaýy gowulaşdyrmady (belki hasam bulaşdyrdy). Ine, Joda-Time dünýä indi: Java üçin ajaýyp sene / wagt API alternatiwasy . Java 8-de (JSR 310) täze Sene / Wagt API Joda-Time- iň täsirine düşýär we ondan iň gowusyny alýar. Täze paketde sene, wagt, sene / wagt, wagt guşaklygy, dowamlylygy we wagt manipulýasiýasy üçin ähli synplarjava.time bar . API dizaýny üýtgewsizlige çynlakaý çemeleşdi: üýtgeşmelere ýol berilmeýär (öwrenilen gaty sapak ). Üýtgetmek zerur bolsa, degişli synpyň täze mysaly yzyna gaýtarylar. Esasy synplara we olaryň ulanylyşynyň mysallaryna seredeliň. Wagt zolagyny ulanyp häzirki dessine, senä we wagta girişi üpjün edýän birinji synp . ýerine we ulanylyp bilner . java.util.CalendarClockClockSystem.currentTimeMillis()TimeZone.getDefault()
// Получить системное время How смещение UTC
final Clock clock = Clock.systemUTC();
System.out.println( clock.instant() );
System.out.println( clock.millis() );
Konsolyň çykyşy:
2014-04-12T15:19:29.282Z
1397315969360
Beýleki täze synplara serederis LocaleDatewe LocalTime. LocaleDatediňe ISO-8601 senenama ulgamynda wagt zolagy bolmadyk sene bölegini öz içine alýar. Şoňa laýyklykda, LocalTimewagt kodunyň diňe bir bölegi bar.
// получить местную 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 );
Konsolyň çykyşy:
2014-04-12
2014-04-12
11:25:54.568
15:25:54.568
LocalDateTimebirleşdirýär LocaleDatewe LocalTimeISO-8601 senenama ulgamynda sene we wagty öz içine alýar, ýöne wagt guşagy ýok. Simpleönekeý mysal aşakda berilýär.
// Get the local date/time
final LocalDateTime datetime = LocalDateTime.now();
final LocalDateTime datetimeFromClock = LocalDateTime.now( clock );

System.out.println( datetime );
System.out.println( datetimeFromClock );
Konsolyň çykyşy:
2014-04-12T11:37:52.309
2014-04-12T15:37:52.309
Belli bir wagt zolagy üçin sene / wagt gerek bolsa , ZonedDateTime. ISO-8601 senenama ulgamynda senäni we wagty öz içine alýar. Dürli wagt guşaklygy üçin käbir mysallar.
// Получение даты/времени для временной зоны
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 );
Konsolyň çykyşy:
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]
Iň soňunda bolsa synpa göz aýlalyň Duration: wagt sekuntlarda we nanosekuntda. Bu iki senäniň arasyndaky hasaplamany gaty ýönekeýleşdirýär. Muny nädip etmelidigini göreliň:
// Получаем разницу между двумя датами
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() );
Aboveokardaky mysal, 2014-nji ýylyň 16-njy aprelinden 2015 -nji ýylyň 16-njy apreline çenli iki senäniň arasyndaky dowamlylygy (günlerde we sagatlarda) hasaplaýar . Ine, konsolyň çykyşynyň mysaly:
Duration in days: 365
Duration in hours: 8783
Java 8-de täze senäniň / wagtyň umumy täsiri gaty oňyn. Üýtgeşmeleriň söweş synagyndan (Joda-Time) esaslanýandygy sebäpli, bu gezek bu meselä çynlakaý seredilip, işläp düzüjileriň sesleri eşidildi. Jikme-jiklikler üçin resmi resminamalara ýüz tutmagyňyzy haýyş edýäris .

5.4. Nashorn JavaScript hereketlendirijisi

Java 8 , JVM-de käbir JavaScript programmalaryny ösdürmäge we işletmäge mümkinçilik berýän täze Nashorn JavaScript dwigateli bilen gelýär . “Nashorn JavaScript” hereketlendirijisi, Java we JavaScript-iň özara täsirleşmegine rugsat bermek üçin şol bir kadalar toplumyna eýerýän javax.script.ScriptEngine-iň başga bir ýerine ýetirişidir. Ine kiçijik mysal.
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;" ) );
Konsolyň çykyşy:
jdk.nashorn.api.scripting.NashornScriptEngine
Result: 2

5.5. Base64

Netijede, Base64 kodlamagy goldamak, Java 8 çykmagy bilen Java standart kitaphanasyna girdi. Ulanmak aňsat, mysal muny görkezýär.
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 );
    }
}
Programmanyň konsol çykyşy kodlanan we kodlanan teksti görkezýär:
QmFzZTY0IGZpbmFsbHkgaW4gSmF2YSA4IQ==
Base64 finally in Java 8!
URL üçin amatly kodlaýjylar / dekoderler, şeýle hem MIME üçin amatly kodlaýjylar / kodlaýjylar ( Base64.getUrlEncoder()/ Base64.getUrlDecoder(), Base64.getMimeEncoder()/ Base64.getMimeDecoder()) üçin sapaklar bar.

5.6. Parallel massiwler

Java 8 goýberilişi paralel massiwleri gaýtadan işlemek üçin köp täze usullary goşýar. Perhapshtimal, bularyň iň möhümi parallelSort(), köp ýadroly maşynlarda tertipleşdirmegi ep-esli çaltlaşdyryp biler. Aşakdaky kiçijik mysal, hereketleriň () täze maşgalasyny görkezýär parallelXxx.
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();
    }
}
Bu kiçijik kod bölegi, parallelSetAll()20,000 tötänleýin baha bilen bir massiw doldurmak usulyny ulanýar. Ondan soň ulanylýar parallelSort(). Programma, massiwiň hakykatdanam tertiplenendigini görkezmek üçin sortlanmazdan ozal we soň ilkinji 10 elementi çap edýär. Mysal üçin, programma çykyşy şeýle bolup biler (massiwiň elementleriniň tötänleýin bolandygyna üns beriň).
Unsorted: 591217 891976 443951 424479 766825 351964 242997 642839 119108 552378
Sorted: 39 220 263 268 325 607 655 678 723 793

5.7. Parallelizm

java.util.concurrent.ConcurrentHashMapTäze goşulan akym obýektlerine we lambda aňlatmalaryna esaslanýan jemleýji amallary goldamak üçin synpa täze usullar goşuldy . java.util.concurrent.ForkJoinPoolŞeýle hem umumy howuzy goldamak üçin synpa täze usullar goşuldy ( Java ylalaşygy boýunça mugt kursymyza hem serediň ). Okamak / ýazmak üçin üç giriş rejimi bilen ukyplylyga esaslanan gulplama üpjün etmek üçin täze synp java.util.concurrent.locks.StampedLockgoşuldy (beýle gowy däline has gowy alternatiwa hökmünde seredilip bilner java.util.concurrent.locks.ReadWriteLock). Bukja goşulan täze synplar java.util.concurrent.atomic:
  • DoubleAccumulator
  • DoubleAdder
  • LongAccumulator
  • LongAdder

6. Java iş wagtyndaky täze aýratynlyklar (JVM)

Sebit PermGenpensiýa çykdy we ýerine Metaspace (JEP 122) çalyşdy. JVM opsiýalary -XX:PermSizewe degişlilikde -XX:MaxPermSizeçalşyldy . -XX:MetaSpaceSize-XX:MaxMetaspaceSize

7. Netije

Geljek şu ýerde: Java 8 döredijilere has öndürijilikli bolmaga mümkinçilik berýän aýratynlyklary bermek arkaly platformasyny öňe sürdi. Önümçilik ulgamlaryny Java 8-ä geçirmek entek ir, ýöne ýakyn aýlarda ogullyga almak ýuwaş-ýuwaşdan ösüp başlamaly. Şeýle-de bolsa, indi kod koduňyzy Java 8 sazlaşyklylygy üçin taýýarlamagyň we ýeterlik ygtybarly we durnukly bolanda Java 8 üýtgeşmelerini girizmäge taýynlygyň wagty geldi. Jemgyýetiň Java 8-i kabul edendiginiň subutnamasy hökmünde Pivotal ýakynda Java 8-e önümçilik goldawy bilen Bahar çarçuwasyny çykardy . Java 8-de gyzykly täze aýratynlyklar barada öz teswirleriňizi teswirlerde berip bilersiňiz.

8. Çeşmeler

Java 8 aýratynlyklarynyň dürli taraplaryny ara alyp maslahatlaşýan käbir goşmaça çeşmeler:
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION