এই কার্যকারিতাটি কি পরবর্তী জাভা সংস্করণে রাখা হবে?
কেউ জাভাের switch
বিবৃতিটি যেভাবে প্রযুক্তিগতভাবে কাজ করে, আমি কেন এটি করতে পারি না তা ব্যাখ্যা করতে পারে ?
"Don't hold your breath."
লোল, বাগসসন.বগড্যাটবেস
এই কার্যকারিতাটি কি পরবর্তী জাভা সংস্করণে রাখা হবে?
কেউ জাভাের switch
বিবৃতিটি যেভাবে প্রযুক্তিগতভাবে কাজ করে, আমি কেন এটি করতে পারি না তা ব্যাখ্যা করতে পারে ?
"Don't hold your breath."
লোল, বাগসসন.বগড্যাটবেস
উত্তর:
String
মামলাগুলির সাথে স্যুইচ স্টেটমেন্টগুলি জাভা এসই 7 এ প্রয়োগ করা হয়েছে , তাদের প্রথম অনুরোধের কমপক্ষে 16 বছর পরে। বিলম্বের জন্য একটি সুস্পষ্ট কারণ সরবরাহ করা হয়নি, তবে সম্ভবত এটির সম্পাদন কাজটি করতে হয়েছিল।
বৈশিষ্ট্যটি এখন javac
একটি "ডি-চিনিকরণ" প্রক্রিয়া সহ প্রয়োগ করা হয়েছে ; ঘোষণায় String
ধ্রুবক ব্যবহার করে একটি পরিষ্কার, উচ্চ-স্তরের সিনট্যাক্স case
সংকলন-সময়ে আরও জটিল কোডে একটি প্যাটার্ন অনুসরণ করে প্রসারিত করা হয়। ফলাফলযুক্ত কোড JVM নির্দেশাবলী ব্যবহার করে যা সর্বদা বিদ্যমান থাকে।
একটি switch
সঙ্গে String
মামলা সংকলন করার সময় দুই সুইচ অনুবাদ করা হয়। প্রথমটি প্রতিটি স্ট্রিংকে একটি অনন্য পূর্ণসংখ্যার মানচিত্র দেয়। মূল স্যুইচটিতে এটির অবস্থান। এটি প্রথমে লেবেলের হ্যাশ কোডটি স্যুইচ করার মাধ্যমে করা হয়। সম্পর্কিত কেসটি একটি if
বিবৃতি যা স্ট্রিং সমতা পরীক্ষা করে; যদি হ্যাশটিতে সংঘর্ষ হয়, তবে পরীক্ষাটি একটি ক্যাসকেডিং if-else-if
। দ্বিতীয় স্যুইচটি মূল উত্স কোডে মিরর করে, তবে কেস লেবেলগুলিকে তাদের সম্পর্কিত অবস্থানের সাথে প্রতিস্থাপন করে। এই দ্বি-পদক্ষেপ প্রক্রিয়াটি মূল স্যুইচটির প্রবাহ নিয়ন্ত্রণ সংরক্ষণ করা সহজ করে তোলে।
আরও প্রযুক্তিগত গভীরতার জন্য switch
আপনি জেভিএম স্পেসিফিকেশন উল্লেখ করতে পারেন, যেখানে স্যুইচ স্টেটমেন্টগুলির সংকলন বর্ণিত হয়েছে। সংক্ষেপে, দুটি পৃথক জেভিএম নির্দেশাবলী রয়েছে যা কেসগুলির দ্বারা ব্যবহৃত ধ্রুবকগুলির স্বল্পতার উপর নির্ভর করে একটি স্যুইচের জন্য ব্যবহার করা যেতে পারে। উভয়ই দক্ষতার সাথে কার্যকর করতে প্রতিটি ক্ষেত্রে পূর্ণসংখ্যার ধ্রুবক ব্যবহারের উপর নির্ভর করে।
যদি ধ্রুবকগুলি ঘন হয় তবে tableswitch
সেগুলি নির্দেশিকার পয়েন্টগুলির একটি সারণিতে নির্দেশিকা হিসাবে (সর্বনিম্ন মানটি বিয়োগের পরে) ব্যবহার করা হয় used নির্দেশিকা —
যদি কনস্ট্যান্টগুলি খুব কম হয় তবে সঠিক কেসের জন্য বাইনারি অনুসন্ধান করা হয় — lookupswitch
নির্দেশিকা।
ডি-sugaring সালে switch
উপর String
বস্তু, উভয় নির্দেশাবলী সম্ভাবনা বেশি ব্যবহৃত হবে। মামলার lookupswitch
মূল অবস্থানটি খুঁজতে হ্যাশ কোডগুলিতে প্রথম স্যুইচের জন্য উপযুক্ত। ফলস্বরূপ অর্ডিনাল একটি এর জন্য প্রাকৃতিক ফিট tableswitch
।
উভয় নির্দেশাবলীর জন্য প্রতিটি ক্ষেত্রে নির্ধারিত পূর্ণসংখ্যার ধ্রুবকগুলি সংকলনের সময়ে বাছাই করা প্রয়োজন। রানটাইমে, সাধারণভাবে O(1)
পারফরম্যান্সের tableswitch
তুলনায় O(log(n))
পারফরম্যান্স আরও ভালভাবে প্রদর্শিত হয় lookupswitch
, তবে টেবিলে স্থান – সময়ের ট্রেড অফকে ন্যায্য প্রমাণ করার জন্য পর্যাপ্ত ঘন কিনা তা নির্ধারণ করার জন্য কিছু বিশ্লেষণ প্রয়োজন। বিল ভেনারস একটি দুর্দান্ত নিবন্ধ লিখেছেন যা এটি আরও বিশদভাবে কভার করেছে, সাথে জাভা প্রবাহ নিয়ন্ত্রণের অন্যান্য নির্দেশাবলীর নীচে নজর রাখার পাশাপাশি look
জেডিকে to এর আগে, enum
প্রায় String
ভিত্তিক সুইচটি হতে পারে । এটি প্রতিটি ধরণের সংকলক দ্বারা উত্পাদিত স্থিতিশীলvalueOf
পদ্ধতি ব্যবহার করে enum
। উদাহরণ স্বরূপ:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}
Pill
ভিত্তিতে কিছু পদক্ষেপ গ্রহণের জন্য ব্যবহার করছেন str
তবে আমি তর্ক করব যদি অন্যথায় ভাল হয় কারণ এটি আপনাকে str
রেড রেডের বাইরে মানগুলি পরিচালনা করতে দেয় তবে ব্লু valueOf
এর নামের বিরুদ্ধে কোনও ম্যাচ খোঁজেন না বা ম্যানুয়ালি পরীক্ষা করার প্রয়োজন ছাড়াই প্রতিটি অঙ্কের ধরণ যা কেবল অপ্রয়োজনীয় ওভারহেড যুক্ত করে। আমার অভিজ্ঞতায় এটি পরে কেবল valueOf
স্ট্রিংয়ের মানের একটি টাইপসেফের উপস্থাপনার প্রয়োজন হলে একটি অঙ্কে রূপান্তরিত করার জন্য বোধগম্য হয়েছিল।
(hash >> x) & ((1<<y)-1)
যে স্ট্রিংটির জন্য স্বতন্ত্র মান উত্পাদ হবে hashCode
ভিন্ন, এবং (1<<y)
স্ট্রিং দুইবার সংখ্যা কম (অথবা এ তার চেয়ে কম বেশি নয়)।
আপনার কোডে আপনার যদি এমন কোনও জায়গা থাকে যেখানে আপনি স্ট্রিং স্যুইচ করতে পারেন, তবে স্ট্রিংটির সম্ভাব্য মানগুলির একটি গণনা হিসাবে স্ট্রিংটি রিফেক্টর করা ভাল which অবশ্যই, আপনি স্ট্রিংগুলির সম্ভাব্য মানগুলি সীমাবদ্ধ করে আপনার কাছে সেই গণনা রয়েছে যা পছন্দসই বা নাও পারে।
অবশ্যই আপনার গণনায় 'অন্যান্য' এবং একটি স্ট্রিং (স্ট্রিং) পদ্ধতিতে প্রবেশের প্রবেশ থাকতে পারে, তবে আপনি থাকতে পারেন
ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
case MILK: lap(); break;
case WATER: sip(); break;
case BEER: quaff(); break;
case OTHER:
default: dance(); break;
}
নীচে জিবি পোস্টের উপর ভিত্তি করে একটি সম্পূর্ণ উদাহরণ দেওয়া হয়েছে, কাস্টম পদ্ধতি ব্যবহার না করে জাভা এনাম ব্যবহার করা।
নোট করুন যে জাভা এসই 7 এ এবং তারপরে আপনি তার পরিবর্তে স্যুইচ স্টেটমেন্টের অভিব্যক্তিতে একটি স্ট্রিং অবজেক্ট ব্যবহার করতে পারেন।
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
String current = args[0];
Days currentDay = Days.valueOf(current.toUpperCase());
switch (currentDay) {
case MONDAY:
case TUESDAY:
case WEDNESDAY:
System.out.println("boring");
break;
case THURSDAY:
System.out.println("getting better");
case FRIDAY:
case SATURDAY:
case SUNDAY:
System.out.println("much better");
break;
}
}
public enum Days {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
}
পূর্ণসংখ্যার উপর ভিত্তি করে স্যুইচগুলি খুব কার্যকরী কোডে অনুকূলিত করা যায়। অন্যান্য ডেটা টাইপের উপর ভিত্তি করে স্যুইচগুলি কেবল যদি () স্টেটমেন্টের একটি সিরিজে সংকলন করা যায়।
এই কারণে সি এবং সি ++ কেবল পূর্ণসংখ্যার ধরণের স্যুইচগুলিকে অনুমতি দেয়, যেহেতু এটি অন্যান্য ধরণের সাথে অর্থহীন ছিল।
সি # এর ডিজাইনাররা সিদ্ধান্ত নিয়েছিলেন যে কোনও সুবিধা না থাকলেও শৈলীটি গুরুত্বপূর্ণ।
জাভার ডিজাইনাররা দৃশ্যত সি এর ডিজাইনারদের মতো ভেবেছিল thought
String
১.7 থেকে সরাসরি ব্যবহারের একটি উদাহরণও প্রদর্শিত হতে পারে:
public static void main(String[] args) {
switch (args[0]) {
case "Monday":
case "Tuesday":
case "Wednesday":
System.out.println("boring");
break;
case "Thursday":
System.out.println("getting better");
case "Friday":
case "Saturday":
case "Sunday":
System.out.println("much better");
break;
}
}
জেমস কারান সংক্ষেপে বলেছেন: "পূর্ণসংখ্যার উপর ভিত্তি করে স্যুইচগুলি খুব কার্যকরী কোডে অনুকূলিত করা যায় other যেহেতু এটি অন্যান্য ধরণের সাথে অর্থহীন ছিল "
আমার মতামত, এবং কেবলমাত্র এটি হ'ল আপনি অ-আদিমদের স্যুইচ করা শুরু করার সাথে সাথে আপনাকে "সমান" বনাম "==" সম্পর্কে ভাবনা শুরু করতে হবে। প্রথমত দুটি স্ট্রিংয়ের তুলনা করা মোটামুটি দীর্ঘ প্রক্রিয়া হতে পারে, যা উপরে বর্ণিত পারফরম্যান্স সমস্যাগুলিতে যোগ করে। দ্বিতীয়ত যদি স্ট্রিংগুলিতে স্যুইচিং হয় তবে স্ট্রিংগুলিকে অবহেলা করার ক্ষেত্রে স্যুইচ করা, স্থানীয় বিবেচনা করা / উপেক্ষা করার জন্য স্ট্রিংগুলিতে স্যুইচ করা, রেজেক্সের ভিত্তিতে স্ট্রিংগুলিতে স্যুইচ করার দাবি থাকবে .... আমি সেই সিদ্ধান্তকে অনুমোদিত করব যা তার জন্য অনেক সময় সাশ্রয় করেছে প্রোগ্রামারদের জন্য স্বল্প পরিমাণে ভাষা বিকাশকারী।
matched
এবং not matched
। (যদিও [নামযুক্ত] গোষ্ঠীগুলি ইত্যাদি ইত্যাদি বিবেচনায় নেই)
উপরের ভাল যুক্তিগুলির পাশাপাশি, আমি আজ প্রচুর লোককে যুক্ত করব switch
জাভা প্রক্রিয়াগত অতীতের অপ্রচলিত অবশিষ্ট হিসাবে (সি বারে ফিরে)
আমি এই মতামতটি সম্পূর্ণরূপে ভাগ করি switch
না , আমার ধারণা কমপক্ষে তার গতির কারণে কোনও কোনও ক্ষেত্রে এর উপযোগিতা থাকতে পারে এবং যাইহোক এটি কয়েকটি সিরিজের সংখ্যার চেয়ে বেশি ভালelse if
কয়েকটি কোডে দেখেছি এমন ...
তবে প্রকৃতপক্ষে, আপনার যেখানে স্যুইচ প্রয়োজন সেই ক্ষেত্রেটি দেখার মতো এবং এটি আরও ওও দ্বারা কোনও প্রতিস্থাপন করা যায় না কিনা তা দেখুন। উদাহরণস্বরূপ জাভা 1.5+ এ এনামস, সম্ভবত হ্যাশ টেবিল বা অন্য কোনও সংগ্রহ (লুয়া-তে যেমন জাভাস্ক্রিপ্ট নেই - যা আমাদের কাছে প্রথম শ্রেণীর নাগরিক হিসাবে আমাদের (বেনামে) ফাংশন নেই এমন কিছু সময় আমি আফসোস করি) বা এমনকি পলিমারফিজম।
আপনি যদি JDK7 বা ততোধিক ব্যবহার না করে থাকেন তবে আপনি hashCode()
এটি সিমুলেট করতে ব্যবহার করতে পারেন । কারণ String.hashCode()
সাধারণত বিভিন্ন স্ট্রিংয়ের জন্য বিভিন্ন মান প্রদান করে এবং সর্বদা সমান স্ট্রিংয়ের জন্য সমান মান প্রদান করে, এটি মোটামুটি নির্ভরযোগ্য (বিভিন্ন স্ট্রিং একটি মন্তব্যে উল্লিখিত লিলির মতো একই হ্যাশ কোড তৈরি করতে পারে, যেমন "FB"
এবং "Ea"
) ডকুমেন্টেশন দেখুন ।
সুতরাং, কোডটি এর মতো দেখাবে:
String s = "<Your String>";
switch(s.hashCode()) {
case "Hello".hashCode(): break;
case "Goodbye".hashCode(): break;
}
এইভাবে, আপনি প্রযুক্তিগতভাবে একটি চালু করতে চলেছেন int
।
বিকল্পভাবে, আপনি নিম্নলিখিত কোড ব্যবহার করতে পারেন:
public final class Switch<T> {
private final HashMap<T, Runnable> cases = new HashMap<T, Runnable>(0);
public void addCase(T object, Runnable action) {
this.cases.put(object, action);
}
public void SWITCH(T object) {
for (T t : this.cases.keySet()) {
if (object.equals(t)) { // This means that the class works with any object!
this.cases.get(t).run();
break;
}
}
}
}
case
আমি বলেছিলাম যে বিবৃতিগুলি সবসময় ধ্রুবক মান হতে পারে এবং String.hashCode()
এটি তেমন নয় (এমনকি বাস্তবে গণনা জেভিএমগুলির মধ্যে কখনও পরিবর্তিত হয়নি)।
case
সংকলনের সময় বিবৃতি মানগুলি নির্ধারণযোগ্য হবে না তাই এটি সূক্ষ্মভাবে কাজ করে।
কয়েক বছর ধরে আমরা এর জন্য একটি (এন ওপেন সোর্স) প্রিপ্রোসেসর ব্যবহার করে আসছি।
//#switch(target)
case "foo": code;
//#end
প্রাক প্রসেসড ফাইলগুলির নাম দেওয়া হয় Foo.jpp এবং পিঁপড়া স্ক্রিপ্টের সাহায্যে Foo.java তে প্রক্রিয়াজাত হয়।
সুবিধা হ'ল এটি জাভাতে প্রক্রিয়া করা হয় যা 1.0 এ চলে (যদিও সাধারণত আমরা কেবল 1.4 তে সমর্থন করি)। এছাড়াও এটি করা এনামস বা অন্যান্য কাজের সাথে তুলনা করার তুলনায় এটি (প্রচুর স্ট্রিং সুইচ) করা সহজ ছিল - কোডটি পড়া, রক্ষণাবেক্ষণ এবং বোঝার পক্ষে অনেক সহজ ছিল। আইআইআরসি (এই মুহুর্তে পরিসংখ্যান বা প্রযুক্তিগত যুক্তি সরবরাহ করতে পারে না) এটি প্রাকৃতিক জাভা সমতার চেয়েও দ্রুত ছিল।
অসুবিধাগুলি হ'ল আপনি জাভা সম্পাদনা করছেন না তাই এটি আরও কিছুটা ওয়ার্কফ্লো (সম্পাদনা, প্রক্রিয়া, সংকলন / পরীক্ষা) প্লাস কোনও আইডিই জাভাতে আবার লিঙ্ক করবে যা সামান্য বিভ্রান্ত হয় (যদি স্যুইচটি / অন্য যুক্তিযুক্ত পদক্ষেপের একটি সিরিজ হয়ে যায়) এবং স্যুইচ কেস অর্ডার বজায় রাখা হয় না।
আমি এটি 1.7+ এর জন্য প্রস্তাব দেব না তবে আপনি যদি জাভা প্রোগ্রাম করতে চান যা পূর্ববর্তী জেভিএমকে লক্ষ্য করে তোলে (যেহেতু জো পাবলিক খুব কমই সর্বশেষতম ইনস্টলড আছে)।
আপনি এটি এসভিএন থেকে পেতে পারেন বা কোডটি অনলাইনে ব্রাউজ করতে পারেন । এটি ঠিক যেমনটি তৈরি করতে আপনার ইবিল্ড লাগবে।
অন্যান্য উত্তরগুলি জানিয়েছে যে এটি জাভা in-এ যুক্ত করা হয়েছিল এবং পূর্ববর্তী সংস্করণগুলির জন্য কার্যপ্রণালী দেওয়া হয়েছিল। এই উত্তরটি "কেন" উত্তর দেওয়ার চেষ্টা করে
জাভা সি ++ এর অতিরিক্ত জটিলতার একটি প্রতিক্রিয়া ছিল। এটি একটি সাধারণ পরিষ্কার ভাষা হিসাবে তৈরি করা হয়েছিল।
স্ট্রিং ভাষায় কিছুটা বিশেষ কেস হ্যান্ডলিং পেয়েছিল তবে এটি আমার কাছে স্পষ্ট মনে হয় যে ডিজাইনাররা বিশেষ কেসিং এবং সিনট্যাকটিক চিনির পরিমাণ সর্বনিম্ন রাখার চেষ্টা করছেন were
স্ট্রিংগুলি স্যুইচিং হুডের নীচে মোটামুটি জটিল কারণ স্ট্রিংগুলি আদিম ধরনের নয়। জাভা ডিজাইনের সময় এটি কোনও সাধারণ বৈশিষ্ট্য ছিল না এবং মিনিমালিস্ট ডিজাইনের সাথে সত্যই ফিট করে না। বিশেষত যেহেতু তারা স্ট্রিংয়ের জন্য বিশেষ কেস == না নেওয়ার সিদ্ধান্ত নিয়েছে, তাই কেস যেখানে কাজ করতে হবে তার ক্ষেত্রে এটি অদ্ভুত হবে (এবং এটি হল) যেখানে == না।
1.0 এবং 1.4 এর মধ্যে ভাষা নিজে থেকেই বেশ একইরকম থাকে। জাভাতে বেশিরভাগ বর্ধিতাংশ ছিল লাইব্রেরির দিকে।
সমস্ত জাভা 5 দিয়ে পরিবর্তিত হয়েছে, ভাষাটি যথেষ্ট পরিমাণে প্রসারিত হয়েছিল। আরও এক্সটেনশনগুলি 7 এবং 8 সংস্করণে অনুসরণ করেছে আমি আশা করি যে মনোভাবের এই পরিবর্তনটি সি # এর উত্থানের দ্বারা পরিচালিত হয়েছিল
জেপি 354: জেডিকে -13 এবং জেপি 361 -এ স্যুইচ এক্সপ্রেশন (পূর্বরূপ) : জেডিকে -১ 14 এ স্যুইচ এক্সপ্রেশন (স্ট্যান্ডার্ড) সুইচ স্টেটমেন্টটি প্রসারিত করবেযাতে এটি একটি এক্সপ্রেশন হিসাবে ব্যবহার করা যায় ।
এখন তুমি পার:
case L ->
):
"কেস এল ->" স্যুইচ লেবেলের ডানদিকে কোডটি এক্সপ্রেশন, ব্লক বা (সুবিধার জন্য) একটি থ্রো স্টেটমেন্ট হিসাবে সীমাবদ্ধ।
একটি স্যুইচ এক্সপ্রেশন থেকে একটি মান উপার্জন করতে,
break
মান বিবৃতি সহ একটিyield
স্টেটমেন্টের পক্ষে বাদ দেওয়া হয় ।
সুতরাং উত্তরগুলি থেকে ডেমো ( 1 , 2 ) এর মত দেখতে পারা যায়:
public static void main(String[] args) {
switch (args[0]) {
case "Monday", "Tuesday", "Wednesday" -> System.out.println("boring");
case "Thursday" -> System.out.println("getting better");
case "Friday", "Saturday", "Sunday" -> System.out.println("much better");
}
খুব সুন্দর নয়, তবে জাভা 6 এবং বেলোয়ের জন্য এখানে আরেকটি উপায় রয়েছে:
String runFct =
queryType.equals("eq") ? "method1":
queryType.equals("L_L")? "method2":
queryType.equals("L_R")? "method3":
queryType.equals("L_LR")? "method4":
"method5";
Method m = this.getClass().getMethod(runFct);
m.invoke(this);
এটি গ্রোভির একটি হাওয়া; আমি গ্রোভি জার এম্বেড করে groovy
এই সমস্ত কাজ করার জন্য একটি ইউটিলিটি ক্লাস তৈরি করেছি এবং যা যা জাভাতে করতে আমি ক্লান্তিহীন বলে মনে করি (যেহেতু আমি এন্টারপ্রাইজে জাভা 6 ব্যবহার করে আটকা পড়েছি।)
it.'p'.each{
switch (it.@name.text()){
case "choclate":
myholder.myval=(it.text());
break;
}}...
আপনি যখন ইন্টেলিজ ব্যবহার করেন তখন এগুলিও দেখুন:
ফাইল -> প্রকল্পের কাঠামো -> প্রকল্প
ফাইল -> প্রকল্পের কাঠামো -> মডিউল
যখন আপনার একাধিক মডিউল রয়েছে তা নিশ্চিত করে নিন যে আপনি মডিউল ট্যাবে সঠিক ভাষার স্তর নির্ধারণ করেছেন।
public class StringSwitchCase {
public static void main(String args[]) {
visitIsland("Santorini");
visitIsland("Crete");
visitIsland("Paros");
}
public static void visitIsland(String island) {
switch(island) {
case "Corfu":
System.out.println("User wants to visit Corfu");
break;
case "Crete":
System.out.println("User wants to visit Crete");
break;
case "Santorini":
System.out.println("User wants to visit Santorini");
break;
case "Mykonos":
System.out.println("User wants to visit Mykonos");
break;
default:
System.out.println("Unknown Island");
break;
}
}
}