एक विधेय द्वारा एक धारा को सीमित करें


187

क्या एक जावा 8 स्ट्रीम ऑपरेशन है जो एक (संभावित रूप से अनंत) को सीमित करता है Streamजब तक कि पहला तत्व एक विधेय से मेल नहीं खाता है?

जावा 9 में हम takeWhile10 से कम संख्या को प्रिंट करने के लिए नीचे दिए गए उदाहरण के रूप में उपयोग कर सकते हैं ।

IntStream
    .iterate(1, n -> n + 1)
    .takeWhile(n -> n < 10)
    .forEach(System.out::println);

जैसा कि जावा 8 में ऐसा कोई ऑपरेशन नहीं है, सामान्य तरीके से इसे लागू करने का सबसे अच्छा तरीका क्या है?


1
संभवतः उपयोगी जानकारी: stackoverflow.com/q/19803058/248082
nobeh


मैं सोच रहा हूँ कि कैसे आर्किटेक्ट कभी इस usecase में चले बिना "इसके लिए हम वास्तव में इसका क्या उपयोग कर सकते हैं" के माध्यम से प्राप्त कर सकते हैं । जावा 8 धाराओं के रूप में केवल मौजूदा डेटास्ट्रक्चर के लिए सहायक होते हैं: - /
एंडरसन


जावा 9 के साथ, लिखना आसान होगाIntStream.iterate(1, n->n<10, n->n+1).forEach(System.out::print);
मार्क डेज़बेल

जवाबों:


81

इस तरह के एक ऑपरेशन को जावा 8 के साथ संभव होना चाहिए Stream, लेकिन यह आवश्यक रूप से कुशलतापूर्वक नहीं किया जा सकता है - उदाहरण के लिए, आप आवश्यक रूप से इस तरह के ऑपरेशन को समानांतर नहीं कर सकते हैं, क्योंकि आपको तत्वों को क्रम में देखना होगा।

एपीआई इसे करने का एक आसान तरीका प्रदान नहीं करता है, लेकिन जो संभवत: सबसे सरल तरीका है Stream.iterator(), Iteratorउसे "टेक-ऑफ" कार्यान्वयन के लिए लपेटें , और फिर वापस एक Spliteratorऔर फिर एक पर जाएं Stream। या - शायद - लपेटो Spliterator, हालांकि यह वास्तव में इस कार्यान्वयन में अब विभाजित नहीं किया जा सकता है।

यहाँ एक takeWhileपर एक अप्रयुक्त कार्यान्वयन है Spliterator:

static <T> Spliterator<T> takeWhile(
    Spliterator<T> splitr, Predicate<? super T> predicate) {
  return new Spliterators.AbstractSpliterator<T>(splitr.estimateSize(), 0) {
    boolean stillGoing = true;
    @Override public boolean tryAdvance(Consumer<? super T> consumer) {
      if (stillGoing) {
        boolean hadNext = splitr.tryAdvance(elem -> {
          if (predicate.test(elem)) {
            consumer.accept(elem);
          } else {
            stillGoing = false;
          }
        });
        return hadNext && stillGoing;
      }
      return false;
    }
  };
}

static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<? super T> predicate) {
   return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false);
}

8
सिद्धांत रूप में, एक स्थिर विधेय के साथ टेकवाइल को समानांतर करना आसान है। समानांतर बैचों में स्थिति का मूल्यांकन करें (यदि कुछ अतिरिक्त बार निष्पादित किया गया है तो विधेय को फेंकना या साइड-इफेक्ट नहीं है)। यह समस्या पुनरावर्ती अपघटन (कांटा / जुड़ने की रूपरेखा) के संदर्भ में कर रही है जिसका उपयोग धाराएँ करती हैं। वास्तव में, यह ऐसी धाराएँ हैं जो बहुत ही अक्षम हैं।
अलेक्सांद्र डबिन्सकी

91
धाराएं बहुत बेहतर होती अगर वे स्व-प्रतिरक्षित समानता के साथ इतनी व्यस्त नहीं होतीं। समानांतरवाद की आवश्यकता केवल उन छोटे स्थानों में होती है जहाँ धाराओं का उपयोग किया जा सकता है। इसके अलावा, अगर ओरेकल को पेरोफ़ेंस के बारे में इतना ध्यान दिया जाता है, तो वे डेवलपर्स को परेशान किए बिना, जेवीएम जेआईटी को ऑटोवैक्टराइज़ कर सकते हैं, और बहुत बड़ा प्रदर्शन बढ़ा सकते हैं। अब यह सही है।
अलेक्सांद्र डबिन्सकी

आपको यह उत्तर अभी अद्यतन करना चाहिए कि जावा 9 जारी किया गया है।
रेडियोडैफ

4
नहीं, @Radiodef। सवाल विशेष रूप से जावा 8 समाधान के लिए पूछता है।
रेनाटो बैक

145

संचालन takeWhileऔर dropWhileJDK 9 में जोड़ा गया है। आपका उदाहरण कोड

IntStream
    .iterate(1, n -> n + 1)
    .takeWhile(n -> n < 10)
    .forEach(System.out::println);

ठीक उसी तरह का व्यवहार करेंगे जैसा कि आप उम्मीद करते हैं कि JDK 9 के तहत संकलित और चलाया जाएगा।

जेडीके 9 जारी किया गया है। यह यहाँ डाउनलोड के लिए उपलब्ध है: http://jdk.java.net/9/


3
JDK9 स्ट्रीम के लिए पूर्वावलोकन डॉक्स के लिए सीधा लिंक, takeWhile/ dropWhile: download.java.net/jdk9/docs/api/java/util/stream/Stream.html के साथ
माइल्स

1
क्या कोई कारण है कि उन्हें क्यों बुलाया जाता है takeWhileऔरdropWhile बजाय limitWhileऔर skipWhileमौजूदा एपीआई के साथ स्थिरता के लिए?
लुकास एडर

10
@ LukasEder takeWhileऔर dropWhileकाफी व्यापक हैं, जो स्काला, पायथन, ग्रूवी, रूबी, हास्केल, और क्लोजर में होती हैं। के साथ विषमता skipऔर limitदुर्भाग्यपूर्ण है। शायद skipऔर limitकहा जाना चाहिए dropऔरtake , लेकिन जब तक आप पहले से ही हास्केल से परिचित नहीं हैं, तब तक वे उतने सहज नहीं हैं।
स्टुअर्ट मार्क्स

3
@StuartMarks: मैं समझता हूं कि dropXXXऔर takeXXXअधिक लोकप्रिय शब्द हैं लेकिन मैं व्यक्तिगत रूप से अधिक SQL-esque limitXXXऔर के साथ रह सकता हूं skipXXX। मैं इस नई विषमता को शब्दों की व्यक्तिगत पसंद की तुलना में बहुत अधिक भ्रमित करता हूं ... :) (btw: स्काला भी है drop(int)और take(int))
लुकास ईडर

1
हाँ मुझे उत्पादन में सिर्फ Jdk 9 में अपग्रेड करने दें। कई देवता अभी भी Jdk8 पर हैं, इस तरह की सुविधा को शुरू से ही धाराओं के साथ शामिल किया जाना चाहिए था।
विल्मोल

50

allMatch()एक शॉर्ट-सर्कुलेटिंग फ़ंक्शन है, इसलिए आप इसका उपयोग प्रसंस्करण को रोकने के लिए कर सकते हैं। मुख्य नुकसान यह है कि आपको अपना परीक्षण दो बार करना है: एक बार यह देखने के लिए कि क्या आपको इसे संसाधित करना चाहिए, और फिर से यह देखने के लिए कि क्या जारी रखना है।

IntStream
    .iterate(1, n -> n + 1)
    .peek(n->{if (n<10) System.out.println(n);})
    .allMatch(n->n < 10);

5
यह पहली बार में मेरे लिए अनपेक्षित लग रहा था (विधि नाम दिया गया), लेकिन डॉक्स पुष्टि करते हैं कि Stream.allMatch()यह एक शॉर्ट-सर्कुलेटिंग ऑपरेशन है । तो यह भी एक अनंत धारा की तरह पूरा हो जाएगा IntStream.iterate()। बेशक, पूर्वव्यापी में, यह एक समझदार अनुकूलन है।
बैली पार्कर

3
यह साफ-सुथरा है, लेकिन मुझे नहीं लगता कि यह बहुत अच्छी तरह से संवाद करता है कि इसका आशय शरीर है peek। अगर मुझे अगले महीने इसका सामना करना पड़ा, तो मुझे आश्चर्य होगा कि प्रोग्रामर ने मुझे जाँचने से पहले क्यों allMatchऔर फिर उत्तर को अनदेखा कर दिया।
जोशुआ गोल्डबर्ग

