জাভা এনাম সদস্যদের তুলনা করছেন: == বা সমান ()?


1735

আমি জানি যে জাভা এনামগুলি প্রাইভেট কনস্ট্রাক্টর এবং একগুচ্ছ পাবলিক স্ট্যাটিক সদস্যদের সাথে ক্লাসে সংকলিত। প্রদত্ত এনামের দুটি সদস্যের সাথে তুলনা করার সময়, আমি সর্বদা ব্যবহার করেছি .equals(), উদাহরণস্বরূপ

public useEnums(SomeEnum a)
{
    if(a.equals(SomeEnum.SOME_ENUM_VALUE))
    {
        ...
    }
    ...
}

যাইহোক, আমি সবেমাত্র কিছু কোড ==পেয়েছি যা .equals () এর পরিবর্তে সমতুল অপারেটর ব্যবহার করে :

public useEnums2(SomeEnum a)
{
    if(a == SomeEnum.SOME_ENUM_VALUE)
    {
        ...
    }
    ...
}

আমার কোন অপারেটরটি ব্যবহার করা উচিত?


7
আমি কেবল একটি খুব অনুরূপ প্রশ্নে হোঁচট খেয়েছি
ম্যাট বল

39
আমি অবাক হয়েছি যে সমস্ত উত্তরগুলিতে (বিশেষত একাধারে বহুবিশ্লেষকারক থেকে একটি যা বিস্তারিতভাবে কেন == কাজ করে) যেটি == এর আরও একটি বড় সুবিধা উল্লেখ করা হয়নি: এটি এনামগুলি কীভাবে কাজ করে তা স্পষ্ট করে তোলে (সিঙ্গলটনের একটি নির্দিষ্ট সেট হিসাবে) বস্তু)। সমান সমেত এটি একটিকে ভাবতে পরিচালিত করে যে কোনওভাবে একই এনামের 'বিকল্প' এর চারপাশে ভাসমান একাধিক উদাহরণ থাকতে পারে।
স্টুয়ার্ট রোসিটার

6
সহজবোধ্য রাখো. "==" বেশি পঠনযোগ্য এবং এটি কাজ করে কারণ এনামগুলি ডিফল্টরূপে সিঙ্গলটন হয়। রেফ
লোকেশ

উত্তর:


1574

উভয় প্রযুক্তিগতভাবে সঠিক। যদি আপনি এর উত্স কোডটি দেখেন তবে .equals()এটি কেবল পিছিয়ে যায় ==

আমি ব্যবহার করি ==, তবে এটি নাল নিরাপদ হবে।


64
ব্যক্তিগতভাবে, আমি == ব্যবহারের কারণ হিসাবে উল্লিখিত 'নাল সুরক্ষা' পছন্দ করি না।
নিবাস নোভাস

257
@ নিবাস: কেন নয়? আপনি কি নিজের যুক্তিগুলির ক্রম সম্পর্কে উদ্বিগ্ন হওয়া পছন্দ করেন (যা কেবল পাস্কেলের উত্তরের মত বাম দিক থেকে স্থিরদের তুলনা করার ক্ষেত্রে প্রযোজ্য)? আপনি কি সর্বদা পরীক্ষা করে দেখতে চান যে কোনও মান সেট .equals()করার আগে শূন্য হয় না ? আমি জানি আমি না।
ম্যাট বল

86
মনে রাখবেন যে আপনার কোডটি পড়ার সময়, "==" পাঠককে ভুল দেখা দিতে পারে যতক্ষণ না সে / সে চলে না যায় এবং জড়িত প্রকারটির উত্সটি অনুসন্ধান না করে, তারপরে এটি একটি এনাম দেখায়। সেই অর্থে, ".Equals ()" পড়তে কম বিক্ষিপ্ত হয়।
কেভিন বোউরিলিয়ন

60
@ কেভিন - আপনি যদি এমন কোনও আইডিই ব্যবহার না করে থাকেন যা উত্সটি দেখার সময় আপনাকে সরাসরি প্রকারগুলি দেখতে দেয় তবে আপনি নিজেকে প্রতারণা করছেন - সঠিক আইডিই সহ কোনও সমস্যা নয়।
MetroidFan2002

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

1113

পারি ==ব্যবহার করা enum?

