JavaRush /Java Blog /Random-TL /Coffee break #108. 12 Karaniwang Paggamit ng Java Stream,...

Coffee break #108. 12 Karaniwang Paggamit ng Java Stream, Paano Suriin ang Paglalaan ng Memorya ng isang Bagay sa Java

Nai-publish sa grupo

12 Karaniwang Paraan sa Paggamit ng Mga Java Stream

Pinagmulan: Dev.to Ang Java Streams API ay unang lumitaw sa Java 8. Ang layunin nito ay magbigay ng mas compact na paraan upang maisagawa ang mga karaniwang operasyon sa mga koleksyon ng mga bagay. Gayundin, ang Java Streams API ay maaaring gamitin upang ipatupad ang mga kumplikadong algorithm. Sa artikulong ito, pag-uusapan natin ang tungkol sa mga karaniwang kaso ng paggamit ng Java Streams. Coffee break #108.  12 Karaniwang Paggamit ng Mga Java Stream, Paano Suriin ang Paglalaan ng Memorya ng Bagay sa Java - 1Una, linawin natin ang ilang mga pangunahing kaalaman:
  • stream() - lumilikha ng stream mula sa koleksyon.

  • collect() - nangongolekta ng stream sa isang object. Ang isang bagay ay maaaring isang koleksyon, isang primitive, o isang custom na klase.

  • Ang mga kolektor ay isang klase na nagbibigay ng (maraming) mga static na pamamaraan para sa pagkolekta ng mga stream.

Ngayon tingnan natin ang ilang mga kaso ng paggamit para sa Mga Stream:

1. Pagsala

  • Ginagamit para mag-alis ng mga value mula sa isang Collection batay sa isang kundisyon.

  • Upang i-filter ang mga elemento ng koleksyon batay sa isang kundisyon, gamitin ang filter() na paraan . Ang mga tumutugmang elemento lamang ang nai-save.

Halimbawa: alisin ang lahat ng mga kakaibang numero sa listahan.
List<Integer> evenNumbers = originalList.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());

2. Preprocessing

  • Kapaki-pakinabang kapag ang bawat halaga sa isang koleksyon ay kailangang baguhin sa lugar.

  • Ang paraan ng map() ay ginagamit upang maglapat ng function sa bawat elemento ng koleksyon at magbalik ng bagong koleksyon ng mga kinakalkula na halaga.

Halimbawa, i-convert natin ang bawat halaga sa parisukat nito.
List<Integer> squares = originalList.stream()
        .map(n -> n * n)
        .collect(Collectors.toList());

3. Pagbabalik-loob

  • Kapaki-pakinabang kapag gusto nating gawing ibang koleksyon ang isang koleksyon.

  • Mayroong ilang mga paraan upang makamit ito.

Gaya ng nabanggit sa itaas, maaari nating gamitin ang mga pamamaraan ng map() at collect() upang gawing ibang koleksyon ang isang koleksyon.

Halimbawa 1: Gumawa ng Mapa mula sa Mga Listahan.

I-convert ang isang listahan ng mga string sa isang mapa ng mga string at haba.
Map<String, Integer> wordLengths = words.stream()
        .collect(Collectors.toMap(
                word -> word,
                word -> word.length()));

Halimbawa 2. Pag-convert ng listahan sa mga set.

Ito ay isang karaniwang kaso ng paggamit para sa pag-alis ng mga duplicate. Bukod pa rito, kung gusto naming ibalik ang mga elemento sa listahan, maaari naming gamitin ang stream() at collect() na mga pamamaraan nang dalawang beses . Halimbawa, i-convert natin ang isang listahan ng mga string sa isang listahan ng mga natatanging string:
// if we want to collect to a set
Set<String> uniqueWords = words.stream()
        .collect(Collectors.toSet());

// OR

// if we want to start and end as a list
List<String> uniqueWords = words.stream()
        .collect(Collectors.toSet()).stream().collect(Collectors.toList());

Halimbawa 3. Pag-convert ng isang listahan ng mga produkto sa isang listahan ng kanilang mga pangalan. (Flattening - Alignment)

List<String> productNames = products.stream()
        .map(product -> product.getName())
        .collect(Collectors.toList());

4. Pagbawas

  • Binabawasan ang Koleksyon sa iisang halaga.

  • Ang paraan ng reduce() ay ginagamit upang maglapat ng isang function sa bawat elemento ng koleksyon at magbalik ng isang halaga.

Tandaan na dahil nagbabalik ang paraan ng reduce() ng iisang value, hindi ito magagamit para magbalik ng Collection. Halimbawa, ibubuod namin ang lahat ng mga halaga sa listahan:
int sum = numbers.stream()
        .reduce(0, (a, b) -> a + b);

5. Pagpapangkat

  • Pinagpapangkat ang mga elemento ng isang Koleksyon batay sa isang partikular na kundisyon.

  • Upang pagpangkatin ang mga elemento ng Collection ayon sa kundisyon, gamitin ang Collectors.groupingBy() method .

Halimbawa, pangkatin natin ang lahat ng produkto sa mga listahan ng produkto ayon sa kanilang mga kategorya.
Map<String, List<Product>> productsByCategory = products.stream()
        .collect(Collectors.groupingBy(product -> product.getCategory()));

6. Paghahanap

  • Hinahanap ang una o anumang elemento ng Koleksyon na tumutugma sa isang kundisyon.

  • Ang findFirst() at findAny() na mga pamamaraan ay ginagamit para sa paghahanap .

Ito ay kadalasang katulad ng isang linear na paghahanap. Halimbawa, hinahanap namin ang unang salita sa listahan, ang haba nito ay lumampas sa 5 character.
Optional<String> firstLongWord = words.stream()
        .filter(word -> word.length() > 5)
        .findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.

7. Pag-uuri

  • Pinagbukud-bukod ang mga elemento ng Mga Koleksyon.

  • Ang sorted() method ay ginagamit para sa sorting .

Sa pangkalahatan, ang Collections.sort() ay sapat upang pagbukud-bukurin ang isang koleksyon. Maaari naming gamitin ang sorted() partikular kung gusto naming magpatakbo ng isa pang operasyon. Halimbawa, pag-uri-uriin natin ang isang listahan ng mga numero sa pataas na pagkakasunud-sunod at pagkatapos ay ibalik ang mga unang elemento ng k.
List<Integer> topK = numbers.stream()
        .sorted()
        .limit(k)
        .collect(Collectors.toList());

8. Paghahati

  • Pinaghihiwalay ang mga elemento ng isang Koleksyon batay sa isang partikular na kundisyon.

  • Ginagamit ang Collectors.partitioningBy() para paghiwalayin ang mga elemento .

Ang isang split ay katulad ng isang pangkat, maliban na nagbabalik ito ng dalawang koleksyon—isa para sa mga elementong tumutugma sa kundisyon at isa para sa mga elementong hindi tumutugma sa kundisyon. Halimbawa, hatiin natin ang mga estudyante sa mga nakapasa sa pagsusulit at sa mga bumagsak dito.
Map<Boolean, List<Student>> passingFailing = students
        .stream()
        .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

9. Nagbibilang

  • Binibilang ang bilang ng mga elemento na tumutugma sa isang kundisyon.

  • Ang count() method ay ginagamit upang bilangin ang bilang ng mga elemento na tumutugma sa isang kundisyon .

Halimbawa, bilangin natin ang bilang ng mga salita sa listahan na ang haba ay lumampas sa 5 character.
long count = words.stream()
        .filter(word -> word.length() > 5)
        .count();

10. Saklaw

  • Lumilikha ng isang hanay ng mga halaga.

  • Upang lumikha ng isang hanay ng mga halaga, gamitin ang range() na paraan .

May mga espesyal na klase para sa paglikha ng mga stream ng ilang partikular na uri - IntStream , LongStream , DoubleStream at Stream . Ang mga klase na ito ay kapaki-pakinabang kapag nagtatrabaho sa mga primitive na uri ng numero. Upang i-convert ang isang array sa isang stream, gamitin ang Arrays.stream() . Halimbawa, gumawa tayo ng hanay ng mga numero mula 0 hanggang 10.
int[] numbers = IntStream.range(0, 10).toArray();

11. Pagtutugma

  • Tumutugma sa mga elemento ng isang koleksyon na may isang panaguri (kondisyon).

  • Ang mga pamamaraan tulad ng anyMatch() , allMatch() , at noneMatch() ay ginagamit upang tumugma sa mga elemento ng koleksyon na may predicate at magbalik ng boolean value .

Halimbawa, tingnan natin ang mga produktong may presyong mas mataas sa 10.
// true when all elements match the predicate
boolean allMatch = products.stream()
        .allMatch(product -> product.getPrice() > 10);

// true when any element matches the predicate
boolean anyMatch = products.stream()
        .anyMatch(product -> product.getPrice() > 10);

// true when no elements match the predicate
boolean noneMatch = products.stream()
        .noneMatch(product -> product.getPrice() > 10);

12. Pagsali

  • Pinagsasama-sama ang mga elemento ng isang koleksyon sa isang string.

  • Upang isama ang mga elemento ng koleksyon sa isang string, gamitin ang Collectors.joining() method .

Halimbawa, pagsamahin natin ang lahat ng salita sa isang listahan sa isang string.
String joinedWords = words.stream()
        .collect(Collectors.joining(" "));
Iyon lang para sa mga pangkalahatang senaryo. May iba pang hindi gaanong karaniwang mga senaryo na maaari mong tuklasin nang mag-isa:
  • Parallel Stream;
  • Mga istatistika;
  • Mga Custom na Kolektor.

Mga Pakinabang ng mga Thread

  • Mas compact na code—binabawasan ang dami ng code na kinakailangan para maproseso ang koleksyon.

  • Mas kaunting mga intermediate variable. Maaaring magdulot ng mga error na mangyari ang mga intervening variable. Kung mas kaunti ang mayroon, mas madaling maiwasan ang mga hindi inaasahang pagkakamali.

  • Intuitive na code. Ang ilang mga developer ay hindi sasang-ayon na ang mga thread ay mas intuitive kaysa sa iba pang mga pamamaraan. Gayunpaman, kapag nasanay na tayo sa kanila, nagiging mas intuitive sila kaysa sa iba pang mga pamamaraan.

Salamat sa pagbabasa. Sana ay nasiyahan ka sa artikulong ito. Marami pang mga kaso kung saan maaaring gamitin ang mga thread na hindi sakop sa paksang ito. Huwag mag-atubiling magdagdag ng anumang karaniwang senaryo na napalampas ko.

Paano suriin ang paglalaan ng memorya ng isang bagay sa Java

Pinagmulan: DZone Ipinapakita ng artikulong ito ang tatlong pinakakilalang paraan upang suriin ang paglalaan ng memorya ng isang bagay sa Java.

Pagtatasa ng memorya gamit ang Profiler

Ang pinakamadaling paraan upang tantyahin ang memorya ng ilang mga bagay ay direktang tumingin sa JVM memory gamit ang isang profiler tulad ng Visual VM . Coffee break #108.  12 Karaniwang Paggamit ng Mga Java Stream, Paano Suriin ang Paglalaan ng Memorya ng Bagay sa Java - 2Ang problema sa diskarteng ito ay kailangan mong kumonekta sa isang tumatakbong JVM, na maaaring hindi posible para sa mga kapaligiran ng produksyon dahil sa mga kadahilanang pangseguridad.

Pagtatasa ng memorya gamit ang Mga Instrumento

Ang isa pang paraan upang tantyahin ang inilalaan na memorya para sa isang partikular na bagay ay ang paggamit ng Mga Instrumento. Sa madaling salita, kailangan nating lumikha ng isang klase at i-compile ito sa isang JAR. Pagkatapos lumikha ng JAR, dapat nating isagawa ang ating JVM kasama ang JAR na iyon. Maaari mong malaman ang higit pa tungkol sa paraang ito dito . Ang downside dito ay ang pangangailangan na magdagdag ng isang partikular na jar file sa JVM, na maaaring hindi katanggap-tanggap para sa produksyon dahil sa seguridad o mga kaugnay na isyu.

Pagtatasa ng memorya gamit ang JOL Library

Bilang isa pang opsyon, maaari naming gamitin ang JOL Library . Ito ay isang napakalakas na library na maaaring magbigay ng isang detalyadong pagtatantya ng bigat ng isang bagay at ang memorya na inilalaan ng isang bagay na halimbawa. Para magamit ang library, kailangan naming magdagdag ng dependency:
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.16</version>
</dependency>
Pagkatapos nito ay magagamit natin ito tulad nito:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")

ObjectSizeCalculator mula sa archive ng Twitter

Ang pampublikong GitHub repository ng Twitter ay may tool class na tinatawag na ObjectSizeCalculator na maaaring tantyahin ang inilalaan na memorya para sa isang partikular na object instance. Hindi ito nangangailangan ng maraming memorya o oras upang magamit. Ang proseso ng pagsusuri ay tumatagal ng ilang segundo, kahit na para sa malalaking bagay. Ang paggamit ng klase na ito ay medyo simple:
ObjectSizeCalculator.getObjectSize(address)
Inirerekomenda ko ang paraang ito, ngunit tandaan na ito ay sinusuportahan lamang ng Java Hotspot, OpenJDK at TwitterJDK.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION