একটি ধারা থেকে ধারাবাহিক জোড়া সংগ্রহ করুন


102

যেমন একটি স্ট্রিম দেওয়া হয়েছে { 0, 1, 2, 3, 4 } ,

আমি কীভাবে সবচেয়ে সুন্দরভাবে এটিকে প্রদত্ত আকারে রূপান্তর করতে পারি:

{ new Pair(0, 1), new Pair(1, 2), new Pair(2, 3), new Pair(3, 4) }

(ধরে নিচ্ছি, অবশ্যই আমি ক্লাস পেয়ার সংজ্ঞায়িত করেছি)?

সম্পাদনা: এটি কালি বা আদিম স্ট্রিম সম্পর্কে নয়। উত্তর যে কোনও ধরণের স্ট্রিমের জন্য সাধারণ হওয়া উচিত।


2
এফপি থেকে শব্দটি "পার্টিশন", তবে জাভাতে আমি কাঙ্ক্ষিত শব্দার্থবিজ্ঞানের কোনও পদ্ধতি খুঁজে পাচ্ছি না। এটি একটি ভবিষ্যদ্বাণী উপর বিভাজন আছে।
মার্কো টপলনিক

1
সাধারণত জেডিকে 8-এর স্প্লিট্রেটারটি ট্র্যাভারিং এবং পার্টিশনের উদ্দেশ্যে বিবেচিত হয়। আমি একটি উদাহরণও সামনে আনার চেষ্টা করব।
অলিম্পিউ পিওপি

list.stream().map(i -> new Pair(i, i+1));
এপুরিনিট

2
সমতুল্য অ স্ট্রীম করে প্রশ্ন জন্য, দেখুন stackoverflow.com/questions/17453022/...
Raedwald

যাইহোক, কিছু লোকেরা হয় Map.Entryজোড় শ্রেণি হিসাবে প্রয়োগ প্রয়োগ করে । (মঞ্জুর, কেউ কেউ হয়ত এটি একটি হ্যাক হিসাবে বিবেচনা করতে পারে তবে একটি বিল্ট-ইন ক্লাস ব্যবহার করা সুবিধাজনক
বেসিল বাউরক

উত্তর:


33

আমার স্ট্রিমএক্স লাইব্রেরি যা স্ট্রিম প্রসারিত করে pairMapসমস্ত স্ট্রিম প্রকারের জন্য একটি পদ্ধতি সরবরাহ করে । আদিম স্ট্রিমগুলির জন্য এটি স্ট্রিমের ধরণের পরিবর্তন করে না, তবে কিছু গণনা করতে ব্যবহার করা যেতে পারে। সর্বাধিক সাধারণ ব্যবহার হ'ল পার্থক্য গণনা:

int[] pairwiseDiffs = IntStreamEx.of(input).pairMap((a, b) -> (b-a)).toArray();

অবজেক্ট স্ট্রিমের জন্য আপনি অন্য যে কোনও অবজেক্টের প্রকার তৈরি করতে পারেন। আমার গ্রন্থাগারটি কোনও নতুন ব্যবহারকারী-দৃশ্যমান ডেটা স্ট্রাকচারের মতো সরবরাহ করে না Pair(এটি লাইব্রেরি ধারণার অংশ)। তবে আপনার যদি নিজস্ব Pairক্লাস থাকে এবং এটি ব্যবহার করতে চান তবে আপনি নিম্নলিখিতটি করতে পারেন:

Stream<Pair> pairs = IntStreamEx.of(input).boxed().pairMap(Pair::new);

অথবা আপনার যদি ইতিমধ্যে কিছু থাকে Stream:

Stream<Pair> pairs = StreamEx.of(stream).pairMap(Pair::new);

এই কার্যকারিতা কাস্টম স্প্লিটেটর ব্যবহার করে প্রয়োগ করা হয় । এটির ওভারহেড বেশ কম রয়েছে এবং এটি দুর্দান্তভাবে সমান্তরাল করতে পারে। অবশ্যই এটি অন্য যে কোনও স্ট্রিম উত্সের সাথে কাজ করে, কেবল এলোমেলো অ্যাক্সেসের তালিকা / অন্যান্য অনেকগুলি সমাধানের মতো অ্যারে নয়। অনেক পরীক্ষায় এটি সত্যই ভাল সম্পাদন করে। এখানে একটি জেএমএইচ বেঞ্চমার্ক যেখানে আমরা বিভিন্ন পদ্ধতির সাহায্যে বৃহত্তর মান পূর্বে সমস্ত ইনপুট মান খুঁজে পাই ( এই প্রশ্নটি দেখুন)।


ধন্যবাদ! আমি এই গ্রন্থাগারটি যত বেশি অধ্যয়ন করি ততই আমি এটির ভালবাসি। আমি শেষ পর্যন্ত স্ট্রিম ব্যবহার শুরু করতে পারি। ( StreamExপ্রয়োগসমূহ Iterable! হুর!)
আলেকজান্ডার ডাবিনস্কি

আপনার উত্তর 100% সম্পূর্ণ করতে, আপনাকে কিভাবে মোড়ানো দেখাতে পারে Streamএকটি মধ্যে StreamEx?
আলেকজান্ডার ডাবিনস্কি

3
@ অ্যালেক্সান্ডারডুবিনস্কি: কেবল ব্যবহার করুন StreamEx.of(stream)Collection, অ্যারে Readerইত্যাদি থেকে স্ট্রিম তৈরি করার জন্য অন্যান্য সুবিধাজনক স্থিতিশীল পদ্ধতি রয়েছে যা উত্তর সম্পাদনা করেছে।
তাগীর ভালিভ

@ তাগিরওয়ালিভকে pairMapধারাবাহিক স্ট্রিমে অর্ডার দেওয়া হয়েছে? আসলে, আমি চাই পেয়ারস অর্ডার করা () করতে চাই, তবে যেমন কোনও পদ্ধতি নেই তাই আমি কীভাবে এটি অনুকরণ করতে পারি? stream.ordered().forPairs()বা stream().pairMap().forEachOrdered()?
আসকার কল্যাভ

1
@ আশকারকল্যাভ, pairMapহ'ল হস্তক্ষেপহীন স্টেটলেস ম্যাপার ফাংশন সহ মধ্যবর্তী ক্রিয়াকলাপ , ক্রমটি সহজরূপে এটির জন্য নির্দিষ্ট করা হয়নি mapforPairsস্পেসিফিকেশন দ্বারা unordered হয়, কিন্তু unordered অপারেশন ডি ফ্যাক্টো অনুক্রমিক স্ট্রিম জন্য আদেশ হয়। আপনি যদি আপনার মূল সমস্যাটিকে আরও প্রসঙ্গ সরবরাহের জন্য পৃথক স্ট্যাকওভারফ্লো প্রশ্ন হিসাবে সূচনা করেন তবে এটি দুর্দান্ত।
তাগীর ভালিভ

74

জাভা 8 স্ট্রিমের লাইব্রেরিটি মূলত সমান্তরাল প্রক্রিয়াকরণের জন্য ছোট অংশগুলিতে বিভক্ত স্ট্রিমগুলির দিকে তত্পর হয়, সুতরাং রাষ্ট্রীয় পাইপলাইন ধাপগুলি বেশ সীমাবদ্ধ এবং বর্তমান স্ট্রিম উপাদানটির সূচক পাওয়া এবং সংলগ্ন স্ট্রিম উপাদানগুলির অ্যাক্সেসের মতো জিনিসগুলি সমর্থন করে না।

এই সমস্যাগুলি সমাধান করার একটি সাধারণ উপায়, কিছু সীমাবদ্ধতার সাথে অবশ্যই সূচিগুলি দ্বারা স্ট্রিমটি চালনা করা এবং অ্যারেলিস্টের মতো কিছু এলোমেলো-অ্যাক্সেস ডেটা স্ট্রাকচারে মানগুলি প্রক্রিয়া করার উপর নির্ভর করা যা থেকে উপাদানগুলি পুনরুদ্ধার করা যায়। মান যদি হয়arrayList অনুরোধ অনুসারে কেউ এই জাতীয় কিছু করে জোড় তৈরি করতে পারে:

    IntStream.range(1, arrayList.size())
             .mapToObj(i -> new Pair(arrayList.get(i-1), arrayList.get(i)))
             .forEach(System.out::println);

অবশ্যই সীমাবদ্ধতাটি হ'ল ইনপুটটি অসীম স্ট্রিম হতে পারে না। যদিও এই পাইপলাইনটি সমান্তরালে চালানো যেতে পারে।


5
"ইনপুটটি অসীম স্ট্রিম হতে পারে না।" আসলে, ইনপুট মোটেও একটি স্ট্রিম হতে পারে না। ইনপুট ( arrayList) আসলে একটি সংগ্রহ, যে কারণে আমি এটিকে উত্তর হিসাবে চিহ্নিত করি নি। (তবে আপনার সোনার ব্যাজটিতে অভিনন্দন!)
আলেকজান্ডার ডাবিনস্কি

16

এটি মার্জিত নয়, এটি হ্যাকিশ সমাধান, তবে অসীম স্ট্রিমগুলির জন্য কাজ করে

Stream<Pair> pairStream = Stream.iterate(0, (i) -> i + 1).map( // natural numbers
    new Function<Integer, Pair>() {
        Integer previous;

        @Override
        public Pair apply(Integer integer) {
            Pair pair = null;
            if (previous != null) pair = new Pair(previous, integer);
            previous = integer;
            return pair;
        }
    }).skip(1); // drop first null

এখন আপনি আপনার স্ট্রিমটি যে দৈর্ঘ্যটিতে সীমাবদ্ধ করতে পারেন

pairStream.limit(1_000_000).forEach(i -> System.out.println(i));

পিএস আমি আশা করি আরও ভাল সমাধান আছে, ক্লোজারের মতো কিছু something(partition 2 1 stream)


6
বেনাম ক্লাসগুলি ল্যাম্বডাসের কখনও কখনও দরকারী বিকল্প হিসাবে চিহ্নিত করার জন্য কুডোস।
আলেকসান্দ্র ডাবিনস্কি

2
@ এপর্ণিয়েট আমি ধরে নিয়েছি এটি সঠিকভাবে কাজ করবে না। parallelStreamডকের মতে : "সঠিক আচরণ সংরক্ষণের জন্য, এই আচরণগত পরামিতিগুলি হস্তক্ষেপহীন হতে হবে এবং বেশিরভাগ ক্ষেত্রে অবশ্যই রাষ্ট্রহীন হতে হবে"
মিসডাফ

14
এটি স্ট্রিম ফ্রেমওয়ার্কের ডিজাইনের সম্পূর্ণ বিরোধী এবং বেনামে ফাংশন স্টেটলেস না হওয়ায় সরাসরি মানচিত্রের এপিআইয়ের চুক্তি লঙ্ঘন করে । এটি একটি সমান্তরাল স্ট্রিম এবং আরও ডেটা দিয়ে চালানোর চেষ্টা করুন যাতে স্ট্রিম ফ্রেমওয়ার্কটি আরও কার্যকরী থ্রেড তৈরি করে এবং আপনি ফলাফলটি দেখতে পাবেন: অপ্রত্যাশিত এলোমেলো "ত্রুটি "গুলি পুনরুত্পাদন করা প্রায় অসম্ভব এবং আপনার কাছে পর্যাপ্ত ডেটা না থাকলে (উত্পাদনে?) সনাক্ত করা কঠিন difficult এটি বিপর্যয়কর হতে পারে।
মারিও রসি

4
@ আলেকসান্ডারডুবিনস্কি আপনি সীমাবদ্ধতা / স্কিপ সমান্তরাল হওয়ার পক্ষে ভুল করছেন; জেডিকে প্রদত্ত বাস্তবায়ন আসলে সমান্তরালে কাজ করে। অপারেশনটি এনকাউন্টার অর্ডের সাথে আবদ্ধ হওয়ার কারণে, সমান্তরালতা সর্বদা একটি কার্যকারিতা সুবিধা সরবরাহ করতে পারে না তবে উচ্চ-কিউ পরিস্থিতিতে এটি করতে পারে।
ব্রায়ান গয়েটজ

4
নিবন্ধন করুন এটা একটা র্যান্ডম উপাদান লাফালাফি পারে স্ট্রিমটি unordered (কোন সংজ্ঞায়িত করেছে এনকাউন্টার আদেশ, তাই কথাটি সেখানে হয় না "প্রথম" বা "n তম" উপাদান, শুধু উপাদানের।) কিন্তু স্ট্রিম আদেশ বা unordered হয় কিনা, এড়িয়ে যান সবসময় সক্ষম হয়েছে সমান্তরালে কাজ করতে। এই স্ট্রিমটি অর্ডার করা থাকলে উত্তোলনের জন্য মাত্র কম সমান্তরালতা রয়েছে, তবে এটি এখনও সমান্তরাল।
ব্রায়ান গোয়েজ

15

আমি একটি spliterator মোড়কের যা প্রতি লাগে প্রয়োগ করেছি nউপাদানের Tমূল spliterator থেকে উৎপন্ন List<T>:

public class ConsecutiveSpliterator<T> implements Spliterator<List<T>> {

    private final Spliterator<T> wrappedSpliterator;

    private final int n;

    private final Deque<T> deque;

    private final Consumer<T> dequeConsumer;

    public ConsecutiveSpliterator(Spliterator<T> wrappedSpliterator, int n) {
        this.wrappedSpliterator = wrappedSpliterator;
        this.n = n;
        this.deque = new ArrayDeque<>();
        this.dequeConsumer = deque::addLast;
    }

    @Override
    public boolean tryAdvance(Consumer<? super List<T>> action) {
        deque.pollFirst();
        fillDeque();
        if (deque.size() == n) {
            List<T> list = new ArrayList<>(deque);
            action.accept(list);
            return true;
        } else {
            return false;
        }
    }

    private void fillDeque() {
        while (deque.size() < n && wrappedSpliterator.tryAdvance(dequeConsumer))
            ;
    }

    @Override
    public Spliterator<List<T>> trySplit() {
        return null;
    }

    @Override
    public long estimateSize() {
        return wrappedSpliterator.estimateSize();
    }

    @Override
    public int characteristics() {
        return wrappedSpliterator.characteristics();
    }
}

ধারাবাহিক স্ট্রিম তৈরি করতে নিম্নলিখিত পদ্ধতিটি ব্যবহার করা যেতে পারে:

public <E> Stream<List<E>> consecutiveStream(Stream<E> stream, int n) {
    Spliterator<E> spliterator = stream.spliterator();
    Spliterator<List<E>> wrapper = new ConsecutiveSpliterator<>(spliterator, n);
    return StreamSupport.stream(wrapper, false);
}

নমুনা ব্যবহার:

consecutiveStream(Stream.of(0, 1, 2, 3, 4, 5), 2)
    .map(list -> new Pair(list.get(0), list.get(1)))
    .forEach(System.out::println);

এটি কি প্রতিটি উপাদানকে দুবার পুনরাবৃত্তি করে?
আলেকসান্দ্র ডাবিনস্কি

নাঃ। এটি List<E>উপাদান সহ একটি নতুন স্ট্রিম তৈরি করে। প্রতিটি তালিকায় nমূল ধারা থেকে পরপর উপাদান রয়েছে । এটি নিজেই দেখুন;)
টোমেক রেকাভেক

আপনি কি নিজের উত্তরটি পরিবর্তন করতে পারবেন যাতে প্রতিটি উপাদান (প্রথম এবং শেষ ব্যতীত) পুনরাবৃত্তি হয়?
আলেকসান্দ্র ডাবিনস্কি

4
+1 আমি মনে করি এটি ভাল কাজ এবং পার্টিশনের আকার ছাড়াও কোনও পদক্ষেপের আকারে সাধারণীকরণ করা উচিত। একটি (partition size step)ক্রিয়াকলাপের জন্য অনেক প্রয়োজন এবং এটি এটি পাওয়ার সেরা উপায় সম্পর্কে about
মার্কো টপলনিক

3
ArrayDequeঅগ্রাধিকার হিসাবে কর্মক্ষমতা জন্য ব্যবহার বিবেচনা করুন LinkedList
মার্কো টপলনিক

14

আপনি স্ট্রিম.আরডুস () পদ্ধতিটি দিয়ে এটি করতে পারেন (আমি এই কৌশলটি ব্যবহার করে অন্য কোনও উত্তর দেখিনি)।

public static <T> List<Pair<T, T>> consecutive(List<T> list) {
    List<Pair<T, T>> pairs = new LinkedList<>();
    list.stream().reduce((a, b) -> {
        pairs.add(new Pair<>(a, b));
        return b;
    });
    return pairs;
}

1
এটি (1,2) (3,4) এর পরিবর্তে (1,2) (2,3) ফেরত আসবে। এছাড়াও আমি নিশ্চিত না এটি কার্যকরভাবে প্রয়োগ করা হবে কিনা (অবশ্যই এর কোনও নিশ্চয়তা নেই)।
আলেকসান্দ্র ডাবিনস্কি

1
দয়া করে প্রশ্নটি পরীক্ষা করুন, এটিই উদ্দেশ্যমূলক আচরণ @ অ্যালেক্সান্দ্র ডাবিনস্কি
স্যামট্যাবস 33

3
আহ, হ্যাঁ, দুঃখিত। এবং ভাবতে, আমি এটি লিখেছি।
আলেকজান্ডার ডাবিনস্কি


6

স্লাইডিং অপারেটরটি ব্যবহার করে আপনি সাইক্লোপস-রিঅ্যাক্টে (এই লাইব্রেরিতে আমি অবদান রাখছি) এটি করতে পারেন।

  LazyFutureStream.of( 0, 1, 2, 3, 4 )
                  .sliding(2)
                  .map(Pair::new);

অথবা

   ReactiveSeq.of( 0, 1, 2, 3, 4 )
                  .sliding(2)
                  .map(Pair::new);

জোড় নির্মাণকারীকে ধরে নিলে 2 টি উপাদান সহ একটি সংগ্রহ গ্রহণ করা যাবে।

আপনি যদি 4 দ্বারা ভাগ করতে চান এবং 2 দ্বারা বর্ধনও এটি সমর্থিত।

     ReactiveSeq.rangeLong( 0L,Long.MAX_VALUE)
                .sliding(4,2)
                .forEach(System.out::println);

Java.util.stream.Stream উপর একটি সহচরী দৃশ্য এছাড়াও প্রদান করা হয় তৈরি করার জন্য Equivalant স্ট্যাটিক পদ্ধতি সাইক্লপ্স-স্ট্রীম করে StreamUtils বর্গ।

       StreamUtils.sliding(Stream.of(1,2,3,4),2)
                  .map(Pair::new);

দ্রষ্টব্য: - একক থ্রেডেড অপারেশনের জন্য ReactiveSeq আরও উপযুক্ত হবে। লাজিফিউচার স্ট্রিম রিঅ্যাকটিভসেক প্রসারিত করে তবে প্রাথমিকভাবে সমবর্তী / সমান্তরাল ব্যবহারের জন্য প্রস্তুত হয় (এটি ফিউচারের একটি স্ট্রিম)।

লাজিফিউচার স্ট্রিমটি রিঅ্যাকটিভসেককে প্রসারিত করে যা সিককে দুরন্ত জুওλ থেকে প্রসারিত করে (যা java.util.stream.Stream প্রসারিত), সুতরাং লুকাশের উপস্থাপনাগুলি স্ট্রিম প্রকারের সাথেও কাজ করবে। উইন্ডো / স্লাইডিং অপারেটরগুলির মধ্যে প্রাথমিক পার্থক্য সম্পর্কে আগ্রহী হ'ল সুস্পষ্ট আপেক্ষিক শক্তি / জটিলতা বাণিজ্য বন্ধ এবং অসীম স্ট্রিমগুলির সাথে ব্যবহারের উপযুক্ততা (স্লাইডিং প্রবাহটি গ্রাস করে না, তবে এটি প্রবাহিত হওয়ার সাথে সাথে বাফারগুলি)।


এইভাবে আপনি [(0,1) (2,3) ...] পান তবে প্রশ্নটি [(0,1) (1,2) ...] জিজ্ঞাসা করে। দয়া করে আমার উত্তরটি আরএক্সজাভা দিয়ে দেখুন ...
ফ্র্যাক করুন

1
আপনি ঠিক বলেছেন, আমার খারাপ, আমি প্রশ্নটি ভুল করে লিখছি - স্লাইডিং অপারেটরটি এখানে ব্যবহার করার জন্য সঠিক। আমি আমার উত্তর আপডেট করব - ধন্যবাদ!
জন ম্যাকক্লেইন

4

প্রোটন প্যাক গ্রন্থাগার বাতায়নযুক্ত functionnality প্রদান করে। একটি জোড় ক্লাস এবং একটি স্ট্রিম দেওয়া, আপনি এটি এর মতো করতে পারেন:

Stream<Integer> st = Stream.iterate(0 , x -> x + 1);
Stream<Pair<Integer, Integer>> pairs = StreamUtils.windowed(st, 2, 1)
                                                  .map(l -> new Pair<>(l.get(0), l.get(1)))
                                                  .moreStreamOps(...);

এখন pairsস্ট্রিমটিতে রয়েছে:

(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, ...) and so on

তবে মনে হচ্ছে আপনার stদু'বার তৈরি করা দরকার ! এই লাইব্রেরিটি কি কোনও একক ধারা ব্যবহার করে সমস্যার সমাধান করতে পারে?
আলেকসান্দ্র ডাবিনস্কি

@ আলেকসান্ডারডুবিনস্কি আমার মনে হয় না এটি বর্তমান স্প্লিটেটরগুলির সাথে এটি উপলব্ধ। আমি একটি সমস্যা জমা দিয়েছি github.com/poetix/protonpack/issues/9
অ্যালেক্সিস সি।

@AleksandrDubinsky- এ windowedকার্যকারিতা যুক্ত করা হয়েছে! সম্পাদনা দেখুন।
অ্যালেক্সিস সি

1
আপনি কেন আপনার পুরানো উত্তর মুছবেন না, যাতে অন্যান্য ব্যবহারকারীরা সমাধানটি দেখতে পারেন, ইতিহাস নয়।
আলেকজান্ডার ডাবিনস্কি

4

ধারাবাহিক জুটি সন্ধান করা

আপনি যদি কোনও তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করতে ইচ্ছুক থাকেন এবং সমান্তরতার প্রয়োজন না থাকেন তবে জওউ SQL- শৈলীর উইন্ডো ফাংশনগুলি নীচে সরবরাহ করে

System.out.println(
Seq.of(0, 1, 2, 3, 4)
   .window()
   .filter(w -> w.lead().isPresent())
   .map(w -> tuple(w.value(), w.lead().get())) // alternatively, use your new Pair() class
   .toList()
);

প্রদায়ক

[(0, 1), (1, 2), (2, 3), (3, 4)]

lead()ফাংশন উইন্ডো থেকে ট্র্যাভেরসাল অনুক্রমে পরবর্তী মান ব্যবহারের হার।

একের পর এক ট্রিপল / চতুর্থাংশ / এন-টিপলস সন্ধান করা

মন্তব্যে একটি প্রশ্ন আরও সাধারণ সমাধানের জন্য জিজ্ঞাসা করছিল, যেখানে জোড়া নয় এন-টিপলস (বা সম্ভবত তালিকা) সংগ্রহ করা উচিত। এখানে এইভাবে একটি বিকল্প পন্থা:

int n = 3;

System.out.println(
Seq.of(0, 1, 2, 3, 4)
   .window(0, n - 1)
   .filter(w -> w.count() == n)
   .map(w -> w.window().toList())
   .toList()
);

তালিকার একটি তালিকা উত্পাদন

[[0, 1, 2], [1, 2, 3], [2, 3, 4]]

ছাড়া filter(w -> w.count() == n) , ফলাফল হবে

[[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4], [4]]

দাবি অস্বীকার: আমি JOOλ এর পিছনে সংস্থার পক্ষে কাজ করি λ


মজাদার. আমার যদি 3 বা ততোধিক উপাদানগুলির গ্রুপ করতে হয় তবে কী হবে? ব্যবহার করবেন w.lead().lead()?
রাউল সান্তিলিকেস

1
@ রোলস্যানটেলিকস: tuple(w.value(), w.lead(1), w.lead(2))একটি বিকল্প হবে। আমি আমার উত্তরটি আরও সাধারণ সমাধান দিয়ে আপডেট করেছিlength = n
লুকাশ এডার

1
আমি সঠিকভাবে বুঝতে পেরেছি যে .window()অলস অপারেশন নয় যা পুরো ইনপুট স্ট্রিমটি কিছু মধ্যবর্তী সংকলনে সংগ্রহ করে, তারপরে এটি থেকে একটি নতুন স্ট্রিম তৈরি করে?
তাগীর ভালিভ

@ তাগিরওয়ালিভ: হ্যাঁ, এটিই এখনকার বাস্তবায়ন। উপরে যদি (কোন Comparatorপুনর্বিন্যাস জানালা ব্যবহার করা হয়), তারপর মত একটি অপ্টিমাইজেশান এই সম্ভব হবে, এবং সম্ভবত ভবিষ্যতে বাস্তবায়িত হবে।
লুকাশ এদার


2

আমরা আরএক্সজাভা ব্যবহার করতে পারি (খুব শক্তিশালী প্রতিক্রিয়াশীল এক্সটেনশন লাইব্রেরি)

IntStream intStream  = IntStream.iterate(1, n -> n + 1);

Observable<List<Integer>> pairObservable = Observable.from(intStream::iterator).buffer(2,1);

pairObservable.take(10).forEach(b -> {
            b.forEach(n -> System.out.println(n));
            System.out.println();
        });

বাফার অপারেটর একটি লক্ষণীয় যে পর্যবেক্ষণযোগ্য মধ্যে নিঃসরণ করে আইটেম নিঃসরণ করে ঐ আইটেম সংগ্রহ বাফার রূপান্তরিত ..


1
আমি Observable.zip(obs, obs.skip(1), pair->{...})এখনও অবধি ব্যবহার করেছি ! আমি জানতাম না Observable.bufferএকটি পদক্ষেপ সহ একটি সংস্করণ ছিল (এবং আমি zipপাইথন থেকে কৌশলটি অভ্যস্ত)। +1
শারবাণী

1

অপারেশনটি মূলত রাষ্ট্রীয়, তাই প্রবাহগুলি সমাধান করার জন্য আসলে কী বোঝায় না - জাভাদকের " স্টেটলেস বিহ্যাভিয়ার্স" বিভাগটি দেখুন :

পুরোপুরি স্ট্রিম পরিচালনার জন্য রাষ্ট্রীয় আচরণগত পরামিতিগুলি এড়ানো সেরা উপায়

এখানে একটি সমাধান হ'ল একটি বাহ্যিক কাউন্টারের মাধ্যমে আপনার স্ট্রিমের মধ্যে রাষ্ট্র পরিচয় করানো, যদিও এটি কেবলমাত্র অনুক্রমিক স্ট্রিমের সাথে কাজ করবে।

public static void main(String[] args) {
    Stream<String> strings = Stream.of("a", "b", "c", "c");
    AtomicReference<String> previous = new AtomicReference<>();
    List<Pair> collect = strings.map(n -> {
                            String p = previous.getAndSet(n);
                            return p == null ? null : new Pair(p, n);
                        })
                        .filter(p -> p != null)
                        .collect(toList());
    System.out.println(collect);
}


static class Pair<T> {
    private T left, right;
    Pair(T left, T right) { this.left = left; this.right = right; }
    @Override public String toString() { return "{" + left + "," + right + '}'; }
}

প্রশ্নটি কেবল একটি ক্রমাগত পূর্ণসংখ্যা সংগ্রহ করার জন্য নয়, একটি ইনপুট স্ট্রিমের ধারাবাহিক উপাদানগুলি সংগ্রহ করতে বলে। পরিভাষার একটি গুরুত্বপূর্ণ ব্যাখ্যা Stream:! = "ল্যাম্বডাস"।
আলেকসান্দ্র ডাবিনস্কি

আপনি একটি পারমাণবিক রেফারেন্স দ্বারা এটমিকআইন্টিজার প্রতিস্থাপন করতে পারেন। : বিকল্প আপনার নিজের সংগ্রাহক পাকানো বা এই ধরনের এই উদাহরণ হিসাবে বহিরাগত লাইব্রেরি ব্যবহার করা stackoverflow.com/a/30090528/829571
assylias

আমার সম্পাদনা দেখুন। এছাড়াও আমি নিশ্চিত না যে আমি ল্যাম্বডায় আপনার মন্তব্যটি বুঝতে পেরেছি! = স্ট্রিম। বেনামে বর্গ ব্যবহার করা অন্য উত্তরটি মূলত একই জিনিসটি ব্যতীত কেবল বাহ্যিক না হয়ে
রাজ্যকে বেনাম

1
ওই কাজগুলো. StreamExলাইব্রেরি একটি ভাল খুঁজে হয় এবং নিজেই একটি উত্তর হতে পারে। "স্ট্রিমগুলি! = ল্যাম্বডাস" সম্পর্কে আমার মন্তব্য আপনাকে উল্লেখ করে বোঝায় "" অপারেশনটি মূলত রাষ্ট্রীয় তাই লাম্বডাস কী বোঝাতে চাইছেন তা আসলেই নয় "" আমি মনে করি আপনি "স্ট্রিম" শব্দটি ব্যবহার করতে চেয়েছিলেন।
আলেকজান্ডার ডাবিনস্কি

ওহ আমি দেখছি - আমি তা স্পষ্ট করে দিয়েছি
Assylias

0

আপনার ক্ষেত্রে, আমি আমার কাস্টম ইন্টারফंक्शनটি লিখব যা শেষ প্রেরণাকে ট্র্যাক করে রাখে এবং এটি মূল প্রবাহের মানচিত্রের জন্য ব্যবহার করে।

import java.util.function.IntFunction;
import java.util.stream.IntStream;

public class PairFunction implements IntFunction<PairFunction.Pair> {

  public static class Pair {

    private final int first;
    private final int second;

    public Pair(int first, int second) {
      this.first = first;
      this.second = second;
    }

    @Override
    public String toString() {
      return "[" + first + "|" + second + "]";
    }
  }

  private int last;
  private boolean first = true;

  @Override
  public Pair apply(int value) {
    Pair pair = !first ? new Pair(last, value) : null;
    last = value;
    first = false;
    return pair;
  }

  public static void main(String[] args) {

    IntStream intStream = IntStream.of(0, 1, 2, 3, 4);
    final PairFunction pairFunction = new PairFunction();
    intStream.mapToObj(pairFunction)
        .filter(p -> p != null) // filter out the null
        .forEach(System.out::println); // display each Pair

  }

}

এটির সাথে সমস্যা হ'ল এটি জানালার বাইরে রাষ্ট্রহীনতা ছুড়ে দেয়।
রব

@ রব এবং তাতে সমস্যা কী?
আলেকসান্দ্র ডাবিনস্কি

ল্যাম্বডায়ার অন্যতম প্রধান বিষয় হ'ল পারস্পরিক পরিবর্তনযোগ্য অবস্থা না থাকা যাতে অভ্যন্তরীণ সংহতরা কাজের সমান্তরাল করতে পারে।
রব

@ রব: হ্যাঁ, আপনি ঠিক বলেছেন, তবে প্রদত্ত উদাহরণ স্ট্রিমটি যে কোনও উপায়ে সমান্তরালতাটিকে অস্বীকার করে (প্রথম এবং শেষের বিষয়গুলি বাদে) কিছু জোড়ের প্রথম এবং দ্বিতীয় আইটেম হিসাবে ব্যবহৃত হয়।
jpvee

@jpvee হ্যাঁ আমি বুঝতে পেরেছিলাম যে আপনি যা ভাবছিলেন আমি ভাবছি যদিও অন্য কোনও ম্যাপারের সাথে এটি করার কোনও উপায় নেই। সংক্ষেপে আপনার যা দরকার তা হ'ল লুপ ইনক্রিমেন্টারকে দ্বিগুণ করে ফ্যান্টারের সাথে 2 টি আর্গুমেন্ট আনতে হবে। এটা অবশ্যই সম্ভব।
রব

0

একটি সময়-সিরিজের সময় (এক্স-মান) এর ধারাবাহিক পার্থক্য গণনা করার জন্য, আমি streamএর collect(...)পদ্ধতিটি ব্যবহার করি :

final List< Long > intervals = timeSeries.data().stream()
                    .map( TimeSeries.Datum::x )
                    .collect( DifferenceCollector::new, DifferenceCollector::accept, DifferenceCollector::combine )
                    .intervals();

যেখানে ডিফারেন্সক্লাক্টর এইরকম কিছু:

public class DifferenceCollector implements LongConsumer
{
    private final List< Long > intervals = new ArrayList<>();
    private Long lastTime;

    @Override
    public void accept( final long time )
    {
        if( Objects.isNull( lastTime ) )
        {
            lastTime = time;
        }
        else
        {
            intervals.add( time - lastTime );
            lastTime = time;
        }
    }

    public void combine( final DifferenceCollector other )
    {
        intervals.addAll( other.intervals );
        lastTime = other.lastTime;
    }

    public List< Long > intervals()
    {
        return intervals;
    }
}

আপনার প্রয়োজন অনুসারে আপনি সম্ভবত এটি সংশোধন করতে পারেন।


0

পরিশেষে আমি বেশ কয়েকটি মূল্যবোধের সাথে ঝরঝরে মোকাবেলা করতে সক্ষম হতে স্ট্রিম.ড্রেসকে জালিয়াতির একটি উপায় আবিষ্কার করেছি; এমন অনেকগুলি ব্যবহারের কেস রয়েছে যার জন্য এই সুবিধার দরকার যা জেডিকে 8 তে প্রাকৃতিকভাবে প্রদর্শিত হয় না :

public static int ArithGeo(int[] arr) {
    //Geometric
    List<Integer> diffList = new ArrayList<>();
    List<Integer> divList = new ArrayList<>();
    Arrays.stream(arr).reduce((left, right) -> {
        diffList.add(right-left);
        divList.add(right/left);
        return right;
    });
    //Arithmetic
    if(diffList.stream().distinct().count() == 1) {
        return 1;
    }
    //Geometric
    if(divList.stream().distinct().count() == 1) {
        return 2;
    }
    return -1;
}

আমি যে কৌশলটি ব্যবহার করি তা হ'ল রিটার্ন; বিবৃতি।


1
আমি মনে করি না reduceএটি কাজ করার জন্য যথেষ্ট গ্যারান্টি দেয়।
আলেকসান্দ্র ডাবিনস্কি

পর্যাপ্ত গ্যারান্টি সম্পর্কে আরও জানতে আগ্রহী হবে । আপনি দয়া করে বিস্তারিত বলতে পারেন? পেয়ারাতে হয়তো বিকল্প আছে ... তবে আমি বাধা হয়েছি এবং এটি ব্যবহার করতে পারি না।
বিজার

-1

একটি মার্জিত সমাধান হ'ল জিপ ব্যবহার করা । কিছুটা এইরকম:

List<Integer> input = Arrays.asList(0, 1, 2, 3, 4);
Stream<Pair> pairStream = Streams.zip(input.stream(),
                                      input.stream().substream(1),
                                      (a, b) -> new Pair(a, b)
);

এটি বেশ সংক্ষিপ্ত এবং মার্জিত, তবে এটি একটি ইনপুট হিসাবে একটি তালিকা ব্যবহার করে। অসীম স্ট্রিম উত্সটি এভাবে প্রক্রিয়া করা যায় না।

আরেকটি (আরও অনেক ঝামেলার) সমস্যা হ'ল পুরো স্ট্রিম ক্লাসের সাথে জিপটি ইদানীং এপিআই থেকে সরানো হয়েছে। উপরের কোডটি কেবলমাত্র b95 বা আরও পুরানো প্রকাশের সাথে কাজ করে । তাই সর্বশেষ জেডিকে দিয়ে আমি বলব এখানে কোনও মার্জিত এফপি স্টাইল সমাধান নেই এবং এখনই আমরা কেবল আশা করতে পারি যে কোনওভাবে জিপটি এপিআইতে পুনঃপ্রবর্তিত হবে।


প্রকৃতপক্ষে, zipসরানো হয়েছে। আমি Streamsক্লাসে যা ছিল তার সব কিছুই মনে নেই , তবে কিছু জিনিস Streamইন্টারফেসে স্থির পদ্ধতি হিসাবে স্থানান্তরিত হয়েছে , এবং এখানে StreamSupportএবং Stream.Builderক্লাসগুলিও রয়েছে।
স্টুয়ার্ট

সেটা ঠিক. কনক্যাট বা পুনরাবৃত্তির মতো আরও কিছু পদ্ধতি সরিয়ে নেওয়া হয়েছে এবং স্ট্রিমের ডিফল্ট পদ্ধতিতে পরিণত হয়েছে। দু: খজনকভাবে জিপটি এপিআই থেকে সরিয়ে নেওয়া হয়েছে। আমি এই পছন্দটির পিছনে কারণগুলি বুঝতে পারি (যেমন: টিপলসের অভাব) তবে এটি একটি দুর্দান্ত বৈশিষ্ট্য ছিল।
গ্যাজেট

2
@ গ্যাজেট টিপলসের সাথে কী করতে হবে zip? প্যাড্যান্টিক কারণগুলি যা আবিষ্কার করা যেতে পারে তা হত্যার ন্যায্যতা দেয় না zip
আলেকসান্দ্র ডাবিনস্কি

@ আলেকসান্ডারডুবিনস্কি বেশিরভাগ ক্ষেত্রে জিপ আউটপুট হিসাবে জোড় / টিপলসের সংগ্রহ তৈরি করতে ব্যবহৃত হয়। তাদের যুক্তি ছিল যে তারা জিপ রাখলে লোকেরাও জেডকে-র অংশ হিসাবে টিপলসকে জিজ্ঞাসা করবে। যদিও আমি কোনও বিদ্যমান বৈশিষ্ট্যটি কখনও সরিয়ে ফেলতে পারতাম না।
গ্যাজেট

-1

এটি একটি আকর্ষণীয় সমস্যা। আমার সংকর প্রচেষ্টা কোন ভাল নীচে?

public static void main(String[] args) {
    List<Integer> list = Arrays.asList(1, 2, 3);
    Iterator<Integer> first = list.iterator();
    first.next();
    if (first.hasNext())
        list.stream()
        .skip(1)
        .map(v -> new Pair(first.next(), v))
        .forEach(System.out::println);
}

আমি বিশ্বাস করি যে এটি সমান্তরাল প্রক্রিয়াকরণের জন্য নিজেকে ndণ দেয় না এবং তাই অযোগ্য ঘোষণা করা যেতে পারে।


প্রশ্নটি সমান্তরাল প্রক্রিয়াকরণের জন্য জিজ্ঞাসা করে নি, তবে এটি ধরে নিয়েছে যে আমাদের কাছে কেবল একটি Stream, একটি নয় List। অবশ্যই, আমরা পাশাপাশি স্ট্রিম থেকে একটি পুনরাবৃত্তি করতে পারেন, তাই এটি একটি বৈধ সমাধান হতে পারে। যাইহোক, এটি একটি আসল পদ্ধতির।
আলেকসান্দ্র ডাবিনস্কি

-1

অন্যরা যেমন পর্যবেক্ষণ করেছেন, সমস্যা প্রকৃতির কারণে কিছুটা রাষ্ট্রীয়তা প্রয়োজন।

আমি একই ধরণের সমস্যার মুখোমুখি হয়েছি, যার মধ্যে আমি চেয়েছিলাম মূলত ওরাকল এসকিউএল ফাংশনটি কী ছিল। এটি বাস্তবায়নের জন্য আমার প্রচেষ্টা নীচে।

/**
 * Stream that pairs each element in the stream with the next subsequent element.
 * The final pair will have only the first item, the second will be null.
 */
<T> Spliterator<Pair<T>> lead(final Stream<T> stream)
{
    final Iterator<T> input = stream.sequential().iterator();

    final Iterable<Pair<T>> iterable = () ->
    {
        return new Iterator<Pair<T>>()
        {
            Optional<T> current = getOptionalNext(input);

            @Override
            public boolean hasNext()
            {
                return current.isPresent();
            }

            @Override
            public Pair<T> next()
            {
                Optional<T> next = getOptionalNext(input);
                final Pair<T> pair = next.isPresent()
                    ? new Pair(current.get(), next.get())
                    : new Pair(current.get(), null);
                current = next;

                return pair;
            }
        };
    };

    return iterable.spliterator();
}

private <T> Optional<T> getOptionalNext(final Iterator<T> iterator)
{
    return iterator.hasNext()
        ? Optional.of(iterator.next())
        : Optional.empty();
}

-1

প্রবাহের মধ্য দিয়ে প্রবাহিত উপাদানগুলি সংরক্ষণ করার জন্য একটি সীমাবদ্ধ সারি ব্যবহার করে আপনি এটি অর্জন করতে পারেন (যা আমি এখানে বিস্তারিতভাবে বর্ণনা করেছি এমন ধারণাকে ভিত্তি করে দেখছি: স্ট্রিমের পরবর্তী উপাদানটি পাওয়া সম্ভব? )

নীচে উদাহরণস্বরূপ প্রথমে বাউন্ডেড কিউ ক্লাসের উদাহরণ সংজ্ঞায়িত করা হয়েছে যা প্রবাহের মধ্য দিয়ে যাওয়া উপাদানগুলি সংরক্ষণ করবে (যদি আপনি লিংকডলিস্টটি প্রসারিত করার ধারণা পছন্দ করেন না, তবে বিকল্প এবং আরও জেনেরিক পদ্ধতির জন্য উপরে উল্লিখিত লিঙ্কটি দেখুন)। পরবর্তীতে আপনি কেবল দুটি পরবর্তী উপাদানকে জোড়ের উদাহরণের সাথে একত্রিত করুন:

public class TwoSubsequentElems {
  public static void main(String[] args) {
    List<Integer> input = new ArrayList<Integer>(asList(0, 1, 2, 3, 4));

    class BoundedQueue<T> extends LinkedList<T> {
      public BoundedQueue<T> save(T curElem) {
        if (size() == 2) { // we need to know only two subsequent elements
          pollLast(); // remove last to keep only requested number of elements
        }

        offerFirst(curElem);

        return this;
      }

      public T getPrevious() {
        return (size() < 2) ? null : getLast();
      }

      public T getCurrent() {
        return (size() == 0) ? null : getFirst();
      }
    }

    BoundedQueue<Integer> streamHistory = new BoundedQueue<Integer>();

    final List<Pair<Integer>> answer = input.stream()
      .map(i -> streamHistory.save(i))
      .filter(e -> e.getPrevious() != null)
      .map(e -> new Pair<Integer>(e.getPrevious(), e.getCurrent()))
      .collect(Collectors.toList());

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

-3

আমি @Aepurniet এর সাথে একমত হই তবে পরিবর্তে আপনাকে মানচিত্রটিওবজ ব্যবহার করতে হবে map

range(0, 100).mapToObj((i) -> new Pair(i, i+1)).forEach(System.out::println);

1
ঠিক। তবে এটি কেবল প্রবাহের (কোনও প্রকারের) উপাদানগুলির জোড়া নয়, কেবল পূর্ণসংখ্যার জোড় সংগ্রহ করে।
আলেকজান্ডার ডাবিনস্কি

-5

আপনার স্ট্রিমের for0 থেকে একটি লুপ চালানlength-1

for(int i = 0 ; i < stream.length-1 ; i++)
{
    Pair pair = new Pair(stream[i], stream[i+1]);
    // then add your pair to an array
}

3
এবং সমাধানের ল্যাম্বডা অংশটি কোথায়?
অলিম্পিউ পিওপি

স্রোত অসীম হওয়ার ক্ষেত্রে
এমনটি

@ অলিম্পিউ - আপনি একটি ল্যাম্বডা প্রয়োজন ছিল কোথায়? আমি এটি মিস করছি না তা নিশ্চিত করতে আমি দুবার প্রশ্নটি পড়েছি। আমি সম্পাদনার ইতিহাসও পরীক্ষা করেছিলাম। এবং প্রশ্ন এটি দিয়ে ট্যাগ করা হয় না।
jww
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.