হ্যাঁ: এনামগুলিতে টাইট ইনস্ট্যান্স নিয়ন্ত্রণ রয়েছে যা আপনাকে ==উদাহরণগুলির সাথে তুলনা করতে ব্যবহার করতে দেয় । এখানে ভাষা স্পেসিফিকেশন দ্বারা সরবরাহ করা গ্যারান্টি দেওয়া হয়েছে (আমার দ্বারা জোর দেওয়া):

জেএলএস 8.9 এনামস

একটি এনাম ধরণের এনাম ধ্রুবক দ্বারা সংজ্ঞায়িত ছাড়া অন্য কোনও দৃষ্টান্ত নেই।

এটি একটি এনাম টাইপ স্পষ্টভাবে ইনস্ট্যান্ট করার চেষ্টা করা একটি সংকলন-সময় ত্রুটি। final cloneপদ্ধতি Enumনিশ্চিত করে যে enumধ্রুবক ক্লোন হতে পারে না, এবং ধারাবাহিকতাতে প্রক্রিয়া নিশ্চিত করে যে ডুপ্লিকেট দৃষ্টান্ত deserialization ফলে কখনো নির্মিত দ্বারা বিশেষ চিকিত্সা। এনাম ধরণের প্রতিবিম্বিত ইনস্ট্যান্টেশন নিষিদ্ধ। একসাথে, এই চারটি জিনিস নিশ্চিত করে যে ধ্রুবকগুলির enumদ্বারা নির্ধারিত সংখ্যার বাইরে কোনও ধরণের উদাহরণ নেই enum

যেহেতু প্রতিটি enumধ্রুবকের কেবল একটি উদাহরণ রয়েছে , দুটি অবজেক্টের রেফারেন্সের তুলনা করার সময় পদ্ধতির জায়গায় অপারেটরটি ব্যবহার করা অনুমোদিত যদি জানা যায় যে তাদের মধ্যে কমপক্ষে একটি স্থিরকে বোঝায়==equalsenum । ( equalsপদ্ধতিটি Enumহ'ল এমন একটি finalপদ্ধতি যা কেবল super.equalsতার যুক্তি উপস্থাপন করে এবং ফলাফলটি প্রদর্শন করে, যাতে একটি পরিচয়ের তুলনা করা হয়।

এই গ্যারান্টিটি যথেষ্ট দৃ is় যে জোশ ব্লচ সুপারিশ করেছেন, আপনি যদি সিঙ্গেলটন প্যাটার্নটি ব্যবহার করার জন্য জোর দিয়ে থাকেন তবে এটি প্রয়োগের সর্বোত্তম উপায় হল একটি একক উপাদান ব্যবহার করা enum(দেখুন: কার্যকর জাভা 2 য় সংস্করণ, আইটেম 3: একটির সাথে সিঙ্গেলটন সম্পত্তি প্রয়োগ করুন) প্রাইভেট কনস্ট্রাক্টর বা এনাম টাইপ ; থ্রেড সেফটি সিঙ্গলটনে )


==এবং মধ্যে পার্থক্য কি equals?

অনুস্মারক হিসাবে, এটি বলা দরকার যে সাধারণত, এটির পক্ষে ==কার্যকর একটি বিকল্প নয় equals। এটি যখন হয় (যেমন সহ enum), তখন দুটি গুরুত্বপূর্ণ পার্থক্য বিবেচনা করতে হবে:

== কখনও ছুড়ে না NullPointerException

enum Color { BLACK, WHITE };

Color nothing = null;
if (nothing == Color.BLACK);      // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException

== সংকলন সময়ে উপযুক্ততা চেক টাইপ সাপেক্ষে

enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };

if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT);      // DOESN'T COMPILE!!! Incompatible types!

==প্রযোজ্য হলে ব্যবহার করা উচিত ?

ব্লাচ নির্দিষ্টভাবে উল্লেখ করেছে যে অপরিবর্তনীয় শ্রেণিগুলির যেগুলির দৃষ্টান্তগুলির যথাযথ নিয়ন্ত্রণ রয়েছে তাদের ক্লায়েন্টদের গ্যারান্টি দিতে পারে ==যা ব্যবহারযোগ্য। enumউদাহরণস্বরূপ উদাহরণস্বরূপ উল্লেখ করা হয়।

আইটেম 1: নির্মাতাদের পরিবর্তে স্থির কারখানার পদ্ধতিগুলি বিবেচনা করুন

[...] এটি একটি অপরিবর্তনীয় শ্রেণিকে গ্যারান্টি তৈরি করতে দেয় যে কোনও দুটি সমান দৃষ্টান্ত উপস্থিত নেই: a.equals(b)যদি এবং কেবল যদি a==b। কোনও শ্রেণি যদি এই গ্যারান্টি দেয় তবে তার ক্লায়েন্টরা পদ্ধতির ==পরিবর্তে অপারেটরটি ব্যবহার করতে পারে equals(Object), যার ফলশ্রুতি উন্নত হতে পারে। এনাম ধরণের এই গ্যারান্টি সরবরাহ করে।

সংক্ষিপ্তসার হিসাবে, ব্যবহার ==করার জন্য যুক্তিগুলি হ'ল enum:

  • এটা কাজ করে।
  • এটা দ্রুত।
  • রান-টাইমে এটি নিরাপদ।
  • সংকলন সময়ে এটি নিরাপদ।

27
উত্তম উত্তর কিন্তু ... 1. এটি কাজ করে : সম্মত হয় 2. এটি দ্রুত : এটি এনামদের জন্য প্রমাণ করুন :) 3. এটি রান-টাইমে নিরাপদ : Color nothing = null;আইএমএইচও কি বাগ এবং এটি ঠিক করা উচিত, আপনার এনমের দুটি মান রয়েছে, তিনটি নয় ( টম হাটিনের মন্তব্য দেখুন) ৪. এটি সংকলন-সময়ে নিরাপদ : ঠিক আছে, তবে equalsএখনও ফিরে আসবে false। শেষে, আমি এটি কিনব না, আমি equals()পঠনযোগ্যতার জন্য পছন্দ করি (কেভিনের মন্তব্য দেখুন)।
পাস্কেল থিভেন্ট

201
এটি জাভার বিরুদ্ধে কালো চিহ্ন যা কিছু লোক মনে করে যে foo.equals(bar)এটি তার থেকে বেশি পঠনযোগ্যfoo == bar
বেনেট ম্যাকএলউই

19
এটি কাজ করে: যতক্ষণ না আপনাকে রিফ্যাক্টরিংয়ের অংশ হিসাবে একটি এনামকে ক্লাসের সাথে প্রতিস্থাপন করতে হবে। শুভকামনা == যা ভেঙে ব্যবহার করে সমস্ত কোড সন্ধান করুন। এটি দ্রুত: এমনকি সত্য (প্রশ্নোত্তর) হলেও, অকাল অপটিমাইজেশন সম্পর্কে নথের উদ্ধৃতি রয়েছে। রান-টাইমে নিরাপদ: "নিরাপদ" হ'ল প্রথম শব্দ নয় যা মনে হয় যদি == ব্যবহার আপনাকে নালপয়েন্টার এক্সসেপশন থেকে আলাদা করে দেয় only সংকলন সময়ে নিরাপদ: আসলে না। এটি ভুল ধরণের তুলনা করার পরিবর্তে প্রাথমিক ভুল থেকে আপনাকে রক্ষা করতে পারে, তবে আবার যদি আপনার প্রোগ্রামাররা এইভাবে বোবা হয় তবে "নিরাপদ" হ'ল এক জিনিস যা আপনি নন।
লাসলোক

35
"যদি এইভাবে আপনার প্রোগ্রামাররা বোবা হয় তবে" নিরাপদ "হ'ল একটি জিনিস যা আপনি নন" " - আমি এই উদ্ধৃতির সাথে একমত নই। এই ধরণের চেকিং সম্পর্কে যা হয়: সংকলনের সময় "বোবা" ভুলগুলি প্রতিরোধ করা, এইভাবে কোড চালানোর আগেই। এমনকি স্মার্ট লোকেরা বোবা ভুল করে, প্রতিশ্রুতির চেয়ে কিছু গ্যারান্টি দেয়।
ইয়ামাজোরস

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

88

==দুটি এনাম মানের তুলনা করতে ব্যবহার করে কাজ করে, কারণ প্রতিটি এনাম ধ্রুবকের জন্য কেবল একটি অবজেক্ট থাকে।

পাশের নোটে, ==নাল-সেফ কোড লিখতে আসলে ব্যবহার করার দরকার নেই , আপনি যদি নিজের equals()মতো করে লিখে থাকেন তবে :

public useEnums(final SomeEnum a) {
    if (SomeEnum.SOME_ENUM_VALUE.equals(a)) {
        
    }
    
}

বাম দিক থেকে তুলনামূলক কনস্ট্যান্ট নামে পরিচিত এটি একটি সেরা অনুশীলন যা আপনার অবশ্যই অনুসরণ করা উচিত।


9
আমি .equals()স্ট্রিংয়ের মানগুলিতে প্রবেশ করার সময় এটি করি তবে আমি এখনও মনে করি এটি নাল-নিরাপদ কোড লেখার জন্য একটি কৃপণ উপায়। আমার চেয়ে অনেক বেশি অপারেটর থাকত (বা কোনও পদ্ধতি, তবে আমি জানি যে [নাল বস্তু] জাটায় বিন্দু অপারেটর কীভাবে কাজ করে তার জরিপগুলি কখনই নাল-নিরাপদ হবে না) যা নির্বিশেষে সর্বদা নাল-নিরাপদ অর্ডার এটি ব্যবহার করা হয়েছে। শব্দার্থকভাবে, "সমতুল্য" অপারেটরটি সর্বদা ভ্রমণ করা উচিত ।
ম্যাট বল

2
ঠিক আছে, জাভাতে গ্রোভির নিরাপদ নেভিগেশন অপারেটর নেই ( ?.), ধ্রুবকের সাথে তুলনা করার সময় আমি এই অনুশীলনটি চালিয়ে যাব এবং, টিবিএইচ, আমি এটি কৃপণ মনে করি না, সম্ভবত "কম প্রাকৃতিক" হতে পারে।
পাস্কাল থিভেন্ট 21

32
একটি nullএনাম সাধারণত একটি ত্রুটি। আপনি সমস্ত সম্ভাব্য মানগুলির এই সংখ্যাটি পেয়েছেন এবং এখানে অন্য একটি রয়েছে!
টম হাটিন -

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

24
বাম দিক থেকে কনস্ট্যান্টদের তুলনা করুন যোদা স্টাইলে সেরা ইংলিশের মতো সেরা অনুশীলনের।
মার্টিনাস

58

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

যাহোক:

  1. এটা সত্য যে ==আমার মনের মধ্যে NPE ছোঁড়ার কখনো হয় অসুবিধা এর ==enumপ্রকারভেদগুলির জন্য খুব কমই কখনও প্রয়োজন হওয়া উচিত null, যেহেতু আপনি যে কোনও অতিরিক্ত রাষ্ট্রের মাধ্যমে প্রকাশ করতে চাইতে nullপারেন কেবলমাত্র enumএকটি অতিরিক্ত উদাহরণ হিসাবে যুক্ত হতে পারে । এটি যদি অপ্রত্যাশিতভাবে হয় তবে nullআমি ==চুপচাপ মিথ্যাতে মূল্যায়ন করার চেয়ে এনপিই করতাম । সুতরাং আমি রান-টাইম মতামত এটিকে আরও নিরাপদ সাথে একমত নই ; অভ্যাসে প্রবেশ করা ভাল, কখনই enumমানগুলি হতে দেওয়া উচিত নয় @Nullable
  2. যুক্তি হল যে ==হয় আরো দ্রুত আরো বাজে হয়। অধিকাংশ ক্ষেত্রে আপনাকে কল করব .equals()একটি পরিবর্তনশীল যার কম্পাইল সময় টাইপ enum ক্লাস হয়, এবং এইসব ক্ষেত্রেও কম্পাইলার জানতে পারেন যে, এই হিসাবে একই ==(কারণ একটি enum'র equals()পদ্ধতি উপেক্ষিত হতে পারে না) এবং ফাংশন কল নিখুত করতে দূরে। কম্পাইলারটি বর্তমানে এটি করে কিনা তা আমি নিশ্চিত নই, তবে এটি যদি না ঘটে এবং জাভাতে সামগ্রিকভাবে পারফরম্যান্সের সমস্যা হিসাবে দেখা দেয় তবে আমি 100,000 জাভা প্রোগ্রামারদের প্রোগ্রামিং স্টাইলটি অনুসারে পরিবর্তন করার চেয়ে কম্পাইলারটি ঠিক করেছি rather একটি নির্দিষ্ট সংকলক সংস্করণ এর কর্মক্ষমতা বৈশিষ্ট্য।
  3. enumsঅবজেক্টস। অন্যান্য সমস্ত অবজেক্টের ধরণের জন্য মান তুলনা হয় .equals()না ==। আমি মনে করি এটির জন্য একটি ব্যতিক্রম করা বিপজ্জনক enumsকারণ আপনি ঘটনাক্রমে ==পরিবর্তে অবজেক্টের সাথে তুলনা করে শেষ করতে equals()পারেন, বিশেষত যদি আপনি enumএকটি অ-এনাম শ্রেণিতে রেফ্যাক্টর হন। এই ধরনের রিফ্যাক্টরিংয়ের ক্ষেত্রে এটি উপরের দিক থেকে কাজ করে যা ভুল। নিজেকে বোঝানোর জন্য যে ব্যবহারের ব্যবহার ==সঠিক, আপনি যাচাই করতে হবে যে প্রশ্নে মানটি একটি enumবা আদিম; যদি এটি একটি শ্রেণিবদ্ধ হয় enum, তবে এটি ভুল তবে মিস করা সহজ হবে কারণ কোডটি এখনও সংকলিত হবে। একমাত্র ক্ষেত্রে যখন ব্যবহার.equals()ভুল হবে যদি প্রশ্নের মানগুলি আদিম হয়; সেক্ষেত্রে কোডটি সংকলন করবে না তাই এটি মিস করা আরও শক্ত। সুতরাং, .equals()সঠিক হিসাবে চিহ্নিত করা অনেক সহজ এবং ভবিষ্যতের রিফ্যাক্টরিংগুলির বিরুদ্ধে এটি নিরাপদ।

আমি আসলেই মনে করি যে জাভা ভাষায় বাম হাতের মানকে .equals () কল করতে অবজেক্টগুলিতে == সংজ্ঞায়িত করা উচিত ছিল এবং বস্তুর পরিচয়ের জন্য পৃথক অপারেটর প্রবর্তন করা উচিত, তবে জাভা সংজ্ঞায়িত হয়নি।

সংক্ষেপে, আমি এখনও যুক্তিগুলি ধরণের .equals()জন্য ব্যবহারের পক্ষে বলে মনে করি enum


4
ওয়েল, প্রায় 3 পয়েন্ট, আমি লক্ষ্য enumহিসাবে ব্যবহার করতে পারি switchতাই তারা কিছুটা বিশেষ। Stringগুলিও কিছুটা বিশেষ।
কার্টেনডগ

স্যুইচ স্টেটমেন্টের সিনট্যাক্সে না হয় == না .equals () থাকে তাই আপনার পয়েন্টটি কী তা আমি দেখতে পাই না। আমার পয়েন্ট ৩) কোনও পাঠকের পক্ষে যাচাই করা সহজ কোড সম্পর্কে। স্যুইচ স্টেটমেন্টগুলির সাম্যতা শব্দার্থতত্তা যতক্ষণ স্যুইচ বিবৃতিটি সংকলন করে ততক্ষণ সঠিক।
টোবিয়াস

17

আমি ব্যবহার করতে পছন্দ করি == পরিবর্তেequals :

ইতিমধ্যে এখানে অন্যদের সাথে আলোচনা করা ছাড়াও অন্য কারণ, আপনি কি কোনও বাগটি উপলব্ধি না করেই পরিচয় করিয়ে দিতে পারেন। ধরুন আপনার কাছে এই এনাম রয়েছে যা ঠিক একই তবে পৃথক পৃথক প্যাকেজে (এটি সাধারণ নয়, তবে এটি ঘটতে পারে):

প্রথম এনাম :

package first.pckg

public enum Category {
    JAZZ,
    ROCK,
    POP,
    POP_ROCK
}

দ্বিতীয় এনাম:

package second.pckg

public enum Category {
    JAZZ,
    ROCK,
    POP,
    POP_ROCK
}

তারপর অনুমান আপনি পরবর্তী মত সমান ব্যবহার item.categoryযা first.pckg.Categoryকিন্তু আপনি দ্বিতীয় enum (আমদানি second.pckg.Categoryএটা বুঝতে ছাড়া) পরিবর্তে প্রথম:

import second.pckg.Category;
...

Category.JAZZ.equals(item.getCategory())

সুতরাং আপনি সবসময় পাওনা পাচ্ছেন falseএটি একটি আলাদা এনাম তবে আপনি সত্য বলে আশা করছেন কারণ item.getCategory()এটি JAZZ। এবং এটি দেখতে কিছুটা কঠিন হতে পারে।

সুতরাং, আপনি যদি পরিবর্তে অপারেটরটি ব্যবহার করেন তবে আপনার ==একটি সংকলন ত্রুটি থাকবে:

অপারেটর == "সেকেন্ড.প্যাকজি.এইগ্রাফিকেশন", "ফার্স্ট.প্যাক.জি. ক্যাটাগরি" এ প্রয়োগ করা যাবে না

import second.pckg.Category; 
...

Category.JAZZ == item.getCategory() 

আপনি উল্লেখ করেছেন খুব ভাল পয়েন্ট। সুতরাং আমি যা করব তা হ'ল myenum.value () প্রয়োগ করা এবং তারপরে এনপিই সুরক্ষার জন্য == তুলনা করুন।
জাভা মেইন

14

দুটি তুলনা করার জন্য এখানে একটি অপরিশোধিত সময় পরীক্ষা:

import java.util.Date;

public class EnumCompareSpeedTest {

    static enum TestEnum {ONE, TWO, THREE }

    public static void main(String [] args) {

        Date before = new Date();
        int c = 0;

        for(int y=0;y<5;++y) {
            for(int x=0;x<Integer.MAX_VALUE;++x) {
                if(TestEnum.ONE.equals(TestEnum.TWO)) {++c;}
                if(TestEnum.ONE == TestEnum.TWO){++c;}              
            }
        }

        System.out.println(new Date().getTime() - before.getTime());
    }   

}

একবারে আইএফ-কে মন্তব্য করুন। বিযুক্ত কোডটি বিযুক্ত-কোডের মধ্যে উপরে থেকে দুটি তুলনা করা হল:

 21  getstatic EnumCompareSpeedTest$TestEnum.ONE : EnumCompareSpeedTest.TestEnum [19]
 24  getstatic EnumCompareSpeedTest$TestEnum.TWO : EnumCompareSpeedTest.TestEnum [25]
 27  invokevirtual EnumCompareSpeedTest$TestEnum.equals(java.lang.Object) : boolean [28]
 30  ifeq 36

 36  getstatic EnumCompareSpeedTest$TestEnum.ONE : EnumCompareSpeedTest.TestEnum [19]
 39  getstatic EnumCompareSpeedTest$TestEnum.TWO : EnumCompareSpeedTest.TestEnum [25]
 42  if_acmpne 48

প্রথম (সমান) একটি ভার্চুয়াল কল করে এবং স্ট্যাক থেকে রিটার্ন বুলিয়ান পরীক্ষা করে। দ্বিতীয় (==) স্ট্যাক থেকে সরাসরি বস্তুর ঠিকানাগুলির তুলনা করে। প্রথম ক্ষেত্রে আরও ক্রিয়াকলাপ রয়েছে।

আমি একবারে উভয় আইএফ-এর সাথে এই পরীক্ষাটি বেশ কয়েকবার চালিয়েছি। "==" এতো সামান্য দ্রুত হয়।


আমি সন্দেহ করি যে সংকলক শাখা-পূর্বাভাস এই পরীক্ষাটি অবৈধ করে তুলতে পারে। একটি স্মার্ট সংকলক উভয়ই যদি বিবৃতি সর্বদা মিথ্যা হিসাবে মূল্যায়ন করবে এবং এইভাবে একাধিক তুলনা করা এড়াবে তা স্বীকার করবে recognize সত্যই স্মার্ট সংকলক এমনকি স্বীকৃতি দিতে পারে যে y এবং x লুপের মানগুলি ফলাফলের উপর কোনও প্রভাব ফেলবে না এবং পুরো
জিনিসটিকে

এটা পারে, কিন্তু এটা অবশ্যই না। আমি আমার উত্তরে প্রকৃত সংকলক-উত্পাদিত বাইটকোড দেখাব।
ChrisCantrell

আপনি উভয় বিভ্রান্ত :-) শাখার পূর্বাভাস রান-টাইমে কাজ করে তাই বিভিন্ন বাইট কোডটি অত্যন্ত প্রাসঙ্গিক নয়। তবে এই ক্ষেত্রে শাখার পূর্বাভাস উভয় ক্ষেত্রেই সমানভাবে সহায়তা করবে ।
মিনিটে ভিজিট করুন

7
কে পাত্তা দেয়? ভিডিও গেম চলাকালীন আপনি লুপের ভিতরে কয়েক হাজার বার এনামের সাথে তুলনা না করলে অতিরিক্ত ন্যানোসেকেন্ড অর্থহীন।
user949300

বাইটকোড পারফরম্যান্সের জন্য বেশ অপ্রাসঙ্গিক, যদি না আপনি ব্যাখ্যামূলক মোডটি চাপ দিচ্ছেন। পারফরম্যান্স হুবহু দেখতে দেখতে একটি জেএমএইচ বেঞ্চমার্ক লিখুন ।
maarartinus


7

TL; ড

আরেকটি বিকল্প হ'ল Objects.equalsইউটিলিটি পদ্ধতি।

Objects.equals( thisEnum , thatEnum )

Objects.equals নাল-সুরক্ষার জন্য

সমান অপারেটর == সমান () এর পরিবর্তে

আমার কোন অপারেটরটি ব্যবহার করা উচিত?

তৃতীয় বিকল্প হ'ল জাভা 7 এবং তার পরে যুক্তequals হওয়া Objectsইউটিলিটি ক্লাসে স্থিতিশীল পদ্ধতি ।

উদাহরণ

Monthএনাম ব্যবহার করে এখানে একটি উদাহরণ ।

boolean areEqual = Objects.equals( Month.FEBRUARY , Month.JUNE ) ;  // Returns `false`.

উপকারিতা

আমি এই পদ্ধতিতে একটি দম্পতি উপকার পেয়েছি:

  • নাল-নিরাপত্তা
    • দুজনেই নাল ➙ true
    • হয় নাল ➙ false
    • নিক্ষেপের ঝুঁকি নেই NullPointerException
  • কমপ্যাক্ট, পঠনযোগ্য

কিভাবে এটা কাজ করে

কি যুক্তি দ্বারা ব্যবহৃত হয় Objects.equals?

নিজের জন্য দেখুন, থেকে জাভা 10 সোর্স কোড এর OpenJDK :

return (a == b) || (a != null && a.equals(b));

6

==এনাম কনস্ট্যান্টের তুলনা করা ছাড়া অন্য কিছু ব্যবহার করা বাজে কথা। এটি বস্তুর সাথে তুলনা করার মতোclassequals - এটি করবেন না!

তবে সান জেডিকে 6u10 এবং এর আগের একটি বাজে বাগ (বাগআইড 6277781 ) ছিল historical তিহাসিক কারণে এটি আকর্ষণীয় হতে পারে। এই বাগটি ==ডিসিরিয়ালাইজড এনামগুলিতে যথাযথ ব্যবহার রোধ করেছিল , যদিও এটি তর্কযোগ্যভাবে কিছুটা কোণার ক্ষেত্রে।


4

এনামগুলি হ'ল এমন ক্লাস যা একক (যেমন সিঙ্গলটনের মতো) প্রতিটি গণনার ধ্রুবক দ্বারা public static final field(স্থাবর) দ্বারা ঘোষিত হয় যাতে পদ্ধতি ==ব্যবহারের পরিবর্তে অপারেটর তাদের সাম্যতা পরীক্ষা করতে ব্যবহার করতে পারেequals()


1

এনামগুলি সহজেই == দিয়ে কাজ করার কারণ হ'ল প্রতিটি সংজ্ঞায়িত উদাহরণটিও একটি সিঙ্গলটন। সুতরাং পরিচয় তুলনা == ব্যবহার সর্বদা কার্যকর হবে।

তবে == ব্যবহার করা কারণ এটি এনামগুলির সাথে কাজ করে তার অর্থ আপনার সমস্ত কোড সেই এনামের ব্যবহারের সাথে শক্তভাবে মিশ্রিত।

উদাহরণস্বরূপ: এনামস একটি ইন্টারফেস প্রয়োগ করতে পারে। মনে করুন আপনি বর্তমানে এমন একটি এনাম ব্যবহার করছেন যা ইন্টারফেস 1 প্রয়োগ করে। যদি পরে, কেউ এটি পরিবর্তন করে বা একই ইন্টারফেসের প্রয়োগ হিসাবে একটি নতুন শ্রেণি ইমপ্লায় 1 প্রবর্তন করে। তারপরে, আপনি যদি ইমপ্লাই 1 এর উদাহরণগুলি ব্যবহার করতে শুরু করেন তবে পূর্ববর্তী ব্যবহারের == ব্যবহারের কারণে আপনার কাছে প্রচুর কোড পরিবর্তন এবং পরীক্ষা করতে হবে।

অতএব, যদি কোন ন্যায়সঙ্গত লাভ না হয় তবে একটি ভাল অনুশীলন হিসাবে বিবেচিত যা অনুসরণ করা ভাল।


উত্তম উত্তর, তবে ইতিমধ্যে এখানে উল্লেখ করা হয়েছে
shmosel

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

1

সোনার নিয়মের একটি Enum values should be compared with "=="। কারণগুলি নিম্নরূপ:

একটি এনাম মানের সাথে সমতা পরীক্ষা করার equals()বিষয়টি পুরোপুরি বৈধ কারণ একটি এনাম একটি অবজেক্ট এবং প্রতিটি জাভা বিকাশকারী জানেন ==যে কোনও বস্তুর সামগ্রীর তুলনা করতে ব্যবহার করা উচিত নয়। একই সময়ে, ==এনামগুলিতে ব্যবহার করে:

  • হিসাবে একই প্রত্যাশিত তুলনা (সামগ্রী) সরবরাহ করে equals()

  • তুলনায় আরও নাল নিরাপদ equals()

  • রানটাইম চেকিংয়ের চেয়ে কমপাইল টাইম (স্ট্যাটিক) চেকিং সরবরাহ করে

এই কারণে, ব্যবহার ==পছন্দ করা উচিত equals()

কিন্তু শেষ না অন্তত, ==enums উপর তর্কসাপেক্ষে আরো পাঠযোগ্য (কম বাগাড়ম্বরপূর্ণ) চেয়ে equals()


0

সংক্ষেপে, উভয় পক্ষের পক্ষে মতামত আছে।

==অন্য উত্তরে বর্ণিত হিসাবে একদিকে যেমন এর ব্যবহারের সুবিধাগুলি রয়েছে ।

অন্যদিকে, যদি আপনি কোনও কারণে এনামগুলিকে একটি ভিন্ন পদ্ধতির (সাধারণ শ্রেণীর উদাহরণ) দিয়ে প্রতিস্থাপন করেন, তবে আপনাকে ==কামড় দিয়েছিল। (BTDT।)


-1

আমি বহুগুণে জবাব দিতে চাই:

আমি ব্যক্তিগতভাবে সমান () পছন্দ করি। তবে এটি ধরণের সামঞ্জস্যতা পরীক্ষা করে তোলে। যা আমি মনে করি এটি একটি গুরুত্বপূর্ণ সীমাবদ্ধতা।

সংকলনের সময় সামঞ্জস্যতা পরীক্ষা করতে টাইপ করতে, আপনার এনামে একটি কাস্টম ফাংশন ঘোষণা করুন এবং ব্যবহার করুন।

public boolean isEquals(enumVariable) // compare constant from left
public static boolean areEqual(enumVariable, enumVariable2) // compare two variable

এটির সাহায্যে আপনি উভয় সমাধানের সমস্ত সুবিধা পেয়েছিলেন: এনপিই সুরক্ষা, কোড পড়ার পক্ষে সহজ এবং সংকলনের সময় সামঞ্জস্যতা পরীক্ষা করে টাইপ করুন।

আমি এনামের জন্য একটি শোধিত মান যুক্ত করার পরামর্শও দিই।


4
এই সমাধান কেন এর চেয়ে ভাল ==? সঙ্গে ==আপনি NPE সুরক্ষা, সহজ-থেকে-পড়া কোড, এবং কম্পাইল সময় টাইপ সামঞ্জস্য পরীক্ষণ পাবেন, এবং আপনি ঐ সব পেতে লেখার কোনো কাস্টম সমান মত পদ্ধতি ছাড়াই।
ম্যাট বল

1
একটি UNDEFINEDমান সম্ভবত একটি ভাল ধারণা। অবশ্যই, জাভা 8 এ আপনি Optionalপরিবর্তে ব্যবহার করবেন ।
টমাস

-7

==NullPointerExceptionকোনও প্রিমিটিভ টাইপটিকে তার ক্লাস ভার্সনের সাথে তুলনা করা হলে নিক্ষেপ করতে পারে। উদাহরণ স্বরূপ:

private static Integer getInteger() {
    return null;
}

private static void foo() {
    int a = 10;

    // Following comparison throws a NPE, it calls equals() on the 
    // non-primitive integer which is itself null. 
    if(a == getInteger()) { 
        // Some code
    }
}

2
এই প্রশ্নে সুযোগটি বরং স্পষ্ট এবং আদিম ধরণের সুযোগ নেই।
টম

@ টমকে এখানে আলোচনা করা বিভ্রান্তিমূলক যা ==কখনই ফেলতে পারে না NPEs। এই প্রশ্নের যথেষ্ট উত্তর রয়েছে তবে আমার মতো কেউ যদি বাগ / বৈশিষ্ট্যটি পেতে 2 ঘন্টা সময় নেয় তবে এটি ভাল রেফারেন্স হতে পারে।
আয়ুষ্প

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