CodeGym /జావా కోర్సు /మాడ్యూల్ 2: జావా కోర్ /స్ట్రీమ్‌లతో పని చేయడం, పార్ట్ 1

స్ట్రీమ్‌లతో పని చేయడం, పార్ట్ 1

మాడ్యూల్ 2: జావా కోర్
స్థాయి , పాఠం
అందుబాటులో ఉంది

Stream1. తరగతి యొక్క పద్ధతుల జాబితా

డేటా స్ట్రీమ్‌ల గొలుసులను నిర్మించడాన్ని సులభతరం చేయడానికి తరగతి Streamసృష్టించబడింది . దీన్ని సాధించడానికి, తరగతి కొత్త వస్తువులను తిరిగి ఇచ్చే పద్ధతులను కలిగి ఉంది.Stream<T>Stream

ఈ డేటా స్ట్రీమ్‌లలో ప్రతి ఒక్కటి ఒక సాధారణ చర్యను చేస్తుంది, కానీ మీరు వాటిని గొలుసులుగా మిళితం చేసి, ఆసక్తికరమైన లాంబ్డా ఫంక్షన్‌లను జోడిస్తే , మీకు కావలసిన అవుట్‌పుట్‌ను రూపొందించడానికి మీకు శక్తివంతమైన మెకానిజం ఉంటుంది. త్వరలో మీరు మీ కోసం చూస్తారు.

ఇక్కడ తరగతి పద్ధతులు ఉన్నాయి Stream(అత్యంత ప్రాథమికమైనవి మాత్రమే):

పద్ధతులు వివరణ
Stream<T> of()
వస్తువుల సమితి నుండి స్ట్రీమ్‌ను సృష్టిస్తుంది
Stream<T> generate()
పేర్కొన్న నియమం ప్రకారం స్ట్రీమ్‌ను రూపొందిస్తుంది
Stream<T> concat()
రెండు ప్రవాహాలను కలుపుతుంది
Stream<T> filter()
డేటాను ఫిల్టర్ చేస్తుంది, పేర్కొన్న నియమానికి సరిపోయే డేటాను మాత్రమే పంపుతుంది
Stream<T> distinct()
నకిలీలను తొలగిస్తుంది. ఇప్పటికే ఎదుర్కొన్న డేటాను పాస్ చేయదు
Stream<T> sorted()
డేటాను క్రమబద్ధీకరిస్తుంది
Stream<T> peek()
స్ట్రీమ్‌లోని ప్రతి మూలకంపై చర్యను అమలు చేస్తుంది
Stream<T> limit(n)
కుదించబడిన స్ట్రీమ్‌ను తిరిగి అందిస్తుంది, తద్వారా అది పేర్కొన్న పరిమితి కంటే ఎక్కువ ఉండదు
Stream<T> skip(n)
మొదటి n మూలకాలను దాటవేస్తుంది
Stream<R> map()
డేటాను ఒక రకం నుండి మరొక రకానికి మారుస్తుంది
Stream<R> flatMap()
డేటాను ఒక రకం నుండి మరొక రకానికి మారుస్తుంది
boolean anyMatch()
స్ట్రీమ్‌లో పేర్కొన్న నియమానికి సరిపోలే కనీసం ఒక మూలకం ఉందా అని తనిఖీ చేస్తుంది
boolean allMatch()
స్ట్రీమ్‌లోని అన్ని అంశాలు పేర్కొన్న నియమానికి సరిపోతాయో లేదో తనిఖీ చేస్తుంది
boolean noneMatch()
స్ట్రీమ్‌లోని మూలకాలు ఏవీ పేర్కొన్న నియమానికి సరిపోలడం లేదా అని తనిఖీ చేస్తుంది
Optional<T> findFirst()
నియమానికి సరిపోలే మొదటి మూలకాన్ని చూపుతుంది
Optional<T> findAny()
స్ట్రీమ్‌లోని నియమానికి సరిపోలే ఏదైనా మూలకాన్ని అందిస్తుంది
Optional<T> min()
డేటా స్ట్రీమ్‌లో కనీస మూలకం కోసం శోధిస్తుంది
Optional<T> max()
డేటా స్ట్రీమ్‌లో గరిష్ట మూలకాన్ని అందిస్తుంది
long count()
డేటా స్ట్రీమ్‌లోని మూలకాల సంఖ్యను అందిస్తుంది
R collect()
స్ట్రీమ్ నుండి మొత్తం డేటాను చదివి, దానిని సేకరణగా అందిస్తుంది

Stream2. తరగతి ద్వారా ఇంటర్మీడియట్ మరియు టెర్మినల్ కార్యకలాపాలు

మీరు చూడగలిగినట్లుగా, పై పట్టికలోని అన్ని పద్ధతులు aని తిరిగి ఇవ్వవు Stream. తరగతి యొక్క పద్ధతులను ఇంటర్మీడియట్ ( నాన్-టెర్మినల్ అని కూడా పిలుస్తారు ) పద్ధతులు మరియు టెర్మినల్ పద్ధతులుగా Streamవిభజించవచ్చు అనే వాస్తవానికి ఇది సంబంధించినది .

ఇంటర్మీడియట్ పద్ధతులు

ఇంటర్మీడియట్ పద్ధతులు ఇంటర్‌ఫేస్‌ను అమలు చేసే వస్తువును తిరిగి అందిస్తాయి Streamమరియు అవి ఒకదానితో ఒకటి బంధించబడతాయి.

టెర్మినల్ పద్ధతులు

టెర్మినల్ పద్ధతులు a కాకుండా వేరే విలువను అందిస్తాయి Stream.

పద్ధతి కాల్ పైప్లైన్

ఈ విధంగా, మీరు ఎన్ని ఇంటర్మీడియట్ పద్ధతులతో కూడిన స్ట్రీమ్ పైప్‌లైన్‌ను నిర్మించవచ్చు మరియు చివరిలో ఒకే టెర్మినల్ పద్ధతి కాల్ చేయవచ్చు. ఈ విధానం కోడ్ రీడబిలిటీని పెంచుతూ, సంక్లిష్టమైన తర్కాన్ని అమలు చేయడానికి మిమ్మల్ని అనుమతిస్తుంది.

పద్ధతి కాల్ పైప్లైన్

డేటా స్ట్రీమ్‌లోని డేటా ఏమాత్రం మారదు. ఇంటర్మీడియట్ పద్ధతుల గొలుసు అనేది డేటా ప్రాసెసింగ్ పైప్‌లైన్‌ను పేర్కొనే స్లిక్ (డిక్లరేటివ్) మార్గం, ఇది టెర్మినల్ పద్ధతిని పిలిచిన తర్వాత అమలు చేయబడుతుంది.

మరో మాటలో చెప్పాలంటే, టెర్మినల్ పద్ధతిని పిలవకపోతే, డేటా స్ట్రీమ్‌లోని డేటా ఏ విధంగానూ ప్రాసెస్ చేయబడదు. టెర్మినల్ పద్ధతిని పిలిచిన తర్వాత మాత్రమే స్ట్రీమ్ పైప్‌లైన్‌లో పేర్కొన్న నిబంధనల ప్రకారం డేటా ప్రాసెస్ చేయడం ప్రారంభమవుతుంది.

stream()
  .intemediateOperation1()
  .intemediateOperation2()
  ...
  .intemediateOperationN()
  .terminalOperation();
పైప్లైన్ యొక్క సాధారణ ప్రదర్శన

ఇంటర్మీడియట్ మరియు టెర్మినల్ పద్ధతుల పోలిక:

ఇంటర్మీడియట్ టెర్మినల్
రిటర్న్ రకం Stream కాదు aStream
పైప్‌లైన్‌ను రూపొందించడానికి ఒకే రకమైన బహుళ పద్ధతులతో కలపవచ్చు అవును లేదు
ఒకే పైప్‌లైన్‌లోని పద్ధతుల సంఖ్య ఏదైనా ఒకటి కంటే ఎక్కువ కాదు
తుది ఫలితాన్ని ఉత్పత్తి చేస్తుంది లేదు అవును
స్ట్రీమ్‌లో డేటాను ప్రాసెస్ చేయడం ప్రారంభిస్తుంది లేదు అవును

ఒక ఉదాహరణ చూద్దాం.

జంతు ప్రేమికుల కోసం మన దగ్గర ఒక క్లబ్ ఉందనుకుందాం. రేపు క్లబ్ జింజర్ క్యాట్ డేని జరుపుకుంటుంది. క్లబ్‌లో పెంపుడు జంతువుల యజమానులు ఉన్నారు, వీటిలో ప్రతి ఒక్కటి పెంపుడు జంతువుల జాబితాను కలిగి ఉంటుంది. అవి పిల్లులకే పరిమితం కాదు.

