JavaRush /Java Blog /Random-TK /Java 8 gollanmasy. 1 bölüm.
ramhead
Dereje

Java 8 gollanmasy. 1 bölüm.

Toparda çap edildi

"Java henizem diridir we adamlar muňa düşünip başladylar."

Java 8 bilen tanyşlygyma hoş geldiňiz. Bu gollanma size diliň ähli täze aýratynlyklaryny ädimme-ädim öwrener. Gysga, ýönekeý kod mysallary arkaly, interfeýsiň başlangyç usullaryny , lambda aňlatmalaryny , salgylanma usullaryny we gaýtalanyp boljak düşündirişleri ulanmagy öwrenersiňiz . Makalanyň soňuna çenli akymlar, funksiýa interfeýsleri, birleşme giňeltmeleri we täze Sene API ýaly API-lerdäki soňky üýtgeşmeler bilen tanyş bolarsyňyz. Içgysgynç tekstiň diwarlary ýok - diňe bir topar düşündirişli kod parçalary. Lezzet al!

Interfeýsler üçin esasy usullar

Java 8, esasy açar söz ulanyp, interfeýsde ýerine ýetirilen abstrakt däl usullary goşmaga mümkinçilik berýär . Bu aýratynlyk giňeltmek usullary hökmünde hem bellidir . Ine, ilkinji mysalymyz: interface Formula { double calculate(int a); default double sqrt(int a) { return Math.sqrt(a); } } Abstrakt usuly hasaplamakdan başga-da , Formula interfeýsi sqrt başlangyç usulyny hem kesgitleýär . Formula interfeýsini amala aşyrýan synplar diňe abstrakt hasaplamak usulyny durmuşa geçirýärler . Adaty sqrt usuly gutudan göni ulanylyp bilner. Formula Formula formula = new Formula() { @Override public double calculate(int a) { return sqrt(a * 100); } }; formula.calculate(100); // 100.0 formula.sqrt(16); // 4.0 obýekti näbelli obýekt hökmünde amala aşyrylýar. Kod gaty täsirli: sqrt (a * 100) hasaplamak üçin 6 setir kod . Indiki bölümde görşümiz ýaly, Java 8-de ýeke-täk usul obýektlerini durmuşa geçirmegiň has özüne çekiji usuly bar.

Lambda aňlatmalary

Java-yň irki wersiýalarynda setirleriň toplumyny nädip tertipleşdirmelidiginiň ýönekeý bir mysalyndan başlalyň: Statistik kömekçi usuly Collections.sort berlen sanawyň elementlerini tertiplemek üçin sanaw we Deňeşdiriji alýar . Oftenygy-ýygydan bolup geçýän zat, näbelli deňeşdirijileri döredip, olary tertipleşdirmek usullaryna geçirmekdir. Java 8 hemişe näbelli zatlary döretmegiň ýerine, has az sintaksis, lambda aňlatmalaryny ulanmaga mümkinçilik berýär : Görşüňiz ýaly kod has gysga we okamak aňsat. Hereöne bu ýerde hasam gysgalýar: Bir setirli usul üçin {ly egrilen ýaýlardan we yzyna gaýtarmak sözünden dynyp bilersiňiz . Hereöne ine, kod hasam gysgalýan ýeri: Java düzüjisi parametrleriň görnüşlerinden habarly, şonuň üçin olary hem goýup bilersiňiz. Indi lambda aňlatmalarynyň hakyky durmuşda ulanyp boljakdygyna has çuňňur öwreneliň. List names = Arrays.asList("peter", "anna", "mike", "xenia"); Collections.sort(names, new Comparator () { @Override public int compare(String a, String b) { return b.compareTo(a); } }); Collections.sort(names, (String a, String b) -> { return b.compareTo(a); }); Collections.sort(names, (String a, String b) -> b.compareTo(a)); Collections.sort(names, (a, b) -> b.compareTo(a));

Funksiýa interfeýsleri

Lambda aňlatmalary Java görnüş ulgamyna nädip laýyk gelýär? Her lambda interfeýs bilen kesgitlenen berlen görnüşe gabat gelýär. Funksiýa interfeýsi diýilýän zat takyk yglan edilen abstrakt usuly öz içine almalydyr. Berlen görnüşiň her lambda aňlatmasy bu abstrakt usula gabat geler.Dymmaklyk usullar abstrakt usullar bolmansoň, funksional interfeýsiňize deslapky usullary goşup bilersiňiz. Interfeýsde diňe bir abstrakt usul bar bolsa, lambda aňlatmasy hökmünde özbaşdak interfeýsi ulanyp bileris. Interfeýsiňiziň bu şertleri kanagatlandyrýandygyna göz ýetirmek üçin @FunctionalInterface düşündirişini goşmaly . Düzüjä bu düşündiriş bilen interfeýsde diňe bir usulyň bolmalydygy we bu interfeýsde ikinji abstrakt usula duş gelse ýalňyşlyk goýberjekdigi habar berler. Mysal: @FunctionalInterface düşündirişi yglan edilmedik ýagdaýynda-da bu koduň hem güýje girjekdigini ýadyňyzdan çykarmaň . @FunctionalInterface interface Converter { T convert(F from); } Converter converter = (from) -> Integer.valueOf(from); Integer converted = converter.convert("123"); System.out.println(converted); // 123

Usullara we konstruktorlara salgylanmalar

Aboveokardaky mysal, statistiki usul salgylanmasyny ulanmak arkaly hasam aňsatlaşdyrylyp bilner: Java 8 :: açar söz nyşanlaryny ulanyp, usullara we konstruktorlara salgylanmalary geçirmäge mümkinçilik berýär . Aboveokardaky mysal, statistiki usullaryň nähili ulanylyp bilinjekdigini görkezýär. Objectsöne obýektlerdäki usullara hem salgylanyp bileris: Geliň , konstruktorlar üçin nähili işleýändigine göz aýlalyň . Ilki bilen, dürli konstruktorlar bilen bir mysal kesgitläliň: Soňra, täze adam obýektlerini döretmek üçin “PersonFactory” zawod interfeýsini kesgitleýäris : Converter converter = Integer::valueOf; Integer converted = converter.convert("123"); System.out.println(converted); // 123 class Something { String startsWith(String s) { return String.valueOf(s.charAt(0)); } } Something something = new Something(); Converter converter = something::startsWith; String converted = converter.convert("Java"); System.out.println(converted); // "J" class Person { String firstName; String lastName; Person() {} Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } } interface PersonFactory

{ P create(String firstName, String lastName); } Zawody el bilen ýerine ýetirmegiň ýerine, hemme zady konstruktor salgylanmasy bilen birleşdirýäris: Şahsy synpyň konstruktoryna Şahsy :: täze arkaly salgylanma döredýäris . Java düzüjisi, konstruktorlaryň goluny PersonFactory.create usulynyň goly bilen deňeşdirip, degişli konstruktory awtomatiki çagyrar . PersonFactory personFactory = Person::new; Person person = personFactory.create("Peter", "Parker");

Lambda sebiti

Lambda aňlatmalaryndan daşarky çäk üýtgeýjilerine girişi guramak, näbelli bir obýektiň girişine meňzeýär. Localerli çäklerden soňky üýtgeýänlere , mysal üçin meýdanlara we jemi üýtgeýänlere girip bilersiňiz.
Localerli üýtgeýänlere girmek
Lambda aňlatmasynyň çäginden iň soňky üýtgediji bilen ýerli üýtgeýjini okap bileris : anöne näbelli zatlardan tapawutlylykda, lambda aňlatmasyndan girip boljak üýtgeýänleri gutarnykly diýip yglan etmeli däl . Bu kod hem dogry: Şeýle-de bolsa, üýtgeýji üýtgewsiz galmalydyr. kod düzmek üçin gutarnykly gutarnykly boluň . Aşakdaky kod düzülmez: lambda aňlatmasynyň içinde numuň üýtgemegine -de rugsat berilmeýär. final int num = 1; Converter stringConverter = (from) -> String.valueOf(from + num); stringConverter.convert(2); // 3 int num = 1; Converter stringConverter = (from) -> String.valueOf(from + num); stringConverter.convert(2); // 3 int num = 1; Converter stringConverter = (from) -> String.valueOf(from + num); num = 3;
Instant meýdanlaryna we statistik üýtgeýänlere girmek
Varierli üýtgeýjilerden tapawutlylykda, lambda aňlatmalarynyň içindäki mysal meýdanlaryny we statistiki üýtgeýjileri okap we üýtgedip bileris. Bu hereketi näbelli zatlardan bilýäris. class Lambda4 { static int outerStaticNum; int outerNum; void testScopes() { Converter stringConverter1 = (from) -> { outerNum = 23; return String.valueOf(from); }; Converter stringConverter2 = (from) -> { outerStaticNum = 72; return String.valueOf(from); }; } }
Interfeýsleriň esasy usullaryna girmek
Birinji bölümden formula mysaly bilen mysaly ýadyňyzdamy ? Formula interfeýsi, näbelli obýektleri goşmak bilen, formulanyň her mysalyndan girip bolýan deslapky sqrt usulyny kesgitleýär. Bu lambda aňlatmalary bilen işlemeýär. Lambda aňlatmalarynyň içinde deslapky usullara girip bolmaýar. Aşakdaky kod düzmeýär: Formula formula = (a) -> sqrt( a * 100);

Gurlan funksional interfeýsler

JDK 1.8 API köp sanly içerki interfeýsleri öz içine alýar. Olaryň käbiri Java-yň öňki wersiýalaryndan belli. Mysal üçin deňeşdiriji ýa-da işledip bolýan . Bu interfeýsler, @FunctionalInterface düşündirişini ulanyp, lambda goldawyny öz içine alýar . Javaöne Java 8 API durmuşyňyzy aňsatlaşdyrjak täze funksional interfeýslerden hem doly. Bu interfeýsleriň käbiri Google-yň Guava kitaphanasyndan belli . Bu kitaphana bilen tanyş bolsaňyzam, peýdaly interfeýs usullary bilen bu interfeýsleriň nädip giňeldilendigine has içgin göz aýlamaly.
Predicates
Predicates - bir argument bilen Boolean funksiýalary. Interfeýsde predikatlary ulanyp, çylşyrymly logiki aňlatmalary (we, ýa-da ret etmek) döretmek üçin dürli başlangyç usullar bar Predicate predicate = (s) -> s.length() > 0; predicate.test("foo"); // true predicate.negate().test("foo"); // false Predicate nonNull = Objects::nonNull; Predicate isNull = Objects::isNull; Predicate isEmpty = String::isEmpty; Predicate isNotEmpty = isEmpty.negate();
Funksiýalar
Funksiýalar bir argument alýar we netije berýär. Birnäçe funksiýany bir zynjyrda birleşdirmek (düzmek we soň) üçin deslapky usullar ulanylyp bilner. Function toInteger = Integer::valueOf; Function backToString = toInteger.andThen(String::valueOf); backToString.apply("123"); // "123"
Üpjün edijiler
Üpjün edijiler bir ýa-da başga bir netijäni (mysal) gaýtaryp berýärler. Funksiýalardan tapawutlylykda üpjün edijiler argument almaýarlar. Supplier personSupplier = Person::new; personSupplier.get(); // new Person
Sarp edijiler
Sarp edijiler interfeýs usullaryny ýekeje argument bilen görkezýärler. Consumer greeter = (p) -> System.out.println("Hello, " + p.firstName); greeter.accept(new Person("Luke", "Skywalker"));
Deňeşdirijiler
Deňeşdirijiler Java-yň öňki wersiýalaryndan bize mälim. Java 8 interfeýslere dürli başlangyç usullary goşmaga mümkinçilik berýär. Comparator comparator = (p1, p2) -> p1.firstName.compareTo(p2.firstName); Person p1 = new Person("John", "Doe"); Person p2 = new Person("Alice", "Wonderland"); comparator.compare(p1, p2); // > 0 comparator.reversed().compare(p1, p2); // < 0
Mümkinçilikler
Opsiýalar interfeýsi işlemeýär, ýöne NullPointerException-yň öňüni almak üçin peýdalydyr . Bu indiki bölüm üçin möhüm nokat, geliň, bu interfeýsiň işleýşine gysgaça göz aýlalyň. Meýletin interfeýs, null ýa-da null bolup bilýän bahalar üçin ýönekeý gap . Usulyň bahany ýa-da hiç zady yzyna gaýtaryp biljekdigini göz öňüne getiriň. Java 8-de, null yzyna gaýtarmagyň ýerine , goşmaça mysal getirýärsiňiz . Comparator comparator = (p1, p2) -> p1.firstName.compareTo(p2.firstName); Person p1 = new Person("John", "Doe"); Person p2 = new Person("Alice", "Wonderland"); comparator.compare(p1, p2); // > 0 comparator.reversed().compare(p1, p2); // < 0

Akym

java.util.Stream - bu bir ýa-da köp amal ýerine ýetirilýän elementleriň yzygiderliligi. Her akym amaly ýa-da aralykdyr. Terminal amallary belli bir görnüşiň netijesini gaýtaryp berýär, aralyk amallar bolsa akym obýektiniň özüni yzyna gaýtaryp, usul jaňlarynyň zynjyryny döretmäge mümkinçilik berýär. Akym, java.util ýaly sanawlar we toplumlar üçin ýygnamak (kartalar goldanylmaýar) ýaly interfeýsdir . Her akym amaly yzygiderli ýa-da paralel ýerine ýetirilip bilner. Akymyň işleýşine göz aýlalyň. Ilki bilen, setirleriň sanawy görnüşinde nusga koduny dörederis: Java 8-de kolleksiýalar , Collection.stream () ýa-da Collection.parallelStream () jaň edip, akymlary döredip bilersiňiz . Indiki bölümde iň möhüm, ýönekeý akym amallary düşündiriler. List stringCollection = new ArrayList<>(); stringCollection.add("ddd2"); stringCollection.add("aaa2"); stringCollection.add("bbb1"); stringCollection.add("aaa1"); stringCollection.add("bbb3"); stringCollection.add("ccc"); stringCollection.add("bbb2"); stringCollection.add("ddd1");
Süzgüç
Süzgüç, akymyň ähli elementlerini süzmek üçin predikatlary kabul edýär. Bu amal, aralyk bolup, netijede (süzülen) netijede beýleki akym amallaryna (mysal üçinEach) jaň etmäge mümkinçilik berýär. “ForEach” eýýäm süzülen akymyň her elementinde ýerine ýetiriljek amaly kabul edýär. “ForEach” terminal amalydyr. Mundan başga-da, beýleki amallary çagyrmak mümkin däl. stringCollection .stream() .filter((s) -> s.startsWith("a")) .forEach(System.out::println); // "aaa2", "aaa1"
Sortirlendi
Sortirlenen, akymyň tertipli görnüşini görkezýän aralyk amal. Deňeşdirijiňizi görkezmeseňiz, elementler dogry tertipde tertiplenýär . stringCollection .stream() .sorted() .filter((s) -> s.startsWith("a")) .forEach(System.out::println); // "aaa1", "aaa2" Sortirlenen kolleksiýanyň özüne täsir etmezden akymyň tertipli görnüşini döredýändigini ýadyňyzdan çykarmaň. StringCollection elementleriniň tertibi elýeterli däl: System.out.println(stringCollection); // ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1
Karta
Aralyk karta amaly, netijäni ulanyp, her elementi başga bir obýekte öwürýär. Aşakdaky mysal her setiri baş harp setirine öwürýär. Eachöne her bir obýekti başga görnüşe öwürmek üçin kartany ulanyp bilersiňiz. Alnan akym obýektleriniň görnüşi, karta geçirýän funksiýaňyza baglydyr. stringCollection .stream() .map(String::toUpperCase) .sorted((a, b) -> b.compareTo(a)) .forEach(System.out::println); // "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"
Duşuşyk
Akym gatnaşyklarynda belli bir predikatyň hakykatyny barlamak üçin dürli gabat gelýän amallar ulanylyp bilner. Matchhli gabat gelýän amallar terminal bolup, Boolean netijesini gaýtaryp berýär. boolean anyStartsWithA = stringCollection .stream() .anyMatch((s) -> s.startsWith("a")); System.out.println(anyStartsWithA); // true boolean allStartsWithA = stringCollection .stream() .allMatch((s) -> s.startsWith("a")); System.out.println(allStartsWithA); // false boolean noneStartsWithZ = stringCollection .stream() .noneMatch((s) -> s.startsWith("z")); System.out.println(noneStartsWithZ); // true
Hasapla
Hasap, akym elementleriniň sanyny uzynlygyna gaýtaryp berýän terminal amalydyr . long startsWithB = stringCollection .stream() .filter((s) -> s.startsWith("b")) .count(); System.out.println(startsWithB); // 3
Azaltmak
Bu, geçen funksiýany ulanyp akym elementlerini gysgaldýan terminal amalydyr. Netijede gysgaldylan bahany öz içine alýan Goşmaça bolar . Optional reduced = stringCollection .stream() .sorted() .reduce((s1, s2) -> s1 + "#" + s2); reduced.ifPresent(System.out::println); // "aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2"

Paralel akymlar

Aboveokarda belläp geçişimiz ýaly akymlar yzygiderli ýa-da parallel bolup biler. Yzygiderli akym amallary yzygiderli sapakda, paralel akym amallary bolsa birnäçe parallel sapaklarda ýerine ýetirilýär. Aşakdaky mysal paralel akymyň kömegi bilen öndürijiligi nädip ýokarlandyrmalydygyny görkezýär. Ilki bilen üýtgeşik elementleriň uly sanawyny döredeliň: Indi bu ýygyndynyň akymyny tertiplemek üçin sarp edilen wagty kesgitläris. int max = 1000000; List values = new ArrayList<>(max); for (int i = 0; i < max; i++) { UUID uuid = UUID.randomUUID(); values.add(uuid.toString()); }
Seriýa akymy
long t0 = System.nanoTime(); long count = values.stream().sorted().count(); System.out.println(count); long t1 = System.nanoTime(); long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0); System.out.println(String.format("sequential sort took: %d ms", millis)); // sequential sort took: 899 ms
Parallel akym
long t0 = System.nanoTime(); long count = values.parallelStream().sorted().count(); System.out.println(count); long t1 = System.nanoTime(); long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0); System.out.println(String.format("parallel sort took: %d ms", millis)); // parallel sort took: 472 ms Görşüňiz ýaly, iki bölek hem birmeňzeş, ýöne paralel sortlamak 50% has çalt. Size zerur zat, akymy () parallelStream () -e üýtgetmek .

Karta

Öň bellenip geçilişi ýaly, kartalar akymlary goldamaýar. Munuň ýerine karta umumy meseleleri çözmek üçin täze we peýdaly usullary goldap başlady. Aboveokardaky kod içgin bolmaly: putIfAbsent bize goşmaça null barlaglary ýazmazlyk barada duýduryş berýär. forEach karta bahalarynyň her biri üçin ýerine ýetirmek funksiýasyny kabul edýär. Bu mysal, funksiýalary ulanyp, karta bahalarynda amallaryň nähili ýerine ýetirilýändigini görkezýär: Indiki, berlen açar üçin ýazgyny diňe belli bir baha bilen karta eden ýagdaýynda nädip aýyrmalydygyny öwreneris: Anotherene bir gowy usul: Karta ýazgylaryny birleşdirmek gaty aňsat: Birleşmek ýa-da berlen açar üçin ýazgy ýok bolsa, açary / bahany karta salar ýa-da bar bolan ýazgynyň bahasyny üýtgedjek birleşdiriş funksiýasy çagyrylar. Map map = new HashMap<>(); for (int i = 0; i < 10; i++) { map.putIfAbsent(i, "val" + i); } map.forEach((id, val) -> System.out.println(val)); map.computeIfPresent(3, (num, val) -> val + num); map.get(3); // val33 map.computeIfPresent(9, (num, val) -> null); map.containsKey(9); // false map.computeIfAbsent(23, num -> "val" + num); map.containsKey(23); // true map.computeIfAbsent(3, num -> "bam"); map.get(3); // val33 map.remove(3, "val3"); map.get(3); // val33 map.remove(3, "val33"); map.get(3); // null map.getOrDefault(42, "not found"); // not found map.merge(9, "val9", (value, newValue) -> value.concat(newValue)); map.get(9); // val9 map.merge(9, "concat", (value, newValue) -> value.concat(newValue)); map.get(9); // val9concat
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION