আমি জানি জাভাতে সরাসরি কোনও সমতুল্য নেই, তবে সম্ভবত কোনও তৃতীয় পক্ষ?
এটা সত্যিই সুবিধাজনক। বর্তমানে আমি একটি পুনরুক্তি প্রয়োগ করতে চাই যা একটি গাছে সমস্ত নোড দেয়, যা ফলন সহ প্রায় পাঁচ লাইনের কোড।
আমি জানি জাভাতে সরাসরি কোনও সমতুল্য নেই, তবে সম্ভবত কোনও তৃতীয় পক্ষ?
এটা সত্যিই সুবিধাজনক। বর্তমানে আমি একটি পুনরুক্তি প্রয়োগ করতে চাই যা একটি গাছে সমস্ত নোড দেয়, যা ফলন সহ প্রায় পাঁচ লাইনের কোড।
উত্তর:
আমি যে দুটি অপশন সম্পর্কে জানি তা হ'ল 2007 এর অ্যাভিয়াড বেন ডভের ইনফোমেন্সার্স-সংগ্রহ গ্রন্থাগার এবং ২০০৮ সালের জিম ব্ল্যাকারের ইয়েলড অ্যাডাপ্টার লাইব্রেরি (যা অন্য উত্তরেও উল্লেখ করা হয়েছে)।
উভয়ই আপনাকে yield return
জাভাতে পছন্দ মতো কনস্ট্রাক্ট সহ কোড লেখার অনুমতি দেবে , তাই উভয়ই আপনার অনুরোধটি পূরণ করবে। দুজনের মধ্যে উল্লেখযোগ্য পার্থক্য হ'ল:
আভিয়াদের লাইব্রেরি বাইকোড ম্যানিপুলেশন ব্যবহার করছে যখন জিম এর মাল্টিথ্রেডিং ব্যবহার করে। আপনার প্রয়োজনের উপর নির্ভর করে প্রত্যেকের নিজস্ব সুবিধা এবং অসুবিধা থাকতে পারে। এটি সম্ভবত আভিয়াডের সমাধানটি দ্রুততর, যখন জিম এর বেশি বহনযোগ্য (উদাহরণস্বরূপ, আমি মনে করি না অ্যাভিডের লাইব্রেরি অ্যান্ড্রয়েডে কাজ করবে)।
আভিয়াদের লাইব্রেরিতে একটি ক্লিনার ইন্টারফেস রয়েছে - এখানে একটি উদাহরণ রয়েছে:
Iterable<Integer> it = new Yielder<Integer>() {
@Override protected void yieldNextCore() {
for (int i = 0; i < 10; i++) {
yieldReturn(i);
if (i == 5) yieldBreak();
}
}
};
যদিও জিম এর উপায়টি আরও জটিল, আপনার adept
একটি জেনেরিকের প্রয়োজন Collector
যা একটি collect(ResultHandler)
পদ্ধতি আছে ... উঘা। যাইহোক, আপনি জুমের তথ্য দ্বারা জিমের কোডের চারপাশে এই মোড়কের মতো কিছু ব্যবহার করতে পারেন যা এটি ব্যাপকভাবে সরল করে:
Iterable<Integer> it = new Generator<Integer>() {
@Override protected void run() {
for (int i = 0; i < 10; i++) {
yield(i);
if (i == 5) return;
}
}
};
আভিয়াদের সমাধান বিএসডি।
জিমের সমাধানটি পাবলিক ডোমেন এবং উপরে উল্লিখিত এর মোড়কটিও এটি।
AbstractIterator
।
yield(i)
জেডিকে ১৩ হিসাবে ভাঙ্গবে, যেহেতু yield
নতুন জাভা বিবৃতি / সংরক্ষিত কীওয়ার্ড হিসাবে যুক্ত করা হচ্ছে।
এই দুটি পদ্ধতিরই কিছুটা পরিষ্কার করা যায় এখন জাভাতে লাম্বডাস রয়েছে। আপনি যেমন কিছু করতে পারেন
public Yielderable<Integer> oneToFive() {
return yield -> {
for (int i = 1; i < 10; i++) {
if (i == 6) yield.breaking();
yield.returning(i);
}
};
}
Yielderable
? এটা ঠিক করা উচিত নয় Yieldable
? (ক্রিয়া শুধু 'ফলন' হচ্ছে না 'yielder' বা 'yielderate' বা যাই হোক না কেন)
yield -> { ... }
yield
নতুন জাভা স্টেটমেন্ট / সংরক্ষিত কীওয়ার্ড হিসাবে যুক্ত করা হওয়ায় , জেডিকে ১৩ হিসাবে ব্রেক হবে ।
আমি জানি এটি একটি খুব পুরানো প্রশ্ন, এবং উপরে বর্ণিত দুটি উপায় রয়েছে:
yield
যা স্পষ্টতই সম্পদের ব্যয় করে।তবে yield
জাভাতে জেনারেটর বাস্তবায়নের আরও একটি তৃতীয় এবং সম্ভবত সবচেয়ে প্রাকৃতিক উপায় রয়েছে যা সি # ২.০+ সংকলক yield return/break
প্রজন্মের জন্য যা করেন তার নিকটতম বাস্তবায়ন : লম্বোক-পিজি । এটি সম্পূর্ণরূপে একটি রাষ্ট্রের মেশিনের উপর ভিত্তি করে এবং javac
উত্স কোড এএসটি পরিচালনা করার জন্য কঠোর সহযোগিতা প্রয়োজন । দুর্ভাগ্যক্রমে, লম্বোক-পিজি সমর্থন বন্ধ হয়ে গেছে বলে মনে হচ্ছে (এক বা দুই বছরের বেশি সময় ধরে কোনও রিপোজিটরির ক্রিয়াকলাপ নেই) এবং মূল প্রকল্প লোমবকের দুর্ভাগ্যক্রমে yield
বৈশিষ্ট্যের অভাব রয়েছে (এটিতে ইক্যালিপস, ইন্টেলিজ আইডিইএ সমর্থন যেমন আরও ভাল আইডিই রয়েছে)।
স্ট্রিম.আইরেট (বীজ, বীজ অপারেটর) .মিলিট (এন) .পরিচা (ক্রিয়া) ফলন অপারেটরের মতো নয়, তবে আপনার নিজের জেনারেটরগুলি এভাবে লেখার পক্ষে কার্যকর হতে পারে:
import java.util.stream.Stream;
public class Test01 {
private static void myFoo(int someVar){
//do some work
System.out.println(someVar);
}
private static void myFoo2(){
//do some work
System.out.println("some work");
}
public static void main(String[] args) {
Stream.iterate(1, x -> x + 1).limit(15).forEach(Test01::myFoo); //var1
Stream.iterate(1, x -> x + 1).limit(10).forEach(item -> myFoo2()); //var2
}
}
যদি আপনি ইতিমধ্যে কোনও পর্যবেক্ষককে "ইয়েল্ডার" হিসাবে ব্যবহার করতে আপনার প্রকল্পে আরএক্সজাভা ব্যবহার করছেন তবে আমিও পরামর্শ দেব । আপনি যদি নিজের পর্যবেক্ষণযোগ্য করে থাকেন তবে এটি একই ধরণের ফ্যাশনে ব্যবহৃত হতে পারে।
public class Example extends Observable<String> {
public static void main(String[] args) {
new Example().blockingSubscribe(System.out::println); // "a", "b", "c", "d"
}
@Override
protected void subscribeActual(Observer<? super String> observer) {
observer.onNext("a"); // yield
observer.onNext("b"); // yield
observer.onNext("c"); // yield
observer.onNext("d"); // yield
observer.onComplete(); // finish
}
}
পর্যবেক্ষণযোগ্যগুলিকে পুনরাবৃত্তিতে রূপান্তর করা যায় যাতে আপনি এগুলি লুপের জন্য আরও বেশি traditionalতিহ্যবাহী ব্যবহার করতে পারেন। এছাড়াও আরএক্সজাভা আপনাকে সত্যিকারের শক্তিশালী সরঞ্জাম দেয়, তবে আপনার যদি কেবল সাধারণ কিছু প্রয়োজন হয় তবে সম্ভবত এটি একটি ওভারকিল হবে।
আমি এখানেই অন্য একটি (এমআইটি-লাইসেন্সধারী) সমাধান প্রকাশ করেছি , যা নির্মাতাকে পৃথক থ্রেডে প্রবর্তন করে এবং প্রযোজক এবং গ্রাহকের মধ্যে একটি সীমাবদ্ধ সারি সেট করে, উত্পাদক এবং ভোক্তার মধ্যে সমান্তরাল পাইপলাইনের অনুমতি দেয় (তাই) যেটি ভোক্তা পূর্ববর্তী আইটেমটি উত্পাদন করতে কাজ করতে পারে যখন প্রযোজক পরবর্তী আইটেম উত্পাদন করতে কাজ করছেন)।
আপনি এই বেনামে অভ্যন্তর শ্রেণীর ফর্মটি ব্যবহার করতে পারেন:
Iterable<T> iterable = new Producer<T>(queueSize) {
@Override
public void producer() {
produce(someT);
}
};
উদাহরণ স্বরূপ:
for (Integer item : new Producer<Integer>(/* queueSize = */ 5) {
@Override
public void producer() {
for (int i = 0; i < 20; i++) {
System.out.println("Producing " + i);
produce(i);
}
System.out.println("Producer exiting");
}
}) {
System.out.println(" Consuming " + item);
Thread.sleep(200);
}
অথবা আপনি বয়লারপ্লেটটি কাটাতে ল্যাম্বদা স্বরলিপি ব্যবহার করতে পারেন:
for (Integer item : new Producer<Integer>(/* queueSize = */ 5, producer -> {
for (int i = 0; i < 20; i++) {
System.out.println("Producing " + i);
producer.produce(i);
}
System.out.println("Producer exiting");
})) {
System.out.println(" Consuming " + item);
Thread.sleep(200);
}