టాస్క్: రేపటి "ప్రొఫెషనల్ హాలిడే" కోసం వారి కోసం వ్యక్తిగతీకరించిన గ్రీటింగ్ కార్డ్‌లను రూపొందించడానికి మీరు అన్ని అల్లం పిల్లుల పేర్లను గుర్తించాలి. గ్రీటింగ్ కార్డ్‌లను పిల్లి వయస్సు ప్రకారం, పెద్దవారి నుండి చిన్నవారి వరకు క్రమబద్ధీకరించాలి.

ముందుగా, ఈ పనిని పరిష్కరించడంలో సహాయపడటానికి మేము కొన్ని తరగతులను అందిస్తాము:

public enum Color {
   WHITE,
   BLACK,
   DARK_GREY,
   LIGHT_GREY,
   FOXY,
   GREEN,
   YELLOW,
   BLUE,
   MAGENTA
}
public abstract class Animal {
   private String name;
   private Color color;
   private int age;

   public Animal(String name, Color color, int age) {
      this.name = name;
      this.color = color;
      this.age = age;
   }

   public String getName() {
      return name;
   }

   public Color getColor() {
      return color;
   }

   public int getAge() {
      return age;
   }
}
public class Cat extends Animal {
   public Cat(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Dog extends Animal {
   public Dog(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Parrot extends Animal {
   public Parrot(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Pig extends Animal {
   public Pig(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Snake extends Animal {
   public Snake(String name, Color color, int age) {
      super(name, color, age);
   }
}
public class Owner {
   private String name;
   private List<Animal> pets = new ArrayList<>();

   public Owner(String name) {
      this.name = name;
   }

   public List<Animal> getPets() {
      return pets;
   }
}

ఇప్పుడు తరగతిని చూద్దాం Selector, ఇక్కడ పేర్కొన్న ప్రమాణాల ప్రకారం ఎంపిక చేయబడుతుంది:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Selector {
   private static List<Owner> owners;

   private static void initData() {
      final Owner owner1 = new Owner("Ronan Turner");
      owner1.getPets().addAll(List.of(
            new Cat("Baron", Color.BLACK, 3),
            new Cat("Sultan", Color.DARK_GREY, 4),
            new Dog("Elsa", Color.WHITE, 0)
      ));

      final Owner owner2 = new Owner("Scarlet Murray");
      owner2.getPets().addAll(List.of(
            new Cat("Ginger", Color.FOXY, 7),
            new Cat("Oscar", Color.FOXY, 5),
            new Parrot("Admiral", Color.BLUE, 3)
      ));

      final Owner owner3 = new Owner("Felicity Mason");
      owner3.getPets().addAll(List.of(
            new Dog("Arnold", Color.FOXY, 3),
            new Pig("Vacuum Cleaner", Color.LIGHT_GREY, 8)
      ));

      final Owner owner4 = new Owner("Mitchell Stone");
      owner4.getPets().addAll(List.of(
            new Snake("Mr. Boa", Color.DARK_GREY, 2)
      ));

      final Owner owner5 = new Owner("Jonathan Snyder");
      owner5.getPets().addAll(List.of(
            new Cat("Fisher", Color.BLACK, 16),
            new Cat("Zorro", Color.FOXY, 14),
            new Cat("Margo", Color.WHITE, 3),
            new Cat("Brawler", Color.DARK_GREY, 1)
      ));

      owners = List.of(owner1, owner2, owner3, owner4, owner5);
   }
}

పద్ధతికి కోడ్‌ని జోడించడమే మిగిలి ఉంది main. ప్రస్తుతం, మేము మొదట initData()క్లబ్‌లోని పెంపుడు జంతువుల యజమానుల జాబితాను నింపే పద్ధతిని పిలుస్తాము. అప్పుడు మేము అల్లం పిల్లుల పేర్లను వారి వయస్సును బట్టి అవరోహణ క్రమంలో ఎంచుకుంటాము.

ముందుగా, ఈ పనిని పరిష్కరించడానికి స్ట్రీమ్‌లను ఉపయోగించని కోడ్‌ని చూద్దాం:

public static void main(String[] args) {
   initData();

   List<String> findNames = new ArrayList<>();
   List<Cat> findCats = new ArrayList<>();
   for (Owner owner : owners) {
      for (Animal pet : owner.getPets()) {
         if (Cat.class.equals(pet.getClass()) && Color.FOXY == pet.getColor()) {
            findCats.add((Cat) pet);
         }
      }
   }

   Collections.sort(findCats, new Comparator<Cat>() {
      public int compare(Cat o1, Cat o2) {
         return o2.getAge() - o1.getAge();
      }
   });

   for (Cat cat : findCats) {
      findNames.add(cat.getName());
   }

   findNames.forEach(System.out::println);
}

ఇప్పుడు ప్రత్యామ్నాయాన్ని చూద్దాం:

public static void main(String[] args) {
   initData();

   final List<String> findNames = owners.stream()
           .flatMap(owner -> owner.getPets().stream())
           .filter(pet -> Cat.class.equals(pet.getClass()))
           .filter(cat -> Color.FOXY == cat.getColor())
           .sorted((o1, o2) -> o2.getAge() - o1.getAge())
           .map(Animal::getName)
           .collect(Collectors.toList());

   findNames.forEach(System.out::println);
}

మీరు గమనిస్తే, కోడ్ చాలా కాంపాక్ట్. అదనంగా, స్ట్రీమ్ పైప్‌లైన్ యొక్క ప్రతి పంక్తి ఒకే చర్య, కాబట్టి వాటిని ఆంగ్లంలో వాక్యాల వలె చదవవచ్చు:

.flatMap(owner -> owner.getPets().stream())
Stream<Owner>a నుండి aకి తరలించండిStream<Pet>
.filter(pet -> Cat.class.equals(pet.getClass()))
డేటా స్ట్రీమ్‌లో పిల్లులను మాత్రమే ఉంచండి
.filter(cat -> Color.FOXY == cat.getColor())
డేటా స్ట్రీమ్‌లో అల్లం పిల్లులను మాత్రమే ఉంచండి
.sorted((o1, o2) -> o2.getAge() - o1.getAge())
అవరోహణ క్రమంలో వయస్సు వారీగా క్రమబద్ధీకరించండి
.map(Animal::getName)
పేర్లు పొందండి
.collect(Collectors.toList())
ఫలితాన్ని జాబితాలో ఉంచండి

3. స్ట్రీమ్‌లను సృష్టించడం

తరగతిలో Streamమేము ఇంకా కవర్ చేయని మూడు పద్ధతులు ఉన్నాయి. ఈ మూడు పద్ధతుల యొక్క ఉద్దేశ్యం కొత్త థ్రెడ్‌లను సృష్టించడం.

Stream<T>.of(T obj)పద్ధతి

పద్ధతి ఒకే మూలకాన్ని కలిగి ఉన్న స్ట్రీమ్‌నుof() సృష్టిస్తుంది . ఒక ఫంక్షన్ ఆబ్జెక్ట్‌ను ఆర్గ్యుమెంట్‌గా తీసుకున్నప్పుడు ఇది సాధారణంగా అవసరమవుతుంది , కానీ మీకు ఆబ్జెక్ట్ మాత్రమే ఉంటుంది. అప్పుడు మీరు ఒకే మూలకాన్ని కలిగి ఉన్న స్ట్రీమ్‌ను పొందడానికి పద్ధతిని సులభంగా మరియు సులభంగా ఉపయోగించవచ్చు .Stream<T>Tof()

ఉదాహరణ:

Stream<Integer> stream = Stream.of(1);

Stream<T> Stream.of(T obj1, T obj2, T obj3, ...)పద్ధతి

of()పద్ధతి ఆమోదించబడిన మూలకాలతో కూడిన స్ట్రీమ్‌ను సృష్టిస్తుంది . ఎన్ని మూలకాలు అయినా అనుమతించబడతాయి. ఉదాహరణ:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);

Stream<T> Stream.generate(Supplier<T> obj)పద్ధతి

generate()అభ్యర్థించబడినప్పుడు స్ట్రీమ్ యొక్క తదుపరి మూలకాన్ని రూపొందించడానికి ఉపయోగించే నియమాన్ని సెట్ చేయడానికి ఈ పద్ధతి మిమ్మల్ని అనుమతిస్తుంది. ఉదాహరణకు, మీరు ప్రతిసారీ యాదృచ్ఛిక సంఖ్యను ఇవ్వవచ్చు .

ఉదాహరణ:

Stream<Double> s = Stream.generate(Math::random);

Stream<T> Stream.concat(Stream<T> a, Stream<T> b)పద్ధతి

concat()పద్ధతి రెండు పాసైన స్ట్రీమ్‌లను ఒకటిగా కలుపుతుంది . డేటా చదివినప్పుడు, అది మొదటి స్ట్రీమ్ నుండి మొదట చదవబడుతుంది, ఆపై రెండవది నుండి చదవబడుతుంది . ఉదాహరణ:

Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream2 = Stream.of(10, 11, 12, 13, 14);
Stream<Integer> result = Stream.concat(stream1, stream2);

4. వడపోత డేటా

మరో 6 పద్ధతులు కొత్త డేటా స్ట్రీమ్‌లను సృష్టిస్తాయి, స్ట్రీమ్‌లను విభిన్న సంక్లిష్టతతో కూడిన గొలుసులు (లేదా పైప్‌లైన్‌లు)గా కలపడానికి మిమ్మల్ని అనుమతిస్తాయి.

Stream<T> filter(Predicate<T>)పద్ధతి

ఈ పద్ధతి ఆమోదించబడిన నియమం ప్రకారం సోర్స్ డేటా స్ట్రీమ్‌ను ఫిల్టర్ చేసే కొత్త డేటా స్ట్రీమ్‌ని అందిస్తుంది . పద్ధతిని ఒక వస్తువుపై తప్పనిసరిగా పిలవాలి, దాని రకం .Stream<T>

మీరు లాంబ్డా ఫంక్షన్‌ని ఉపయోగించి ఫిల్టరింగ్ నియమాన్ని పేర్కొనవచ్చు , ఇది కంపైలర్ ఆబ్జెక్ట్‌గా మారుస్తుంది Predicate<T>.

ఉదాహరణలు:

బంధించిన ప్రవాహాలు వివరణ
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> stream2 = stream.filter(x -> (x < 3));

మూడు కంటే తక్కువ సంఖ్యలను మాత్రమే ఉంచండి
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
Stream<Integer> stream2 = stream.filter(x -> (x > 0));

సున్నా కంటే ఎక్కువ సంఖ్యలను మాత్రమే ఉంచండి

Stream<T> sorted(Comparator<T>)పద్ధతి

ఈ పద్ధతి సోర్స్ స్ట్రీమ్‌లోని డేటాను క్రమబద్ధీకరించే కొత్త డేటా స్ట్రీమ్‌ను అందిస్తుంది . మీరు కంపారిటర్‌లో ఉత్తీర్ణులయ్యారు , ఇది డేటా స్ట్రీమ్‌లోని రెండు అంశాలను పోల్చడానికి నియమాలను సెట్ చేస్తుంది.

Stream<T> distinct()పద్ధతి

ఈ పద్ధతి సోర్స్ డేటా స్ట్రీమ్‌లోని ప్రత్యేక అంశాలను మాత్రమే కలిగి ఉన్న కొత్త డేటా స్ట్రీమ్‌ను అందిస్తుంది . మొత్తం డూప్లికేట్ డేటా విస్మరించబడింది. ఉదాహరణ:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.distinct(); // 1, 2, 3, 4, 5

Stream<T> peek(Consumer<T>)పద్ధతి

ఈ పద్ధతి కొత్త డేటా స్ట్రీమ్‌ని అందిస్తుంది , అయితే ఇందులోని డేటా సోర్స్ స్ట్రీమ్‌లో ఉన్నట్లే ఉంటుంది. కానీ స్ట్రీమ్ నుండి తదుపరి మూలకం అభ్యర్థించబడినప్పుడు, మీరు పద్ధతికి పాస్ చేసిన ఫంక్షన్peek() దానితో కాల్ చేయబడుతుంది.

మీరు ఫంక్షన్‌ను పద్ధతికి పంపితే System.out::println, peek()అన్ని వస్తువులు స్ట్రీమ్ గుండా వెళుతున్నప్పుడు అవి ప్రదర్శించబడతాయి.

Stream<T> limit(int n)పద్ధతి

ఈ పద్ధతి సోర్స్ డేటా స్ట్రీమ్‌లోని మొదటి ఎలిమెంట్‌లను మాత్రమే కలిగి ఉన్న కొత్త డేటా స్ట్రీమ్‌ను అందిస్తుంది . అన్ని ఇతర డేటా విస్మరించబడింది. ఉదాహరణ:n

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.limit(3); // 1, 2, 3

Stream<T> skip(int n)పద్ధతి

ఈ పద్ధతి కొత్త డేటా స్ట్రీమ్‌ని అందిస్తుంది, అది సోర్స్ స్ట్రీమ్‌లోని అన్ని అంశాలనే కలిగి ఉంటుంది , కానీ మొదటి మూలకాలను దాటవేస్తుంది (విస్మరిస్తుంది). nఉదాహరణ:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 2, 2, 2, 3, 4);
Stream<Integer> stream2 = stream.skip(3); // 4, 5, 2, 2, 2, 3, 4

వ్యాఖ్యలు
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION