JavaRush /Блоги Java /Random-TG /Хусусиятҳои Java 8 - Роҳнамои ниҳоӣ (Қисми 2)
0xFF
Сатҳи
Донецк

Хусусиятҳои Java 8 - Роҳнамои ниҳоӣ (Қисми 2)

Дар гурӯҳ нашр шудааст
Қисми дуюми тарҷумаи мақолаи Java 8 Features – The ULTIMATE Guide . Қисми аввал ин ҷост (пайванд метавонад тағир ёбад). Хусусиятҳои Java 8 - Роҳнамои ниҳоӣ (Қисми 2) - 1

5. Хусусиятҳои нав дар китобхонаҳои Java 8

Java 8 бисёр синфҳои нав ва синфҳои мавҷударо васеъ кардааст, то мувофиқати муосир, барномасозии функсионалӣ, сана/вақт ва ғайраро беҳтар дастгирӣ кунад.

5.1. Синфи ихтиёрӣ

Машҳур NullPointerException то ба ҳол сабаби маъмултарини нокомии барномаҳои Java мебошад. Чанде пеш, лоиҳаи аълои Google GuavaOptional ҳамчун як ҳалли пешниҳодшуда пешниҳод карда шуд NullPointerException, ки ба ин васила аз олуда шудани code тавассути чекҳои бефоида пешгирӣ карда мешавад ва дар натиҷа навиштани рамзи тозатарро ташвиқ мекунад. Синфи Guava, ки аз Google илҳом гирифта шудааст, Optionalҳоло як қисми Java 8 мебошад. OptionalИн танҳо як контейнер аст: он метавонад дорои арзиш ё ягон навъи Т, ё танҳо нул бошад. Он бисёр усулҳои муфидро пешниҳод мекунад, то санҷишҳои возеҳи бефоида дигар асоснок нашаванд. Барои маълумоти муфассал ба ҳуҷҷатҳои расмӣ муроҷиат кунед. Биёед ду мисоли хурди истифодаро бубинем 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!" ) );
Усули ҳақиқироisPresent() бармегардонад, агар мисол дорои арзиши ғайриманқул бошад ва дар акси ҳол, нодуруст бошад . Ин усул механизми бозгашти натиҷаро дар бар мегирад, агар он нул дошта бошад ва функсияҳоро барои тавлиди арзиши пешфарз қабул мекунад. Усули map () арзиши ҷориро тағир медиҳад ва намунаи навро бармегардонад . Усул ба - монанд аст , аммо ба ҷои функсия он арзиши пешфарзро мегирад. Ин аст натиҷаи ин барнома: OptionalorElseGet()OptionalOptionalOptionalorElse()orElseGet()
Full Name is set? false
Full Name: [none]
Hey Stranger!
Биёед ба мисоли дигар зуд назар андозем:
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();
Натиҷа чунин хоҳад буд:
First Name is set? true
First Name: Tom
Hey Tom!
Барои маълумоти муфассал, лутфан ба ҳуҷҷатҳои расмӣ муроҷиат кунед .

5.2. Ҷараёнҳо

API Stream нав иловашуда ( java.util.stream) барномасозии услуби функсионалии воқеиро дар Java ҷорӣ мекунад. Он то ҳол иловаи мукаммалтарин ба китобхонаи Java мебошад ва ба таҳиягарони Java имкон медиҳад, ки ба таври назаррас самараноктар бошанд ва инчунин ба онҳо имкон медиҳад, ки рамзи муассир, тоза ва мухтасар эҷод кунанд. Stream API коркарди коллексияҳоро хеле осон мекунад (вале бо онҳо маҳдуд намешавад, тавре ки мо дертар хоҳем дид). Биёед як синфи оддиро ҳамчун мисол гирем 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 );
        }
    }
}
Вазифа дорои баъзе нуқтаҳо (ё мушкorҳои псевдо-мушкилотӣ) ва метавонад ё КУШОДА ё ПУШТ бошад . Биёед маҷмӯи хурди мушкилотро барои бозӣ муаррифӣ кунем.
final Collection<Task> tasks = Arrays.asList(
    new Task( Status.OPEN, 5 ),
    new Task( Status.OPEN, 13 ),
    new Task( Status.CLOSED, 8 )
);
Саволи аввалине, ки мо ният дорем фаҳмем, ин аст, ки дар айни замон вазифаҳои КУШОДА чанд нуктаро дар бар мегиранд? Пеш аз Java 8, ҳалли маъмулии ин истифодаи итератор буд foreach. Аммо дар Java 8, ҷавоб ҷараёнҳост: пайдарпаии унсурҳое, ки амалиёти муттаҳидшавии пайдарпай ва параллелро дастгирӣ мекунанд.
// Подсчет общего количества очков всех активных задач с использованием sum()
final long totalPointsOfOpenTasks = tasks
    .stream()
    .filter( task -> task.getStatus() == Status.OPEN )
    .mapToInt( Task::getPoints )
    .sum();

System.out.println( "Total points: " + totalPointsOfOpenTasks );
Ва баромади консол чунин хоҳад буд:
Total points: 18
Биёед бубинем, ки дар ин ҷо чӣ рӯй медиҳад. Аввалан, маҷмӯаи вазифаҳо ба намоиши ҷараён табдил дода мешавад. Пас аз он амалиёт ҳамаи вазифаҳоро бо ҳолати ПУШИДАfilter филтр мекунад . Дар қадами навбатӣ, амалиёт ҷараёни s-ро ба ҷараёни s бо истифода аз усул барои ҳар як мисол табдил медиҳад . Дар ниҳоят, ҳамаи нуқтаҳо бо усули ҷамъбаст карда мешаванд , ки натиҷаи ниҳоиро медиҳад. Пеш аз гузаштан ба мисолҳои оянда, баъзе ёддоштҳо дар бораи риштаҳо мавҷуданд, ки бояд дар хотир нигоҳ дошта шаванд (тафсилоти бештар дар ин ҷо ). Амалиёт ба амалиёти мобайнӣ ва ниҳоӣ тақсим мешавад . Амалиёти фосилавӣ ҷараёни навро бармегардонад. Онҳо ҳамеша танбал ҳастанд; ҳангоми иҷрои амалҳои мобайнӣ, ба монанди , онҳо аслан филтрро иҷро намекунанд, балки ба ҷои он ҷараёни наверо эҷод мекунанд, ки ҳангоми анҷом додани он унсурҳои ҷараёни аслии ба предикати додашуда мувофиқат мекунанд. Амалҳои ниҳоӣ , ба монанди ва , метавонанд тавассути ҷараён гузаранд, то натиҷа ё таъсири тараф ба вуҷуд оранд. Пас аз анҷоми амалиёти ниҳоӣ, ҷараён истифодашуда ҳисобида мешавад ва дубора истифода намешавад. Тақрибан дар ҳама ҳолатҳо, амалиётҳои ниҳоӣ одатан интиқоли худро тавассути манбаи асосии маълумот анҷом медиҳанд. Хусусияти дигари арзишманди риштаҳо дастгирии равандҳои параллелӣ аз қуттӣ мебошад. Биёед ин мисолро дида бароем, ки дар он ҷамъи холҳои ҳамаи масъалаҳо пайдо мешавад. 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 );
Ин ба мисоли аввал хеле монанд аст, ба истиснои он, ки мо кӯшиш мекунем, ки ҳама вазифаҳоро дар мувозӣ коркард кунем ва натиҷаи ниҳоиро бо усули reduce. Ин аст баромади консол:
Total points (all tasks): 26.0
Аксар вақт зарурати гурӯҳбандии унсурҳо аз рӯи меъёри муайян вуҷуд дорад. Мисол нишон медиҳад, ки чӣ гуна риштаҳо дар ин кор кӯмак карда метавонанд.
// Группировка задач по их статусу
final Map<Status, List<Task>> map = tasks
    .stream()
    .collect( Collectors.groupingBy( Task::getStatus ) );
System.out.println( map );
Натиҷаи консол чунин хоҳад буд:
{CLOSED=[[CLOSED, 8]], OPEN=[[OPEN, 5], [OPEN, 13]]}
Барои анҷом додани мисолҳои мушкилот, биёед фоизи умумии (ё вазн) ҳар як масъаларо дар маҷмӯа аз рӯи холҳои умумӣ ҳисоб кунем:
// Подсчет веса каждой задачи (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 );
Натиҷаи консол чунин хоҳад буд:
[19%, 50%, 30%]
Дар ниҳоят, тавре ки мо қаблан қайд кардем, Stream API на танҳо барои коллексияҳои Java аст. Амалиёти маъмулии I/O, ба монанди хондани файлҳои матнӣ сатр ба сатр, номзади хеле хуб барои истифодаи коркарди ҷараён аст. Барои исботи ин як мисоли хурде меорем.
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 );
}
Усули onConsole, ки дар ришта даъват карда мешавад, риштаи муъодилро бо коркарди хусусии иловагӣ бармегардонад. Коркарди хусусӣ вақте даъват карда мешавад, ки усул close()дар ришта даъват карда мешавад. Stream API дар якҷоягӣ бо ламбдаҳо ва усулҳои истинод дар якҷоягӣ бо усулҳои пешфарз ва статикӣ дар Java 8 ҷавоб ба парадигмаҳои муосири таҳияи нармафзор мебошанд. Барои маълумоти муфассал, лутфан ба ҳуҷҷатҳои расмӣ муроҷиат кунед .

5.3. API сана/соат (JSR 310)

Java 8 бо пешниҳоди API-и нави сана ва вақт (JSR 310) ба идоракунии сана ва вақт намуди нав меорад . Манипуляцияи сана ва вақт яке аз бадтарин нуқтаҳои дарднок барои таҳиягарони Java мебошад. Стандарти java.util.Dateзерин java.util.Calendarумуман вазъро беҳтар накард (шояд ҳатто онро печидатар кунад). Ҳамин тавр Joda-Time таваллуд шудааст : алтернативаи олиҷаноби сана/вақти API барои Java . API-и нави Date/Time дар Java 8 (JSR 310) аз ҷониби Joda-Time сахт таъсир мекунад ва беҳтаринро аз он мегирад. Бастаи нав ҳама синфҳоро барои сана, вақт, сана/вақт, минтақаҳои вақт, давомнокӣ ва коркарди вақтjava.time дар бар мегирад . Тарҳрезии API тағирнопазириро хеле ҷиддӣ гирифт: тағирот иҷозат дода намешавад (дарси душворе аз ). Агар тағирот талаб карда шавад, намунаи нави синфи мувофиқ баргардонида мешавад. Биёед ба синфҳои асосӣ ва мисолҳои истифодаи онҳо назар кунем. Синфи якум , ки дастрасӣ ба лаҳзаи ҷорӣ, сана ва вақтро бо истифода аз минтақаи вақт таъмин мекунад. метавонад ба ҷои ва истифода шавад . java.util.CalendarClockClockSystem.currentTimeMillis()TimeZone.getDefault()
// Получить системное время How смещение UTC
final Clock clock = Clock.systemUTC();
System.out.println( clock.instant() );
System.out.println( clock.millis() );
Намунаи баромади консол:
2014-04-12T15:19:29.282Z
1397315969360
Дигар синфҳои наве, ки мо онҳоро баррасӣ хоҳем кард LocaleDateва LocalTime. LocaleDateдар системаи тақвими ISO-8601 танҳо қисми санаро бидуни минтақаи вақт дар бар мегирад. Мувофиқи он, LocalTimeон танҳо як қисми codeи вақтро дар бар мегирад>.
// получить местную 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 );
Намунаи баромади консол:
2014-04-12
2014-04-12
11:25:54.568
15:25:54.568
LocalDateTimeдар системаи тақвими ISO-8601 сана ва вақтро муттаҳид мекунад LocaleDateва дар бар мегирад, аммо минтақаи вақт надорад. LocalTimeЯк мисоли оддӣ дар поён оварда шудааст.
// Get the local date/time
final LocalDateTime datetime = LocalDateTime.now();
final LocalDateTime datetimeFromClock = LocalDateTime.now( clock );

System.out.println( datetime );
System.out.println( datetimeFromClock );
Намунаи баромади консол:
2014-04-12T11:37:52.309
2014-04-12T15:37:52.309
Агар ба шумо сана/вақт барои минтақаи вақти муайян лозим бошад, ZonedDateTime. Он дорои сана ва вақт дар системаи тақвими ISO-8601 мебошад. Дар ин ҷо баъзе мисолҳо барои минтақаҳои гуногуни вақт мебошанд.
// Получение даты/времени для временной зоны
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 );
Намунаи баромади консол:
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]
Ва ниҳоят, биёед ба синф назар андозем Duration: фосилаи вақт дар сонияҳо ва наносонияҳо. Ин ҳисобкунии байни ду санаро хеле содда мекунад. Биёед бубинем, ки чӣ тавр ин корро кардан мумкин аст:
// Получаем разницу между двумя датами
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() );
Мисоли дар боло овардашуда давомнокӣ (бо рӯзҳо ва соатҳо) байни ду сана, 16 апрели соли 2014 ва 16 апрели соли 2015 -ро ҳисоб мекунад . Ин аст як мисоли баромади консол:
Duration in days: 365
Duration in hours: 8783
Таассуроти умумии сана/вақти нав дар Java 8 хеле ва хеле мусбат аст. Қисман аз он сабаб, ки тағирот ба таҳкурсии озмоишшуда (Joda-Time) асос ёфтааст, қисман аз он сабаб, ки ин дафъа масъала ба таври ҷиддӣ аз нав дида баромада шуд ва овози таҳиягарон шунида шуд. Барои тафсилот, лутфан ба ҳуҷҷатҳои расмӣ муроҷиат кунед .

5.4. Муҳаррики JavaScript Nashorn

Java 8 бо муҳаррики нави Nashorn JavaScript меояд , ки ба шумо имкон медиҳад намудҳои муайяни барномаҳои JavaScript-ро дар JVM таҳия ва иҷро кунед. Муҳаррики Nashorn JavaScript ин танҳо як амалисозии дигари javax.script.ScriptEngine аст, ки ҳамон маҷмӯи қоидаҳоро риоя мекунад, то ба Java ва JavaScript мутақобила гузорад. Ана як мисоли хурде.
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;" ) );
Намунаи баромади консол:
jdk.nashorn.api.scripting.NashornScriptEngine
Result: 2

5.5. Асос 64

Ниҳоят, дастгирии рамзгузории Base64 ба китобхонаи стандартии Java бо нашри Java 8 роҳ ёфт. Истифодаи он хеле осон аст, мисол инро нишон медиҳад.
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 );
    }
}
Натиҷаи консолии барнома ҳам матни рамзгузорӣ ва ҳам рамзкушошударо нишон медиҳад:
QmFzZTY0IGZpbmFsbHkgaW4gSmF2YSA4IQ==
Base64 finally in Java 8!
Инчунин дарсҳо барои рамзгузорон/деcodeерҳои ба URL-дӯстона, инчунин рамзгузорон/деcodeерҳои ба MIME мувофиқ ( Base64.getUrlEncoder()/ Base64.getUrlDecoder(), Base64.getMimeEncoder()/ Base64.getMimeDecoder()) мавҷуданд.

5.6. Массивҳои параллелӣ

Нашри Java 8 бисёр усулҳои навро барои коркарди массивҳои параллелӣ илова мекунад. Шояд аз ҳама муҳимтарини онҳо ин аст parallelSort(), ки метавонад навъбандиро дар мошинҳои бисёраслӣ хеле суръат бахшад. Мисоли хурди зер оилаи нави усулҳоро ( 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();
    }
}
Ин порчаи хурди code усули parallelSetAll()пур кардани массивро бо 20 000 арзишҳои тасодуфӣ истифода мебарад. Пас аз ин ба кор бурда мешавад parallelSort(). Барнома 10 элементи аввалро пеш аз мураттабсозӣ ва баъд аз он чоп мекунад, то нишон диҳад, ки массив воқеан мураттаб шудааст. Намунаи баромади барнома метавонад чунин бошад (Дар хотир доред, ки унсурҳои массив тасодуфӣ мебошанд).
Unsorted: 591217 891976 443951 424479 766825 351964 242997 642839 119108 552378
Sorted: 39 220 263 268 325 607 655 678 723 793

5.7. Параллелизм

Усулҳои нав ба синф java.util.concurrent.ConcurrentHashMapбарои дастгирии амалиёти ҷамъшуда дар асоси an objectҳои ҷараён ва ифодаҳои лямбда илова карда шуданд. Инчунин ба синф усулҳои нав барои дастгирии ҳавзи муштарак илова карда шуданд java.util.concurrent.ForkJoinPool(инчунин ба курси ройгони мо оид ба ҳамзамон Java нигаред ). Синфи нав java.util.concurrent.locks.StampedLockбарои таъмини қулфкунии қобorятҳо бо се намуди дастрасӣ барои назорати хондан/навиштан илова карда шуд (онро метавон ҳамчун алтернативаи беҳтар ба усули на он қадар хуб ҳисоб кард java.util.concurrent.locks.ReadWriteLock). Дарсҳои наве, ки ба баста илова карда шудаанд java.util.concurrent.atomic:
  • Дучандон аккумулятор
  • DoubleAdder
  • Аккумулятори дароз
  • LongAdder

6. Хусусиятҳои нав дар муҳити кории Java (JVM)

Минтақа PermGenба кор андохта шуд ва ба ҷои он Metaspace (JEP 122) иваз карда шуд. имконоти JVM -XX:PermSizeва мутаносибан бо ва -XX:MaxPermSizeиваз карда шудаанд . -XX:MetaSpaceSize-XX:MaxMetaspaceSize

7. Хулоса

Оянда дар ин ҷост: Java 8 платформаи худро бо пешниҳоди хусусиятҳое пеш бурд, ки ба таҳиягарон имкон медиҳанд, ки самараноктар бошанд. Барои интиқол додани системаҳои истеҳсолӣ ба Java 8 ҳанӯз барвақт аст, аммо қабулкунӣ бояд оҳиста-оҳиста дар тӯли чанд моҳи оянда афзоиш ёбад. Бо вуҷуди ин, ҳоло вақти он расидааст, ки ба омода кардани пойгоҳи codeи худ барои мутобиқати Java 8 оғоз кунед ва омода бошед, ки тағиротҳои Java 8-ро дар ҳолати кофӣ бехатар ва устувор ворид кунед. Ҳамчун шаҳодати қабули ҷомеа аз Java 8, Pivotal ба наздикӣ чаҳорчӯбаи Spring-ро бо дастгирии истеҳсолӣ барои Java 8 нашр кард . Шумо метавонед саҳми худро дар бораи хусусиятҳои нави ҷолиби Java 8 дар шарҳҳо пешниҳод кунед.

8. Сарчашмаҳо

Баъзе захираҳои иловагӣ, ки ҷанбаҳои гуногуни хусусиятҳои Java 8-ро амиқ баррасӣ мекунанд:
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION