জাভাতে শর্টকাট "বা-নিয়োগ" (| =) অপারেটর


89

জাভাতে আমার তুলনা করার একটি দীর্ঘ সেট রয়েছে এবং আমি জানতে চাই যে তাদের মধ্যে আরও এক বা একাধিকটি সত্য হিসাবে আসে কিনা। তুলনাগুলির স্ট্রিংটি পড়া দীর্ঘ এবং কঠিন ছিল, তাই আমি এটি পঠনযোগ্যতার জন্য ভেঙে ফেলেছিলাম এবং স্বয়ংক্রিয়ভাবে |=পরিবর্তে একটি শর্টকাট অপারেটর ব্যবহার করতে গিয়েছিলাম negativeValue = negativeValue || boolean

boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);

আমি negativeValueকোনও ডিফল্ট << কিছু> মানটি নেতিবাচক হলে সত্য হওয়ার প্রত্যাশা করি । এটা কি বৈধ? এটা কি আমি প্রত্যাশা করব? আমি এটি সূর্যের সাইটে বা স্ট্যাকওভারফ্লোতে উল্লিখিত দেখতে পেলাম না, তবে গ্রহগ্রহের সাথে এটির কোনও সমস্যা আছে এবং কোডটি সংকলন ও রান চলছে বলে মনে হচ্ছে না।


একইভাবে, যদি আমি বেশ কয়েকটি যৌক্তিক ছেদটি সম্পাদন করতে চাই, তবে আমি কি তার &=পরিবর্তে ব্যবহার করতে পারি &&?


13
আপনি এটি চেষ্টা করবেন না কেন?
রোমান

এটি সাধারণ বুলিয়ান যুক্তি, কেবল জাভা নয়। যাতে আপনি এটি অন্য জায়গায় সন্ধান করতে পারেন। এবং কেন আপনি শুধু এটি চেষ্টা করে না?
ডায়কাম

16
@ ডাইকাম: না, এখানে নির্দিষ্ট আচরণ রয়েছে। জাভা | = সংক্ষিপ্ত সার্কিট তৈরি করতে বেছে নিতে পারে , যেমন এলএইচএস ইতিমধ্যে সত্য হলে এটি আরএইচএসের মূল্যায়ন করবে না - তবে তা হয় না।
জন স্কিটি

4
@ জোন স্কিইট: অস্তিত্বহীন ||=অপারেটরের জন্য শর্ট সার্কিট করা উপযুক্ত হবে তবে |=এটি বিটওয়াইস বা অপারেটরের সংমিশ্রণ ফর্ম।
ডেভিড থর্নলি

4
@ জোন স্কিট: অবশ্যই, তবে |=শর্ট সার্কিট করা অন্য যৌগিক কার্যনির্বাহী অপারেটরগুলির সাথে অসঙ্গত হবে, যেহেতু দ্বিগুণ মূল্যায়ন করার বিষয়ে সাধারণ সতর্কতা (যদি এটি বিবেচনা করে) তবে এটি a |= b;একই রকম হবে না । আমার কাছে দেখে মনে হচ্ছে বড় ভাষার আচরণের সিদ্ধান্তটি ছিল না , সুতরাং আমি আপনার বক্তব্যটি মিস করছি। a = a | b;a||=
ডেভিড থর্নলি

উত্তর:


205

|=একটি যৌগ নিয়োগ অপারেটর (হয় JLS 15.26.2 বুলিয়ান লজিক্যাল অপারেটর জন্য) |( JLS 15.22.2 ); শর্তসাপেক্ষে বা ||( JLS 15.24 ) এর সাথে বিভ্রান্ত হওয়ার দরকার নেই । এছাড়াও রয়েছে &=এবং ^=লজিক্যাল বুলিয়ান এর যৌগ নিয়োগ সংস্করণে সংশ্লিষ্ট &এবং ^যথাক্রমে।

অন্য কথায়, কারণ boolean b1, b2এই দুটি সমান:

 b1 |= b2;
 b1 = b1 | b2;

লজিকাল অপারেটরগুলির মধ্যে পার্থক্য ( &এবং |) তাদের শর্তসাপেক্ষ প্রতিযোগীদের ( &&এবং ||) তুলনা করে যে প্রাক্তনগুলি "শর্টকার্টকিট" করে না; পরেরটি না। এটাই:

  • &এবং | সর্বদা উভয় অপারেশনকে মূল্যায়ন করুন
  • &&এবং শর্তসাপেক্ষে|| ডান অপরেন্ড মূল্যায়ন ; ডান অপারেন্ডটি কেবল তখনই মূল্যায়ন করা হয় যদি এর মান বাইনারি অপারেশনের ফলাফলকে প্রভাবিত করতে পারে। এর অর্থ হ'ল কখন সঠিক অপারেন্ড মূল্যায়ন করা হয় না:
    • &&মূল্যায়নের বাম ক্রিয়াকলাপfalse
      • (কারণ ডান অপারেণ্ড যা মূল্যায়ন করে তা বিবেচনাধীন নয়, পুরো অভিব্যক্তিটি false)
    • ||মূল্যায়নের বাম ক্রিয়াকলাপtrue
      • (কারণ ডান অপারেণ্ড যা মূল্যায়ন করে তা বিবেচনাধীন নয়, পুরো অভিব্যক্তিটি true)

সুতরাং আপনার মূল প্রশ্নে ফিরে যাওয়া, হ্যাঁ, এটি নির্মাণ বৈধ, এবং এটির |=জন্য ঠিক কোনও সমতুল্য শর্টকাট নয় =এবং ||এটি আপনার যা চান তা গণনা করে। যেহেতু |=আপনার ব্যবহারের ক্ষেত্রে অপারেটরের ডান দিকটি একটি সাধারণ পূর্ণসংখ্যার তুলনা অপারেশন, তাই |শর্টকাট সিকিউটি না করার বিষয়টি তুচ্ছ।

কিছু ক্ষেত্রে আছে, যখন শর্টকিউটিংটি পছন্দসই হয় বা এমনকি প্রয়োজনীয় হয় তবে আপনার দৃশ্যপট সেগুলির একটি নয়।

এটি দুর্ভাগ্যজনক যে অন্য কয়েকটি ভাষার মতো, জাভা &&=ও নেই ||=। এই প্রশ্নটিতে এই আলোচনা করা হয়েছিল যে জাভাতে শর্তাধীন-এবং এবং শর্তসাপেক্ষ-বা অপারেটরগুলির যৌগিক কার্য সম্পাদন সংস্করণগুলি কেন নেই? (&& =, || =)


+1, খুব পুঙ্খানুপুঙ্খ। এটি দুর্ভাগ্যজনক বলে মনে হয় যে কোনও সংকলক শর্ট সার্কিট অপারেটরে রূপান্তর করতে পারে, যদি এটি নির্ধারণ করতে পারে যে আরএইচএসের কোনও পার্শ্ব প্রতিক্রিয়া নেই। যে সম্পর্কে কোন সূত্র?
কার্ল

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

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

এছাড়াও, bitwise বা অপারেটর যা দিয়ে বিভ্রান্ত করা যাবে না এছাড়াও |
user253751

16

এটি কোনও "শর্টকাট" (বা শর্ট সার্কিট) অপারেটর নয় in এবং&& (এতে তারা LHS এর উপর ভিত্তি করে ফলাফলটি ইতিমধ্যে জেনে থাকলে তারা আরএইচএসকে মূল্যায়ন করবে না) তবে এটি কাজের ক্ষেত্রে আপনি যা চান তা করবে ।

পার্থক্যের উদাহরণ হিসাবে, এই কোডটি যদি textনাল হয় তবে তা ঠিক থাকবে :

boolean nullOrEmpty = text == null || text.equals("")

যদিও এটি হবে না:

boolean nullOrEmpty = false;
nullOrEmpty |= text == null;
nullOrEmpty |= text.equals(""); // Throws exception if text is null

(স্পষ্টতই আপনি "".equals(text)সেই বিশেষ ক্ষেত্রে করতে পারেন - আমি কেবল নীতিটি প্রদর্শন করার চেষ্টা করছি))


3

আপনার কেবল একটি বিবৃতি থাকতে পারে। একাধিক লাইনের উপর প্রকাশিত এটি আপনার নমুনা কোডের মতো প্রায় হুবহু পড়ে, কেবল কম জরুরী:

boolean negativeValue
    = defaultStock < 0 
    | defaultWholesale < 0
    | defaultRetail < 0
    | defaultDelivery < 0;

সহজ প্রকাশের জন্য, ব্যবহার |করা তার চেয়ে দ্রুততর হতে পারে ||কারণ এটি তুলনা করা এড়িয়ে যায় যদিও এর অর্থ স্পষ্টভাবে একটি শাখা ব্যবহার করা এবং এটি বহুগুণ ব্যয়বহুল হতে পারে।


আমি কেবল একটি দিয়ে শুরু করেছিলাম, তবে মূল প্রশ্নে যেমন বলেছি আমি অনুভব করেছি যে "তুলনা করার পদ্ধতিটি পড়া এবং পড়া সহজ ছিল, তাই আমি পাঠ্যতার জন্য এটি ভেঙে ফেলেছিলাম"। এই দিকে, এই ক্ষেত্রে আমি কোডটির এই বিশেষ অংশটি তৈরি করার চেয়ে | = এর আচরণ শিখতে আরও আগ্রহী।
ডেভিড ম্যাসন

আমি এই নির্দিষ্ট অপারেটরের জন্য একটি দুর্দান্ত ব্যবহারের কেস খুঁজে পাব বলে মনে হচ্ছে না। আমি বোঝাতে চাইছি যদি আপনার সমস্ত যত্নের ফলাফল হয় তবে আপনার শর্তটি কোথায় পূরণ হবে?
ফরিদ

4
@ ফরিদ কখনও কখনও আপনি থামতে চান না, বলুন যে আমি বেশ কয়েকটি কাজ করে কিছু করেছে কিনা তা সনাক্ত করতে চাই। আমার একটি busyপতাকা রয়েছে, কারণ আমার কোনও একটি কাজ কিছু করার অর্থ এই নয় যে আমি আমার অন্যান্য কাজগুলি চালাতে চাই না, তবে কোনও কাজ যদি ব্যস্ত না হয়, আমি পরিবর্তে একটি পদক্ষেপ নিতে চাই।
পিটার লরি

1

যদিও এটি আপনার সমস্যার জন্য ওভারকিল হতে পারে, পেয়ারা গ্রন্থাগারটিতে কিছু সুন্দর বাক্য গঠন রয়েছে Predicateএবং এটি / / এবং Predicateএর শর্ট সার্কিট মূল্যায়ন করে ।

মূলত, তুলনাগুলি বস্তুতে পরিণত হয়, সংগ্রহের মধ্যে প্যাকেজ করা হয় এবং তারপরে পুনরাবৃত্তি হয়। বা পূর্বাভাসের জন্য, প্রথম সত্যর হিটটি পুনরাবৃত্তি থেকে ফিরে আসে, এবং এর বিপরীতে এবং।


1

যদি এটি পঠনযোগ্যতা সম্পর্কে হয় তবে আমি পরীক্ষার যুক্তি থেকে পৃথকীকরণের পরীক্ষিত ডেটার ধারণা পেয়েছি। কোড নমুনা:

// declare data
DataType [] dataToTest = new DataType[] {
    defaultStock,
    defaultWholesale,
    defaultRetail,
    defaultDelivery
}

// define logic
boolean checkIfAnyNegative(DataType [] data) {
    boolean negativeValue = false;
    int i = 0;
    while (!negativeValue && i < data.length) {
        negativeValue = data[i++] < 0;
    }
    return negativeValue;
}

কোডটি আরও ভার্জোজ এবং স্ব-বর্ণনামূলক বলে মনে হচ্ছে। আপনি এমনকি এই পদ্ধতি পদ্ধতিতে একটি অ্যারে তৈরি করতে পারেন:

checkIfAnyNegative(new DataType[] {
    defaultStock,
    defaultWholesale,
    defaultRetail,
    defaultDelivery
});

এটি 'তুলনামূলক স্ট্রিং'-এর চেয়ে বেশি পঠনযোগ্য এবং শর্ট সার্কিটের পারফরম্যান্স সুবিধাও রয়েছে (অ্যারে বরাদ্দ এবং পদ্ধতি কল ব্যয়ে)।

সম্পাদনা করুন: আরও বেশি পঠনযোগ্যতা কেবল ভারার্গ্স পরামিতি ব্যবহার করে অর্জন করা যায়:

পদ্ধতির স্বাক্ষর হবে:

boolean checkIfAnyNegative(DataType ... data)

এবং কলটি এর মতো দেখতে পেল:

checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery );

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

@ ডেভিডম্যাসন আমি সম্মত তবে মনে রাখবেন, বেশিরভাগ আধুনিক ক্যালকুলেটরগুলি কয়েক মিলির চেয়েও কম সময়ে এই জাতীয় ওভারহেড গিলে ফেলবে। পারফরম্যান্স ইস্যু না হওয়া পর্যন্ত ব্যক্তিগতভাবে আমি ওভারহেডের যত্ন নেব না, যা যুক্তিসঙ্গত বলে মনে হয় । এছাড়াও কোড ভার্বোসিটি হ'ল একটি সুবিধা, বিশেষত যখন জাভাদোক জাআডোডোক সরবরাহ করেন না বা উত্পন্ন হয় না।
ক্রিজিসটফ জাবোসস্কি

1

এটি একটি পুরানো পোস্ট তবে নতুনদের জন্য আলাদা দৃষ্টিকোণ সরবরাহ করার জন্য, আমি একটি উদাহরণ দিতে চাই।

আমি মনে করি অনুরূপ যৌগ অপারেটরের জন্য সর্বাধিক সাধারণ ব্যবহারের কেস হবে +=। আমি নিশ্চিত যে আমরা সবাই এই জাতীয় কিছু লিখেছি:

int a = 10;   // a = 10
a += 5;   // a = 15

এই বিন্দু কি ছিল? মুল বক্তব্যটি ছিল বয়লারপ্লেট এড়ানো এবং পুনরাবৃত্তি কোডটি বাদ দেওয়া।

সুতরাং, পরের লাইন ঠিক একই কাজ করে, b1একই লাইনে দু'বার ভেরিয়েবল টাইপ করা এড়ানো ।

b1 |= b2;

4
অপারেশন এবং অপারেটরের নামগুলিতে ভুলগুলি চিহ্নিত করা শক্ত, বিশেষত যখন নামগুলি দীর্ঘ হয়। longNameOfAccumulatorAVariable += 5; বনাম longNameOfAccumulatorAVariable = longNameOfAccumulatorVVariable + 5;
আন্দ্রেই

0
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale, 
                                       defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;

আমি মনে করি যে আমি negativeValue = defaultStock < 0 || defaultWholesale < 0ইত্যাদি পছন্দ করবো এখানে সমস্ত বক্সিং এবং মোড়কের মোড়কির অদক্ষতা বাদ দিয়ে, আপনার কোডটি আসলে কী বোঝাতে চাইবে তা আমি প্রায় এত সহজে খুঁজে পাই না।
জন স্কিটি

আমার কাছে তারপরে আরও 4 টি পরামিতি রয়েছে এবং মানদণ্ডগুলি তাদের সবার জন্য একই তবে আমি আমার সমাধানটি পছন্দ করি তবে পঠনযোগ্যতার জন্য আমি এটিকে কয়েকটি লাইনে বিভক্ত করতে পারি (অর্থাত্ তালিকা তৈরি করুন, নূন্যতম সন্ধান করুন, নূন্যতমটির সাথে 0 এর সাথে তুলনা করুন) ।
রোমান

এটি একটি বৃহত সংখ্যার তুলনার জন্য কার্যকর দেখায়। এই ক্ষেত্রে আমি মনে করি স্পষ্টতা হ্রাস টাইপিং ইত্যাদির
ডেভিড ম্যাসন

0

|| লজিক্যাল বুলিয়ান OR
| বিটওয়াইজ ও

| = বিটওয়াইস ইনক্লুসিভ ওআর এবং অ্যাসাইনমেন্ট অপারেটর

| = শর্টকাটারিট না করার কারণটি হ'ল কারণ এটি কিছুটা দিকের বা লজিক্যাল ওআর করে না। ঐটাই বলতে হবে:

সি | = 2 সি = সি | এর সমান ঘ

জাভা অপারেটরদের জন্য টিউটোরিয়াল


বুলেটিনের সাথে কিছুটাও নেই বা নেই! অপারেটরটি বিটওয়্যারটি ইমেজ বা |OR হয় তবে এটি যৌক্তিকও হয়
ব্যবহারকারী 85421

আপনি সঠিক কারণ একক বিটের জন্য (বুলেটিয়ান) বিটওয়াস এবং লজিকাল ওআর সমান। যদিও ব্যবহারিকভাবে, ফলাফল একই।
oneklc
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.