উদাহরণটি কি আরও নির্দিষ্ট ধরণের কিছু অন্যান্য উদাহরণের সমান হতে পারে?


25

আমি এই নিবন্ধটি পড়েছি: জাভাতে কীভাবে একটি সমতা পদ্ধতি লিখবেন

মূলত, এটি সমান () পদ্ধতির জন্য একটি সমাধান সরবরাহ করে যা উত্তরাধিকারকে সমর্থন করে:

Point2D twoD   = new Point2D(10, 20);
Point3D threeD = new Point3D(10, 20, 50);
twoD.equals(threeD); // true
threeD.equals(twoD); // true

তবে এটা কি ভাল ধারণা? এই দুটি দৃষ্টান্ত সমান বলে মনে হয় তবে দুটি পৃথক হ্যাশ কোড থাকতে পারে। কিছুটা ভুল না?

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


1
লিঙ্কে বর্ণিত বর্ণযুক্ত পয়েন্ট সহ উদাহরণটি আমার কাছে আরও অর্থবোধ করে। আমি বিবেচনা করব যে একটি 2 ডি পয়েন্ট (x, y) 3 ডি পয়েন্ট হিসাবে শূন্য জেড উপাদান (x, y, 0) এর সাথে দেখা যেতে পারে এবং আমি সমতাটি আপনার ক্ষেত্রে মিথ্যা ফিরিয়ে আনতে চাই। আসলে, নিবন্ধে, একটি রঙিন পয়েন্ট স্পষ্টভাবে বলা হয়েছে একটি পয়েন্ট থেকে আলাদা এবং সর্বদা মিথ্যা ফিরে আসে।
coredump

10
প্রচলিত কনভেনশন ভেঙে এমন টিউটোরিয়ালগুলির চেয়ে খারাপ আর কিছু নয় ... প্রোগ্রামারদের বাইরে এই ধরণের অভ্যাসগুলি ভাঙতে কয়েক বছর সময় লাগে।
কর্সিকা

3
@ কর্ডাম্প 2 ডি পয়েন্টকে শূন্য zস্থানাঙ্ক হিসাবে বিবেচনা করা কিছু অ্যাপ্লিকেশনগুলির জন্য দরকারী কনভেনশন হতে পারে (লিগ্যাসির ডেটা পরিচালনা করার শুরুর সিএডি সিস্টেমগুলি মাথায় আসে)। তবে এটি একটি স্বেচ্ছাসেবী সম্মেলন। 3 বা ততোধিক মাত্রা বিশিষ্ট স্পেসে প্লেনগুলির স্বেচ্ছাসেবী মনোভাব থাকতে পারে ... এটি আকর্ষণীয় সমস্যাগুলিকে আকর্ষণীয় করে তোলে।
বেন rudgers

উত্তর:


71

এটি সমতা হওয়া উচিত নয় কারণ এটি ট্রানজিটিভিটি ভেঙে দেয় । এই দুটি অভিব্যক্তি বিবেচনা করুন:

new Point3D(10, 20, 50).equals(new Point2D(10, 20)) // true
new Point2D(10, 20).equals(new Point3D(10, 20, 60)) // true

যেহেতু সাম্যতা ট্রানজিটিভ, এর অর্থ এই হওয়া উচিত যে নিম্নলিখিত প্রকাশটিও সত্য:

new Point3D(10, 20, 50).equals(new Point3D(10, 20, 60))

তবে অবশ্যই - তা নয়।

সুতরাং, আপনার castালাই সম্পর্কে ধারণা সঠিক - আশা করুন যে জাভাতে কাস্টিংয়ের অর্থ রেফারেন্সের ধরণটি castালাই। আপনি এখানে যা চান তা হ'ল একটি রূপান্তর পদ্ধতি যা কোনও Point2Dবস্তু থেকে একটি নতুন অবজেক্ট তৈরি করবে Point3D। এটি অভিব্যক্তিটিকে আরও অর্থবহ করে তুলবে:

twoD.equals(threeD.projectXY())

1
নিবন্ধটি বাস্তবায়নগুলিকে বর্ণনা করে যা ট্রানজিটিভিটি ভেঙে দেয় এবং বিভিন্ন ধরণের কাজের প্রস্তাব দেয়। এমন একটি ডোমেনে যেখানে আমরা 2 ডি পয়েন্টের অনুমতি দিই, আমরা ইতিমধ্যে সিদ্ধান্ত নিয়েছি যে তৃতীয় মাত্রা কোনও বিষয় নয়। এবং তাই (10, 20, 50)সমান (10, 20, 60)ঠিক আছে। আমরা কেবল যত্নশীল 10এবং 20
বেন rudgers

1
উচিত Point2Dএকটি আছে projectXYZ()একটি প্রদান পদ্ধতি Point3Dনিজেই প্রতিনিধিত্ব? অন্য কথায়, বাস্তবায়ন একে অপরের জানা উচিত ?
hjk

4
@hjk পরিত্রাণটি Point2Dসহজ বলে মনে হচ্ছে যেহেতু 2 ডি পয়েন্ট প্রজেক্ট করার জন্য তাদের বিমানটি প্রথমে 3 ডি স্পেসে নির্ধারণ করা প্রয়োজন। যদি 2 ডি পয়েন্টটি এটি বিমানটি জানে তবে এটি ইতিমধ্যে 3 ডি পয়েন্ট। যদি তা না হয় তবে এটি প্রকল্প করতে পারে না। আমি অ্যাবটের ফ্ল্যাটল্যান্ডের কথা মনে করিয়ে দিচ্ছি ।
বেন rudgers

@ বেনডুজার্স আপনি যদিও কোনও Plane3Dবস্তুর সংজ্ঞা দিতে পারবেন, যা 3D স্থানের মধ্যে একটি প্লেনকে সংজ্ঞায়িত করবে, এই বিমানের একটি liftপদ্ধতি থাকতে পারে (2D-> 3 ডি উত্তোলন করছে, প্রজেক্টিং নয়) যা Point2D"তৃতীয় অক্ষের জন্য একটি এবং একটি সংখ্যা গ্রহণ করবে "- বিমানের সাথে বিমান থেকে দূরত্ব স্বাভাবিক থাকে। ব্যবহারের স্বাচ্ছন্দ্যের জন্য, আপনি সাধারণ বিমানগুলি স্থিতিশীল ধ্রুবক হিসাবে সংজ্ঞায়িত করতে পারেন, যাতে আপনি এই জাতীয় জিনিসগুলি করতে পারেনPlane3D.XY.lift(new Point2D(10, 20), 50).equals(new Point3D(10, 20, 50))
ইদন আর্য

@ ইডানআরি আমি পরামর্শ দিয়েছিলাম যে 2 ডি পয়েন্টে একটি অভিক্ষেপ পদ্ধতি থাকা উচিত। উত্তোলনের পদ্ধতিগুলির সাথে বিমানগুলি সম্পর্কে, আমি মনে করি এটির জন্য দুটি যুক্তি প্রয়োজন হবে: একটি 2 ডি পয়েন্ট এবং বিমানটি এটি অনুমান করা হচ্ছে, অর্থাত্ যদি এটি বিন্দুর মালিক না হয় তবে সত্যই এটি একটি প্রক্ষেপণ হওয়া দরকার ... এবং যদি এটি পয়েন্টটির মালিক হয় তবে কেন কেবল একটি 3 ডি পয়েন্টের মালিক নয় এবং একটি সমস্যাযুক্ত ডেটা ধরণের এবং একটি পাদদেশযুক্ত পদ্ধতির গন্ধকে সরিয়ে দেবেন না? YMMV।
বেন rudgers

10

অ্যালান জে পেরিলসের জ্ঞানের কথা চিন্তা করে নিবন্ধটি পড়া থেকে দূরে চলেছি:

এপিগ্রাম 9. 10 ডাটা স্ট্রাকচারের 10 ফাংশনের চেয়ে একটি ডেটা স্ট্রাকচারে 100 ফাংশন পরিচালনা করা ভাল।

"সমতা" ডান পাওয়ার বিষয়টি হ'ল এই যে সমস্যাটি যে মার্টিন অর্ডারস্কিকে স্কালার উদ্ভাবককে রাতে বাড়িয়ে রাখে তা equalsউত্তরাধিকারসূত্রে গাছে ওভাররাইড করা ভাল ধারণা কিনা তা নিয়ে বিরতি দেওয়া উচিত ।

আমরা যখন দুর্ভাগ্য অর্জন করি তখন কী ঘটে তা ColoredPointহ'ল আমাদের জ্যামিতি ব্যর্থ হয় কারণ আমরা উত্তরাধিকার হিসাবে একটি ভাল উপার্জন না করে ডেটা ধরণের প্রসারিত করতে ব্যবহার করি। equalsকাজটি করার জন্য উত্তরাধিকার গাছের মূল নোডটি ফিরে যেতে এবং সংশোধন করা সত্ত্বেও এটি । কেন শুধুমাত্র একটি যোগ zএবং একটি colorথেকে Point?

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


6

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

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

সুতরাং আপনি সংকীর্ণ সাম্যের একটি টেবিল পাবেন:

Both objects have same values, limited to subset of shared members

Child classes can be equal to parent classes if parent and childs
data members are the same.

Both objects entire data members are the same.