10
इस समाधान का नुकसान यह है कि यह एक बूलियन देता है ताकि आप धारा के परिणामों को इकट्ठा नहीं कर सकें जैसा कि आप सामान्य रूप से करते हैं।
नेक्सस

35

अनुवर्ती @StuartMarks के उत्तर के रूप में । मेरी स्ट्रीमटेक्स लाइब्रेरी में takeWhileऑपरेशन है जो वर्तमान जेडीके -9 कार्यान्वयन के साथ संगत है। JDK-9 के तहत चलने पर यह सिर्फ JDK कार्यान्वयन ( MethodHandle.invokeExactजिसके माध्यम से वास्तव में तेज़ है) में प्रतिनिधि होगा । जेडीके -8 के तहत चलने पर, "पॉलीफिल" कार्यान्वयन का उपयोग किया जाएगा। तो मेरे पुस्तकालय का उपयोग करके समस्या को इस तरह हल किया जा सकता है:

IntStreamEx.iterate(1, n -> n + 1)
           .takeWhile(n -> n < 10)
           .forEach(System.out::println);

आपने इसे StreamEx वर्ग के लिए क्यों लागू नहीं किया है?
Someguy

@Someguy मैंने इसे लागू किया।
टैगिर वलेव


11

अपडेट: जावा 9 Streamअब एक टेकहाइल विधि के साथ आता है ।

हैक या अन्य समाधान के लिए कोई ज़रूरत नहीं है। बस उस का उपयोग करें!


मुझे यकीन है कि इस पर बहुत सुधार किया जा सकता है: (कोई व्यक्ति इसे धागा-सुरक्षित कर सकता है)

Stream<Integer> stream = Stream.iterate(0, n -> n + 1);

TakeWhile.stream(stream, n -> n < 10000)
         .forEach(n -> System.out.print((n == 0 ? "" + n : "," + n)));

यकीन के लिए एक हैक ... सुरुचिपूर्ण नहीं - लेकिन यह काम करता है ~: डी

class TakeWhile<T> implements Iterator<T> {

    private final Iterator<T> iterator;
    private final Predicate<T> predicate;
    private volatile T next;
    private volatile boolean keepGoing = true;

    public TakeWhile(Stream<T> s, Predicate<T> p) {
        this.iterator = s.iterator();
        this.predicate = p;
    }

    @Override
    public boolean hasNext() {
        if (!keepGoing) {
            return false;
        }
        if (next != null) {
            return true;
        }
        if (iterator.hasNext()) {
            next = iterator.next();
            keepGoing = predicate.test(next);
            if (!keepGoing) {
                next = null;
            }
        }
        return next != null;
    }

    @Override
    public T next() {
        if (next == null) {
            if (!hasNext()) {
                throw new NoSuchElementException("Sorry. Nothing for you.");
            }
        }
        T temp = next;
        next = null;
        return temp;
    }

    public static <T> Stream<T> stream(Stream<T> s, Predicate<T> p) {
        TakeWhile tw = new TakeWhile(s, p);
        Spliterator split = Spliterators.spliterator(tw, Integer.MAX_VALUE, Spliterator.ORDERED);
        return StreamSupport.stream(split, false);
    }

}

8

आप java8 + rxjava का उपयोग कर सकते हैं ।

import java.util.stream.IntStream;
import rx.Observable;


// Example 1)
IntStream intStream  = IntStream.iterate(1, n -> n + 1);
Observable.from(() -> intStream.iterator())
    .takeWhile(n ->
          {
                System.out.println(n);
                return n < 10;
          }
    ).subscribe() ;


// Example 2
IntStream intStream  = IntStream.iterate(1, n -> n + 1);
Observable.from(() -> intStream.iterator())
    .takeWhile(n -> n < 10)
    .forEach( n -> System.out.println(n));

6

वास्तव में जावा 8 में बिना किसी अतिरिक्त लाइब्रेरी के या जावा 9 का उपयोग करने के 2 तरीके हैं।

यदि आप कंसोल पर 2 से 20 तक संख्याएँ प्रिंट करना चाहते हैं, तो आप ऐसा कर सकते हैं:

IntStream.iterate(2, (i) -> i + 2).peek(System.out::println).allMatch(i -> i < 20);

या

IntStream.iterate(2, (i) -> i + 2).peek(System.out::println).anyMatch(i -> i >= 20);

आउटपुट दोनों मामलों में है:

2
4
6
8
10
12
14
16
18
20

कोई भी उल्लेख किया anyMatch अभी तक। यही इस पद का कारण है।


5

यह JDK 9 java.util.stream.Stream.takeWhile (Predicate) से कॉपी किया गया स्रोत है। JDK 8 के साथ काम करने के लिए थोड़ा अंतर।

static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<? super T> p) {
    class Taking extends Spliterators.AbstractSpliterator<T> implements Consumer<T> {
        private static final int CANCEL_CHECK_COUNT = 63;
        private final Spliterator<T> s;
        private int count;
        private T t;
        private final AtomicBoolean cancel = new AtomicBoolean();
        private boolean takeOrDrop = true;

        Taking(Spliterator<T> s) {
            super(s.estimateSize(), s.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED));
            this.s = s;
        }

        @Override
        public boolean tryAdvance(Consumer<? super T> action) {
            boolean test = true;
            if (takeOrDrop &&               // If can take
                    (count != 0 || !cancel.get()) && // and if not cancelled
                    s.tryAdvance(this) &&   // and if advanced one element
                    (test = p.test(t))) {   // and test on element passes
                action.accept(t);           // then accept element
                return true;
            } else {
                // Taking is finished
                takeOrDrop = false;
                // Cancel all further traversal and splitting operations
                // only if test of element failed (short-circuited)
                if (!test)
                    cancel.set(true);
                return false;
            }
        }

        @Override
        public Comparator<? super T> getComparator() {
            return s.getComparator();
        }

        @Override
        public void accept(T t) {
            count = (count + 1) & CANCEL_CHECK_COUNT;
            this.t = t;
        }

        @Override
        public Spliterator<T> trySplit() {
            return null;
        }
    }
    return StreamSupport.stream(new Taking(stream.spliterator()), stream.isParallel()).onClose(stream::close);
}

4

यहाँ एक संस्करण है जो कि ints पर किया जाता है - जैसा कि प्रश्न में पूछा गया है।

उपयोग:

StreamUtil.takeWhile(IntStream.iterate(1, n -> n + 1), n -> n < 10);

यहाँ StreamUtil के लिए कोड है:

import java.util.PrimitiveIterator;
import java.util.Spliterators;
import java.util.function.IntConsumer;
import java.util.function.IntPredicate;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;

public class StreamUtil
{
    public static IntStream takeWhile(IntStream stream, IntPredicate predicate)
    {
        return StreamSupport.intStream(new PredicateIntSpliterator(stream, predicate), false);
    }

    private static class PredicateIntSpliterator extends Spliterators.AbstractIntSpliterator
    {
        private final PrimitiveIterator.OfInt iterator;
        private final IntPredicate predicate;

        public PredicateIntSpliterator(IntStream stream, IntPredicate predicate)
        {
            super(Long.MAX_VALUE, IMMUTABLE);
            this.iterator = stream.iterator();
            this.predicate = predicate;
        }

        @Override
        public boolean tryAdvance(IntConsumer action)
        {
            if (iterator.hasNext()) {
                int value = iterator.nextInt();
                if (predicate.test(value)) {
                    action.accept(value);
                    return true;
                }
            }

            return false;
        }
    }
}

2

पुस्तकालय AbacusUtil पाने के लिए जाओ । यह आपके द्वारा वांछित एपीआई प्रदान करता है:

IntStream.iterate(1, n -> n + 1).takeWhile(n -> n < 10).forEach(System.out::println);

घोषणा lar मैं AbacusUtil का डेवलपर हूं।


0

आप शॉर्ट-सर्कुलेटिंग टर्मिनल ऑपरेशन को छोड़कर एक स्ट्रीम को रद्द नहीं कर सकते हैं, जो उनके मूल्य की परवाह किए बिना कुछ स्ट्रीम मानों को असंसाधित छोड़ देगा। लेकिन अगर आप किसी स्ट्रीम पर परिचालन से बचना चाहते हैं तो आप स्ट्रीम में एक ट्रांसफ़ॉर्म और फ़िल्टर जोड़ सकते हैं:

import java.util.Objects;

class ThingProcessor
{
    static Thing returnNullOnCondition(Thing thing)
    {    return( (*** is condition met ***)? null : thing);    }

    void processThings(Collection<Thing> thingsCollection)
    {
        thingsCollection.stream()
        *** regular stream processing ***
        .map(ThingProcessor::returnNullOnCondition)
        .filter(Objects::nonNull)
        *** continue stream processing ***
    }
} // class ThingProcessor

यह चीजों की धारा को नल में बदल देता है जब चीजें कुछ स्थिति से मिलती हैं, तो नल को फ़िल्टर करती हैं। यदि आप साइड इफ़ेक्ट में लिप्त होने के लिए तैयार हैं, तो आप किसी चीज़ के सामने आने के बाद हालत के मूल्य को सही कर सकते हैं, इसलिए बाद की सभी चीज़ों को उनके मूल्य की परवाह किए बिना फ़िल्टर किया जाता है। लेकिन भले ही आप उस स्ट्रीम को मानों को फ़िल्टर करके (यदि बिलकुल नहीं) प्रसंस्करण को बचा सकते हैं, जिसे आप प्रोसेस नहीं करना चाहते हैं।


यह लंगड़ा है कि कुछ गुमनाम रैटर ने मेरे जवाब को बिना कहे नीचे कर दिया। इसलिए न तो मैं और न ही कोई अन्य पाठक जानता है कि मेरे उत्तर में क्या गलत है। उनके औचित्य के अभाव में मैं उनकी आलोचना को अमान्य मानूंगा, और मेरे उत्तर को सही माना जाएगा।
मैथ्यू

आप जवाब देते हैं कि ओपी समस्या हल नहीं होती है, जो अनंत धाराओं से निपट रही है। यह चीजों को अनावश्यक रूप से जटिल करने के लिए भी लगता है क्योंकि आप फ़िल्टर में शर्त लिख सकते हैं () खुद को, बिना मानचित्र () की आवश्यकता के। प्रश्न में पहले से ही एक उदाहरण कोड है, बस उस कोड पर अपना उत्तर लागू करने का प्रयास करें और आप देखेंगे कि प्रोग्राम हमेशा के लिए लूप हो जाएगा।
सेनकोर्ट

0

यहां तक ​​कि मुझे एक समान आवश्यकता थी - वेब-सेवा का आह्वान, यदि यह विफल हो जाता है, तो इसे 3 बार पुन: प्रयास करें। यदि यह इन कई परीक्षणों के बाद भी विफल रहता है, तो एक ईमेल अधिसूचना भेजें। बहुत जाने के बाद, anyMatch()एक उद्धारकर्ता के रूप में आया। मेरा नमूना कोड निम्नानुसार है। निम्नलिखित उदाहरण में, यदि webServiceCall विधि पहले पुनरावृत्ति में ही सही हो जाती है, तो धारा आगे पुनरावृति नहीं करती है जैसा कि हमने कहा है anyMatch()। मुझे विश्वास है, यह वही है जो आप ढूंढ रहे हैं।

import java.util.stream.IntStream;

import io.netty.util.internal.ThreadLocalRandom;

class TrialStreamMatch {

public static void main(String[] args) {        
    if(!IntStream.range(1,3).anyMatch(integ -> webServiceCall(integ))){
         //Code for sending email notifications
    }
}

public static boolean webServiceCall(int i){
    //For time being, I have written a code for generating boolean randomly
    //This whole piece needs to be replaced by actual web-service client code
    boolean bool = ThreadLocalRandom.current().nextBoolean();
    System.out.println("Iteration index :: "+i+" bool :: "+bool);

    //Return success status -- true or false
    return bool;
}

0

यदि आपको पता है कि आपके द्वारा किए गए प्रत्यावर्तन की सही मात्रा क्या है, तो आप कर सकते हैं

IntStream
          .iterate(1, n -> n + 1)
          .limit(10)
          .forEach(System.out::println);

1
हालांकि यह लेखकों के सवाल का जवाब दे सकता है, लेकिन इसमें कुछ स्पष्ट शब्दों और प्रलेखन के लिंक का अभाव है। इसके आसपास कुछ वाक्यांशों के बिना रॉ कोड स्निपेट्स बहुत उपयोगी नहीं हैं। आपको यह भी पता चल सकता है कि एक अच्छा उत्तर बहुत उपयोगी कैसे लिखें । कृपया अपना उत्तर संपादित करें।
नरक

0
    IntStream.iterate(1, n -> n + 1)
    .peek(System.out::println) //it will be executed 9 times
    .filter(n->n>=9)
    .findAny();

चोटी के बजाय आप अंतिम ऑब्जेक्ट या संदेश को वापस करने के लिए mapToObj का उपयोग कर सकते हैं

    IntStream.iterate(1, n -> n + 1)
    .mapToObj(n->{   //it will be executed 9 times
            if(n<9)
                return "";
            return "Loop repeats " + n + " times";});
    .filter(message->!message.isEmpty())
    .findAny()
    .ifPresent(System.out::println);

-2

यदि आपको अलग समस्या है, तो अलग समाधान की आवश्यकता हो सकती है, लेकिन आपकी वर्तमान समस्या के लिए, मैं बस इसके साथ जाऊंगा:

IntStream
    .iterate(1, n -> n + 1)
    .limit(10)
    .forEach(System.out::println);

-2

विषय से थोड़ा हटकर हो सकता है लेकिन हमारे पास List<T>इसके बजाय यही हैStream<T>

पहले आपको एक takeउपयोग विधि की आवश्यकता है। इस तरीके में पहले nतत्व लगते हैं:

static <T> List<T> take(List<T> l, int n) {
    if (n <= 0) {
        return newArrayList();
    } else {
        int takeTo = Math.min(Math.max(n, 0), l.size());
        return l.subList(0, takeTo);
    }
}

यह बस की तरह काम करता है scala.List.take

    assertEquals(newArrayList(1, 2, 3), take(newArrayList(1, 2, 3, 4, 5), 3));
    assertEquals(newArrayList(1, 2, 3), take(newArrayList(1, 2, 3), 5));

    assertEquals(newArrayList(), take(newArrayList(1, 2, 3), -1));
    assertEquals(newArrayList(), take(newArrayList(1, 2, 3), 0));

अब इसके takeWhileआधार पर एक विधि लिखना काफी सरल होगाtake

static <T> List<T> takeWhile(List<T> l, Predicate<T> p) {
    return l.stream().
            filter(p.negate()).findFirst(). // find first element when p is false
            map(l::indexOf).        // find the index of that element
            map(i -> take(l, i)).   // take up to the index
            orElse(l);  // return full list if p is true for all elements
}

यह इस तरह काम करता है:

    assertEquals(newArrayList(1, 2, 3), takeWhile(newArrayList(1, 2, 3, 4, 3, 2, 1), i -> i < 4));

यह कार्यान्वयन आंशिक रूप से कुछ समय के लिए सूची को पुन: व्यवस्थित करता है, लेकिन यह O(n^2)परिचालन को नहीं जोड़ेगा । आशा है कि स्वीकार्य है।


-3

मेरे पास इसे लागू करके एक और त्वरित समाधान है (जो वास्तव में अशुद्ध है, लेकिन आपको यह विचार मिलता है):

public static void main(String[] args) {
    System.out.println(StreamUtil.iterate(1, o -> o + 1).terminateOn(15)
            .map(o -> o.toString()).collect(Collectors.joining(", ")));
}

static interface TerminatedStream<T> {
    Stream<T> terminateOn(T e);
}

static class StreamUtil {
    static <T> TerminatedStream<T> iterate(T seed, UnaryOperator<T> op) {
        return new TerminatedStream<T>() {
            public Stream<T> terminateOn(T e) {
                Builder<T> builder = Stream.<T> builder().add(seed);
                T current = seed;
                while (!current.equals(e)) {
                    current = op.apply(current);
                    builder.add(current);
                }
                return builder.build();
            }
        };
    }
}

2
आप पहले से पूरी स्ट्रीम का मूल्यांकन कर रहे हैं ! और अगर currentकभी नहीं .equals(e), तो आपको एक अंतहीन लूप मिलेगा। भले ही आप बाद में आवेदन करें, दोनों .limit(1)। वह far अशुद्ध ’ से भी बदतर है ।
चार्ली

-3

यहाँ सिर्फ जावा स्ट्रीम लाइब्रेरी का उपयोग करने का मेरा प्रयास है।

        IntStream.iterate(0, i -> i + 1)
        .filter(n -> {
                if (n < 10) {
                    System.out.println(n);
                    return false;
                } else {
                    return true;
                }
            })
        .findAny();

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.