Objects must have all same values and be similar classes. 

Objects must have all same values and be the same class type. 

Equality is determined by specific logical conditions in the domain.

Only Objects that both point to same instance are equal. 

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

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


2

নিয়ম, যখনই আপনি ওভাররাইড করা হয় hashcode(), আপনি ওভাররাইড equals(), এবং বিপরীতভাবে ভাইস। এটি একটি ভাল ধারণা কিনা তা নির্ভরযোগ্য ব্যবহারের উপর নির্ভর করে। ব্যক্তিগতভাবে, আমি isLike()একই প্রভাব অর্জন করতে একটি পৃথক পদ্ধতি ( বা অনুরূপ) নিয়ে যাব ।


1
সমান ওভাররাইড না করে হ্যাশকোডকে ওভাররাইড করা ঠিক হবে। উদাহরণস্বরূপ, এক একই সমতা শর্তের জন্য একটি ভিন্ন হ্যাশিং অ্যালগরিদম পরীক্ষা করার জন্য এটি করবে।
প্যাট্রিসিয়া শানাহান

1

অ-সর্বজনীন-মুখোমুখি শ্রেণীর জন্য সমতা-পরীক্ষার পদ্ধতিটি প্রায়শই কার্যকর হয় যা বিভিন্ন ধরণের অবজেক্টগুলিকে একই তথ্য উপস্থাপন করে তবে একে অপরকে "সমান" বিবেচনা করতে দেয় তবে জাভা কোনও উপায়ে অনুমতি দেয় না যার দ্বারা শ্রেণিগুলি প্রতিটিটিকে নকল করতে পারে না অন্যান্য ক্ষেত্রে প্রায়শই একক পাবলিক-ফেসিং র‍্যাপার টাইপ করা উচিত যেখানে ক্ষেত্রে পৃথক উপস্থাপনার সাথে সমতুল্য বস্তু থাকতে পারে।

উদাহরণস্বরূপ, doubleমানগুলির একটি অপরিবর্তনীয় 2D ম্যাট্রিক্সকে আবদ্ধ করে এমন একটি শ্রেণি বিবেচনা করুন । যদি বাইরের কোনও পদ্ধতিটি 1000 মাপের একটি পরিচয় ম্যাট্রিক্সের জন্য জিজ্ঞাসা করে, দ্বিতীয়টি একটি তির্যক ম্যাট্রিক্সের জন্য জিজ্ঞাসা করে এবং 1000 টি সমেত একটি অ্যারে পাস করে এবং তৃতীয়টি 2 ডি ম্যাট্রিক্সের জন্য জিজ্ঞাসা করে এবং 1000x1000 অ্যারে পাস করে যেখানে প্রাথমিক ত্রিভুজের উপাদানগুলি সমস্ত 1.0 এবং অন্য সবগুলি শূন্য, তিনটি শ্রেণিতে দেওয়া অবজেক্টগুলি অভ্যন্তরীণভাবে বিভিন্ন ব্যাকিং স্টোর ব্যবহার করতে পারে [প্রথম আকারের একক ক্ষেত্র রয়েছে, দ্বিতীয়টি হাজার-উপাদান অ্যারে রয়েছে এবং তৃতীয়টিতে এক হাজার-উপাদান উপাদান রয়েছে] তবে একে অপরকে সমতুল্য হিসাবে প্রতিবেদন করা উচিত [যেহেতু তিনটিই তির্যকটি এবং অন্য কোথাও শূন্যের সাথে 1000x1000 অপরিবর্তনীয় ম্যাট্রিক্সকে আবদ্ধ করে রাখে]।

এটি পৃথক ব্যাকিং-স্টোর প্রকারের অস্তিত্বকে আড়াল করে রাখার পরেও, মোড়কটি তুলনা করার সুবিধার্থে কার্যকর হবে কারণ সমতার জন্য আইটেমগুলি পরীক্ষা করা সাধারণত একটি বহু-পদক্ষেপ প্রক্রিয়া হবে। এটি দ্বিতীয়টির সমান কিনা তা জানে কিনা প্রথম আইটেমটি জিজ্ঞাসা করুন; যদি এটি না জানে, দ্বিতীয়টিকে জিজ্ঞাসা করুন যদি এটি জানে যে এটি প্রথমটির সমান কিনা। যদি কোনও অবজেক্টই জানে না, তবে প্রতিটি অ্যারেটিকে তার পৃথক উপাদানগুলির বিষয়বস্তু সম্পর্কে জিজ্ঞাসা করুন [দীর্ঘ-ধীর স্বতন্ত্র-আইটেম তুলনা রুট করার সিদ্ধান্ত নেওয়ার আগে অন্য চেক যোগ করতে পারে]।

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

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