== অপারেটর স্ট্রিংয়ের মান তুলনা কেন এটি জাভাতে পরিণত হয়নি?


50

প্রতিটি সক্ষম জাভা প্রোগ্রামার জানে যে আপনাকে স্ট্রিং.ইকুয়ালস () ব্যবহার করতে হবে == এর চেয়ে স্ট্রিং তুলনা করতে হবে কারণ == রেফারেন্সের সমতার জন্য পরীক্ষা করা।

আমি যখন স্ট্রিংয়ের সাথে কাজ করি তখন বেশিরভাগ সময় আমি রেফারেন্স সমতার চেয়ে মান সমতার জন্য যাচাই করি। আমার কাছে মনে হয় যে ভাষাটি যদি কেবল == ব্যবহার করে স্ট্রিংয়ের মানকে তুলনা করার অনুমতি দেয় তবে এটি আরও স্বজ্ঞাত হতে পারে।

তুলনা হিসাবে, সি # 's == অপারেটর স্ট্রিংয়ের জন্য মান সমতার জন্য পরীক্ষা করে । এবং যদি আপনার সত্যিকারের রেফারেন্সের সাম্যতার জন্য যাচাই করা দরকার হয় তবে আপনি স্ট্রিং R রেফারেন্সইকুয়ালস ব্যবহার করতে পারেন।

আর একটি গুরুত্বপূর্ণ বিষয় হ'ল স্ট্রিংস অপরিবর্তনীয়, তাই এই বৈশিষ্ট্যটির অনুমতি দিয়ে কোনও ক্ষতি করার দরকার নেই।

এটি জাভাতে প্রয়োগ করা হয়নি তার কোনও বিশেষ কারণ আছে কি?


12
আপনি স্ক্যালার দিকে নজর রাখতে চাইতে পারেন, যেখানে ==বস্তুর সমতা এবং eqরেফারেন্স সমতা ( অফস.রেলি . com / titles / 9780596155957/… )।
জর্জিও

ঠিক যেমন একটি নোট, এবং এটি আপনাকে সাহায্য করতে পারে না তবে যতদূর আমার মনে আছে আপনি স্ট্রিং
আক্ষরিকের

10
@ কেগ্রোভার: আপনি পারেন, তবে এটি কেবল রেফারেন্স সমতার একটি সুবিধাজনক উপ-পণ্য এবং জাভা কীভাবে আক্রমনাত্মকভাবে একই বস্তুর রেফারেন্সগুলিতে স্ট্রিংয়ের সাথে মিলে যাওয়া আক্ষরিককে অনুকূল করে তোলে। অন্য কথায়, এটি কাজ করে তবে ভুল কারণে for
টিডামার্স

1
@aviv ==অপারেটর কেবল মানচিত্র Equalsযদি ==অপারেটর যে ভাবে বাস্তবায়ন করা হয়। এর জন্য পূর্বনির্ধারিত আচরণটি ==হ'ল ReferenceEquals(প্রকৃতপক্ষে, ReferenceEqualsঅবজেক্ট সংস্করণ হিসাবে সংজ্ঞায়িত ==)
প্যাট্রিক হুইজিংদা

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

উত্তর:


90

আমার ধারণা এটি কেবল ধারাবাহিকতা বা "সর্বনিম্ন বিস্ময়ের মূলনীতি"। স্ট্রিং একটি অবজেক্ট, সুতরাং অন্য অবজেক্টের চেয়ে আলাদাভাবে চিকিত্সা করা গেলে অবাক করা হবে।

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

পার্শ্ব নোট হিসাবে, আপনি String.intern()স্ট্রিংটির একটি ক্যানোনিকাল (ইন্টার্নড) উপস্থাপনা পেতে ব্যবহার করতে পারেন , তার পরে তুলনা করা যেতে পারে ==। ইন্টার্নিংয়ে কিছু সময় লাগে, তবে এর পরে, তুলনাগুলি সত্যই দ্রুত হবে।

সংযোজন: কিছু উত্তরের পরামর্শের বিপরীতে এটি অপারেটর ওভারলোডিং সমর্থন করার বিষয়ে নয়+অপারেটর (সংযুক্তকরণের) উপর কাজ করে Stringগুলি যদিও জাভা ওভারলোডিং অপারেটর সমর্থন করে না; সংকলকটিতে এটি কেবল একটি বিশেষ কেস হিসাবে হ্যান্ডল করা হয়েছে, সমাধান করা StringBuilder.append()। একইভাবে, ==একটি বিশেষ কেস হিসাবে পরিচালনা করা যেতে পারে।

তাহলে কেন বিস্মিত হ'ল বিশেষ মামলায় +তবে সাথে নয় ==? কারণ, অ- অবজেক্টগুলিতে প্রয়োগ করার সময় +কেবল সংকলন করা হয় না Stringযাতে তা খুব তাড়াতাড়ি। বিভিন্ন আচরণ এর ==অনেক কম আপাত এবং এইভাবে আরো অনেক কিছু বিস্ময়কর যখন আপনার হিট হবে।


8
বিশেষ ক্ষেত্রে বিস্ময় যোগ করে।
Blrfl

17
স্ট্রিংস 1995 সালে একটি বিলাসবহুল ছিল? সত্যিই ?? কম্পিউটার ভাষার ইতিহাস দেখুন। সেই সময়ে কয়েকটি ধরণের স্ট্রিং থাকাকালীন ভাষার সংখ্যা যেগুলির কাছে নেই সেগুলির চেয়ে অনেক বেশি। সি এবং এর বংশধরদের ছাড়া আর কতটি ভাষা নাল সমাপ্ত অ্যারে ব্যবহার করে?
ওয়ারেনটি

14
@ ওয়ারেনটি: অবশ্যই, কয়েকটি (বেশিরভাগ না হলেও) ভাষার কিছু ধরণের স্ট্রিং ছিল, তবে ইউনিকোড-সক্ষম, আবর্জনা-সংগৃহীত স্ট্রিংগুলি 1995 সালে অভিনবত্ব ছিল, উদাহরণস্বরূপ, পাইথন ইউনিকোড স্ট্রিংগুলি ২.০ সংস্করণ ২,০০০ সংস্করণে প্রবর্তন করেছিল imm অপরিবর্তনীয়তা বাছাই করাও সেই সময় একটি বিতর্কিত পছন্দ ছিল।
জুনাস পুলক্কা

3
@ জুনাসপুলক্কা তারপরে সম্ভবত আপনার উত্তরটি সম্পাদনা করা উচিত say কারণ এটি যেমন দাঁড়িয়েছে, আপনার উত্তরের "সম্পূর্ণ বিলাসিতা" অংশটি বেশ ভুল।
সুইভ 18

1
ইন্টার্নিংয়ের একটি ব্যয় রয়েছে: আপনি এমন একটি স্ট্রিং পাবেন যা কখনই বিঘ্নিত হবে না। (ঠিক আছে, যদি আপনি নিজের ইন্টার্নিং ইঞ্জিন ব্যবহার না করেন যা আপনি ফেলে দিতে পারেন)
ডোনাল ফেলো

32

জাভার স্রষ্টা জেমস গোসলিং জুলাই 2000 সালে এইভাবে এটি ব্যাখ্যা করেছিলেন :

আমি মোটামুটি ব্যক্তিগত পছন্দ হিসাবে অপারেটরকে ওভারলোডিং ছেড়ে দিয়েছি কারণ আমি অনেক লোককে C ++ এ অপব্যবহার করতে দেখেছি। অপারেটর ওভারলোডিং সম্পর্কে লোক জরিপ করে আমি বিগত পাঁচ থেকে ছয় বছরে অনেক সময় ব্যয় করেছি এবং এটি সত্যিই আকর্ষণীয়, কারণ আপনি সম্প্রদায়টি তিনটি টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো হয়ে গেছেন: সম্ভবত প্রায় 20 থেকে 30 শতাংশ জনগণ অপারেটর ওভারলোডিং হিসাবে ভেবেছেন শয়তানের উত্সাহ; অপারেটর ওভারলোডিংয়ের সাথে কেউ এমন কিছু করেছে যা তাদেরকে সত্যিই টিকিয়ে দিয়েছে, কারণ তারা তালিকার সন্নিবেশের জন্য + এর মতো ব্যবহার করেছে এবং এটি জীবনকে সত্যিকার অর্থেই বিভ্রান্তিকর করে তোলে। সমস্যাটি অনেকটাই এই সত্য থেকে উদ্ভূত হয়েছিল যে আপনি কেবল অর্ধ ডজন অপারেটর রয়েছেন যা আপনি বোধগম্যভাবে ওভারলোড করতে পারেন এবং এখনও হাজার হাজার বা মিলিয়ন অপারেটর রয়েছে যা লোকে সংজ্ঞায়িত করতে চায় - তাই আপনাকে বেছে নিতে হবে,


50
আহা, হ্যাঁ, পুরাতন "বাহ্যিক বিষয়গুলিকে ধুয়ে ফেলতে দেয় যাতে ওফগুলি নিজের ক্ষতি করে না" বাহানা।
blrfl

22
@ ব্লারফ্লাল: কোনও সরঞ্জাম যদি সমাধানের চেয়ে বেশি সমস্যা তৈরি করে তবে এটি কোনও ভাল সরঞ্জাম নয়। অবশ্যই, অপারেটর ওভারলোডিংয়ের ক্ষেত্রে এটিই কিনা তা সিদ্ধান্ত নেওয়ার বিষয়টি খুব দীর্ঘ আলোচনায় রূপান্তরিত হতে পারে।
জর্জিও

15
-1। এটি প্রশ্নের কোনও উত্তর দেয় না। জাভা করে অপারেটর ওভারলোডিং আছে। ==অপারেটর বস্তু এবং প্রিমিটিভের জন্য ওভারলোড করা হয়। +অপারেটর জন্য ওভারলোড হয় byte, short, int, long, float, double, Stringএবং সম্ভবত একটি অন্যদের দম্পতি আমি ভুলে গেছি। এটা তোলে পুরোপুরি সম্ভব হতো ওভারলোড করতে ==জন্য Stringহিসাবে ভাল।
জার্গ ডব্লু মিটাগ

10
@ জর্জি - না এটি হয় না। অপারেটর ওভারলোডিং ব্যবহারকারীর স্তরে সংজ্ঞায়িত করা অসম্ভব।
সংকলকটিতে

9
@ ব্লারফ্ল: ওফগুলি নিজেরাই ক্ষতি করে বলে আমি আপত্তি করি না। তারা যখন অজ্ঞাতসারে আমার চোখ টানবে তখন আমি বিরক্ত হই।
জোনাস 21

9

ভাষার মধ্যে ধারাবাহিকতা। অপারেটর থাকা যেটি ভিন্নভাবে কাজ করে তা প্রোগ্রামারটির জন্য আশ্চর্যজনক হতে পারে। জাভা ব্যবহারকারীদের ওভারলোডকে ওভারলোড করার অনুমতি দেয় না - সুতরাং রেফারেন্স সমতা হ'ল ==অবজেক্টগুলির মধ্যে একমাত্র যুক্তিসঙ্গত অর্থ ।

জাভা মধ্যে:

  • সংখ্যার ধরণের মধ্যে, ==সংখ্যার সমতা তুলনা করে
  • বুলিয়ান ধরণের মধ্যে, ==বুলিয়ান সমতার তুলনা করে
  • অবজেক্টের মধ্যে, ==রেফারেন্স পরিচয়ের তুলনা করে
    • .equals(Object o)মানগুলির তুলনা করতে ব্যবহার করুন

এটাই. আপনি যা চান তা শনাক্ত করার জন্য সহজ নিয়ম এবং সহজ। এটি সমস্ত জেএলএসের 15.21 বিভাগে আচ্ছাদিত । এটিতে তিনটি উপ-বিভাগ রয়েছে যা বোঝা, বাস্তবায়ন করা এবং সম্পর্কিত কারণগুলি সহজ।

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

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

এটি "এই ডিজাইনের সিদ্ধান্তের নির্দিষ্ট পরিণতির জন্য কোনও ব্যবহারের ক্ষেত্রে" এর ইস্যু নয়, বরং "এই অন্যান্য বিষয়গুলির সুবিধার্থে এটি একটি নকশার সিদ্ধান্ত, এটি এর পরিণতি" "

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

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

==অবজেক্টগুলির জন্য নিয়মিত চুক্তিটি হ'ল এটি কেবলমাত্র রেফারেন্স সাম্যতা এবং এটি .equals(Object o)সমস্ত বস্তুর জন্য বিদ্যমান যা মান সমতার জন্য পরীক্ষা করা উচিত । এটিকে জটিল করে তোলা অনেক বেশি বিষয়কে জটিল করে তোলে।


উত্তর দেওয়ার জন্য সময় দেওয়ার জন্য ধন্যবাদ আমি যে অন্যান্য প্রশ্নের সাথে লিঙ্ক করেছি এটির একটি দুর্দান্ত উত্তর হবে। দুর্ভাগ্যক্রমে, এটি এই প্রশ্নের উপযুক্ত নয়। আমি মন্তব্যের উপর ভিত্তি করে স্পষ্টতা দিয়ে ওপি আপডেট করব। আমি ব্যবহারের ক্ষেত্রে আরও বেশি খুঁজছি যেখানে কোনও ভাষা-ব্যবহারকারী স্ট্রিংয়ের সাথে তুলনা করার সময় ভ্রান্ত-নেতিবাচক থাকতে চায়। ভাষাটি এই বৈশিষ্ট্যটিকে ধারাবাহিকতা হিসাবে সরবরাহ করে, এখন আমি আমাদের আরও এক ধাপ এগিয়ে যেতে চাই। নতুন ভাষার ডিজাইনারের কাছ থেকে সম্ভবত এটি ভাবছেন, এটির কি দরকার? (দুর্ভাগ্যক্রমে, কোনও ল্যাং-ডিজাইন.এসই নয়)
19:53

3
@ এটি একটি মিথ্যা নেতিবাচক নয় অনুগ্রহ করে। তারা একই জিনিস নয়। এটাই বলছে। আমার জাভা 8-এও এটি অবশ্যই উল্লেখ new String("foo") == new String("foo")করতে হবে ( স্ট্রিংয়ের নকল দেখুন )।

1
ভাষার নকশা হিসাবে, সিএস.এসই বিজ্ঞাপন দেয় যে এটি সেখানে বিষয় হতে পারে।

ওহ, আপনাকে ধন্যবাদ! আমি আমার ভবিষ্যতের ল্যাং-ডিজাইন প্রশ্নগুলি পোস্ট করব। :) এবং হ্যাঁ, দুর্ভাগ্যক্রমে 'মিথ্যা-নেতিবাচক' আমার প্রশ্নটি এবং আমি যা খুঁজছি তার বর্ণনা দেওয়ার সবচেয়ে সঠিক উপায় নয় .. আমার আরও শব্দ লিখতে হবে যাতে লোকেরা আমি কী অনুমান করতে পারি না বলার চেষ্টা করছি।
21

2
"ভাষার মধ্যে ধারাবাহিকতা" জেনেরিকগুলিতেও সহায়তা করে
ব্রেন্ডন

2

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

আমি সি # তে কোনও বিশেষজ্ঞ নই, তবে সেই ভাষার ডিজাইনাররা এটিকে এমনভাবে তৈরি করেছেন বলে মনে হয় যে প্রতিটি আদিম একটি structএবং প্রতিটি structবস্তু। যেহেতু সি # অপারেটরকে ওভারলোডিংয়ের অনুমতি দেয়, সেই ব্যবস্থাটি যে কোনও শ্রেণীর পক্ষে কেবল Stringকোনও অপারেটরের সাথে নিজেকে "প্রত্যাশিত" উপায়ে কাজ করা খুব সহজ করে তোলে । সি ++ একই জিনিসকে অনুমতি দেয়।


1
"জাভা অপারেটর ওভারলোডিং অবলম্বন পাওয়া যায়নি, যার মানে == শুধুমাত্র আদিম ধরনের বা রেফারেন্স ক্ষেত্রে প্রযোজ্য আর কিছু একটি পদ্ধতি নামোচ্চারণের প্রয়োজন।।": এক যোগ করতে পারে যে যদি ==স্ট্রিং সমতা বোঝানো, আমরা রেফারেন্স সমতার জন্য অন্য স্বরলিপি প্রয়োজন হবে।
জর্জিও

@ জর্জিও: হুবহু গিলাদ নামানের উত্তর সম্পর্কে আমার মন্তব্য দেখুন।
ব্লারফ্ল

যদিও এটি একটি স্থির পদ্ধতি দ্বারা সমাধান করা যেতে পারে যা দুটি বস্তুর (বা কোনও অপারেটর) রেফারেন্সের সাথে তুলনা করে। উদাহরণস্বরূপ সি # তে লাইক দিন।
গিলাদ নামান

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

1
@ ব্লারফ্ল: সত্যিই নয়। রেফারেন্স ( ClassName.ReferenceEquals(a,b)), এবং একটি ডিফল্ট ==অপারেটর এবং Equalsপদ্ধতি উভয়ই নির্দেশ করে তুলনা করার জন্য একটি নির্ধারিত উপায় থাকবে ReferenceEquals
গিলাদ নামান

2

এটি অন্যান্য ভাষায় আলাদা করা হয়েছে।

অবজেক্ট পাসক্যাল (ডেল্ফি / ফ্রি পাস্কাল) এবং সি # তে, সাম্য অপারেটরটি স্ট্রিংগুলিতে অপারেটিং করার সময় মানগুলির তুলনা করার জন্য সংজ্ঞা দেওয়া হয়, রেফারেন্সগুলি নয়।

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

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

সুতরাং একটি কারণের জন্য, আমি কেবল অনুমান করতে পারি যে তারা তাদের পক্ষে এটি সহজ করে দিয়েছে এবং অপারেটরকে কোডিং না দিয়ে স্ট্রিংগুলিতে সংকলককে ব্যতিক্রম করে।


এই প্রশ্ন জিজ্ঞাসা উত্তর কিভাবে?
gnat

শেষ বাক্যটি দেখুন (যা আমি একটি সম্পাদনায় সঠিক অনুচ্ছেদে আলাদা করেছি)।
ফ্যাব্রিকিও আরাউজো

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

1

জাভাতে, কোনও অপারেটর ওভারলোডিং নেই যা কিছু আছে, এবং এ কারণেই তুলনা অপারেটরগুলি কেবল আদিম ধরণের জন্য ওভারলোড হয়।

'স্ট্রিং' বর্গটি কোনও আদিম নয়, সুতরাং এটি '==' এর জন্য একটি ওভারলোডিং নেই এবং কম্পিউটারের স্মৃতিতে অবজেক্টের ঠিকানাটির তুলনা করার ডিফল্ট ব্যবহার করে।

আমি নিশ্চিত নই, কিন্তু আমি মনে করি যে জাভা 7 বা 8 ওরাকল কম্পাইলার চিনতে একটি ব্যতিক্রম তৈরি str1 == str2যেমনstr1.equals(str2)


"আমি নিশ্চিত নই, তবে আমি মনে করি যে জাভাতে or বা ৮ টি ওরাকল সংকলকটিতে str1 == str2 কে str1.equals (str2) হিসাবে স্বীকৃতি দিতে ব্যতিক্রম করেছিল": আমি অবাক হব না: ওরাকল কম চিন্তিত বলে মনে হচ্ছে সূর্যের তুলনায় ন্যূনতমতা নিয়ে।
জর্জিও

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

1
@ উইলিহ্যাম টোটল্যান্ড: বিপরীত ক্ষেত্রে বিবেচনা করুন। বর্তমানে, আমি যদি দুটি স্ট্রিং তৈরি করেন, s1এবং s2তাদের একই বিষয়বস্তু দিতে, তারা সমতা (পাস s1.equals(s2)) তুলনা কিন্তু একই রেফারেন্স ( ==) তুলনা কারণ তারা দুটি ভিন্ন বস্তু করছি। সাম্যকে ==বোঝানোর জন্য শব্দার্থবিজ্ঞান পরিবর্তন করার ফলে s1 == s2এটি মূল্যায়নের জন্য trueকোথায় ব্যবহৃত হয়েছিল তা মূল্যায়ন করতে পারে false
ব্লারফ্ল

2
@ ব্রাফল: যদিও এটি সত্য, এটি প্রথম স্থানের উপর নির্ভর করা খুব ব্যতিক্রমী জিনিস বলে মনে হচ্ছে, কারণ স্ট্রিংগুলি অবিচ্ছেদ্য এবং অভ্যন্তরীণ বস্তু।
উইলিয়াম টটল্যান্ড

2
@ জিওরজিও: "জাভা 7 বা 8 ওরাকল স্ট্রাপকে একটি11== str2 হিসাবে str1.equals (str2) হিসাবে স্বীকৃতি দিতে সংকলকটিতে একটি ব্যতিক্রম করেছে" না, জাভা ভাষা নির্দিষ্টকরণ বলেছেন: রেফারেন্স ইক্যুয়ালিটি অপারেটর : "যদি কোনও সমতা অপারেটরের অপারেশনগুলি হয় উভয়ই রেফারেন্স টাইপ বা নাল টাইপ, তারপরে অপারেশন হ'ল অবজেক্ট সমতা "" এই সব ভাবেন। আমি জাভা 8 প্রারম্ভিক খসড়াতে এটি সম্পর্কে নতুন কিছু খুঁজে পাইনি ।
ডেভিড টোনহোফার

0

জাভা একটি মৌলিক নিয়ম বহাল রাখার জন্য ডিজাইন করা হয়েছে বলে মনে হয় যে ==অপারেটর যে কোনও সময় অন্য অপরকে অন্য ধরণের রূপান্তরিত করতে পারলে বৈধ হওয়া উচিত এবং রূপান্তরিত অপারেন্ডের সাথে এই ধরণের রূপান্তরটির ফলাফলের তুলনা করা উচিত।

এই নিয়ম জাভাটির পক্ষে খুব কমই অনন্য, তবে ভাষার অন্যান্য ধরণের-সম্পর্কিত দিকগুলির নকশায় এর কিছু সুদূরপ্রসারী (এবং আইএমএইচও দুর্ভাগ্য) প্রভাব রয়েছে। এটা আচরণে উল্লেখ করার ক্লিনার হত ==ধরনের X এবং Y যেখানে সমন্বয় প্রতীক ধরনের বিশেষ সমন্বয় সংক্রান্ত, এবং নিষেধ x1==y1এবং x2==y1পরোক্ষভাবে না x1==x2কিন্তু প্রত্যেক কদাপি যে [যে দর্শনের অধীনে, না double1 == long1পারেন কিনা ইঙ্গিত করতে হবে double1এর সঠিক উপস্থাপনা নয় long1, বা অন্যথায় সংকলন করতে অস্বীকার করেছে;int1==Integer1নিষিদ্ধ করা উচিত, তবে কোনও বস্তুর নির্দিষ্ট মানযুক্ত বক্সযুক্ত পূর্ণসংখ্যা কিনা (যা এমন কোনও বাক্সের পূর্ণসংখ্যার সাথে তুলনা করা সহজভাবে ফিরে আসা উচিত false) তা পরীক্ষা করার সুবিধাজনক এবং দক্ষ অ-ছোঁড়ার উপায় থাকা উচিত ]।

আবেদন বিষয়ে ==স্ট্রিং অপারেটর, যদি জাভা ধরনের operands মধ্যে সরাসরি তুলনা করতে নিষেধ করেছিলেন Stringএবং Objectআচরণকে, এটা বেশ ভাল এড়াতে পারত চমকের ==, কিন্তু কোন আচরণ এটি যেমন তুলনা যে বিস্ময়কর না হই বাস্তবায়ন হতে পারে না। দুটি স্ট্রিং রেফারেন্স টাইপ করে Objectরাখলে রেফারেন্সে টাইপ করা রেফারেন্সের Stringথেকে আলাদাভাবে আচরণ করা আইনী মিশ্র প্রকারের তুলনার চেয়ে এই আচরণগুলির মধ্যে যেহেতু পৃথক হয় তার চেয়ে অনেক কম বিস্ময়কর হত। তাহলে String1==Object1আইনি হল যে, এর আচরণে জন্য যে একমাত্র উপায় সূচিত করা হবে String1==String2এবং Object1==Object2মেলে String1==Object1একে অপরের মেলানোর জন্য হতে হবে।


আমি অবশ্যই কিছু মিস করছি, তবে আইটেমের আইএমএইচও- ==তে কেবল কল (নাল-নিরাপদ) সমান এবং অন্য কিছু (যেমন, ===বা System.identityEqual) পরিচয় তুলনার জন্য ব্যবহার করা উচিত। আদিম এবং বস্তুগুলির মিশ্রণ প্রথমে নিষিদ্ধ করা হত (1.5 এর আগে কোনও অটোবক্সিং ছিল না) এবং তারপরে কিছু সাধারণ নিয়ম পাওয়া যাবে (যেমন নাল-সেফ আনবক্স, তারপরে কাস্ট, তারপরে তুলনা)।
মার্টিনাস

@ Maaartinus: একটি ভাল ভাষা নকশা মান এবং রেফারেন্স সাম্যের জন্য পৃথক সমতা অপারেটর ব্যবহার করা উচিত। যদিও আমি সম্মত হই যে ধারণাগতভাবে int==Integerঅপারেটরটি falseযদি Integerবাতিল হয়ে যায় এবং অন্যথায় মানগুলির তুলনা করা সম্ভব হত তবে এ পদ্ধতিটি ==অন্য সমস্ত পরিস্থিতিতে আচরণের বিপরীতে হত , যেখানে এটি নিঃশর্তভাবে উভয় অপারেশনকে একই ধরণের আগে জোর করে তোলে where তাদের তুলনা। ব্যক্তিগতভাবে আমি ভাবছি int==Integerযে অযৌক্তিক নয় এমন আচরণ করার সুযোগ দেওয়ার জন্য অটো-আনবক্সিং করা হয়েছিল কিনা ...
সুপারক্যাট

... যেহেতু অটোবক্সিং intএবং একটি রেফারেন্স তুলনা করা নিরীহ হত [তবে সর্বদা ব্যর্থ হত না]। অন্যথায়, আমি কোনও এনপিই দিয়ে ব্যর্থ হতে পারে এমন অন্তর্নিহিত রূপান্তরকে অনুমতি দেওয়ার কোনও কারণ দেখতে পাচ্ছি না।
সুপারক্যাট

আমার ধারণাটি আমার ধারাবাহিক। কেবল এটি মনে রাখবেন যে উন্নত বিশ্বে ==এর কোনও সম্পর্ক নেই identityEquals। +++ "মান এবং রেফারেন্স সমতার জন্য পৃথক সমতা অপারেটর" - তবে কোনটি? আমি আদিম ==এবং রেফারেন্সের মানটি দেখায় এমন বিবেচনায় মূল্য তুলনা equalsহিসাবে বিবেচনা করব । +++ যখন বোঝানো হয় , তারপরে অটোবক্সিং করা উচিত এবং নাল-নিরাপদ সমান ব্যবহার করে রেফারেন্সগুলি তুলনা করা উচিত। +++ আমি ভীত, আমার ধারণাটি আসলে আমার নয়, কোটলিন যা করে তা ঠিক। equals==equalsint==Integer
maarartinus

@ মাআর্টিনাস: যদি ==কখনও রেফারেন্সের সাম্যতা পরীক্ষা না করা হয়, তবে এটি বোধগম্যভাবে নাল-নিরাপদ মান-সমতা পরীক্ষা করতে পারে। যে এটি করে পরীক্ষা রেফারেন্স সমতা অবশ্য গুরুতরভাবে সীমা কিভাবে এটা অসঙ্গতি ছাড়া মিশ্র রেফারেন্স / মান তুলনা সব ব্যবস্থা করতে সক্ষম। এটিও নোট করুন যে জাভা জড়িত ধরণের সংমিশ্রণের ভিত্তিতে বিশেষ আচরণ উপস্থাপনের পরিবর্তে অপারেটরগুলি উভয় অপারেন্ডকে একই ধরণের প্রচার করে not এই ধারণার উপর স্থির করা হয়েছে। উদাহরণস্বরূপ, 16777217==16777216.0fফেরত দেয় trueকারণ এটি প্রথম অপারেন্ডের একটি ক্ষতিকারক রূপান্তর সম্পাদন করে float, যখন ...
সুপারক্যাট

0

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

Address oldAddress;
Address newAddress;
... populate values ...
if (oldAddress==newAddress)
... etc ...

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

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

Integer three=new Integer(3);
Integer triangle=new Integer(3);
if (three==triangle) ...

অবশ্যই এটি মিথ্যা প্রত্যাবর্তন করে তবে আমি কাউকে দেখতে ভেবে দেখছি এটি সত্য হওয়া উচিত।

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

এবং কি সম্পর্কে ...

Object x=new String("foo");
Object y=new String("foo");
if (x==y) ...

এটি কি মিথ্যা কারণ এগুলি দুটি পৃথক বস্তু, বা সত্য কারণ তারা স্ট্রিংস যার বিষয়বস্তু সমান?

সুতরাং হ্যাঁ, আমি বুঝতে পারি কীভাবে প্রোগ্রামাররা এতে বিভ্রান্ত হয়। আমি নিজেই এটি সম্পন্ন করেছি, আমার অর্থ মাইস্ট্রিং == "foo" লিখতে হবে যখন আমি বোঝাতে চাইছিলাম যদি myString.equals ("foo") থাকে। তবে সমস্ত বস্তুর জন্য == অপারেটরের অর্থ পুনরায় ডিজাইনের সংক্ষেপে, আমি কীভাবে এটি সম্বোধন করব তা দেখছি না।


নোট করুন যে JVM- র অন্যান্য আধুনিক ভাষাগুলি, যেমন স্কেলা, =="সমান স্ট্রিং" বোঝাতে ব্যবহার করে।
আন্দ্রেস এফ

@AndresF। (শ্রাগ) জাভাতে, "<" এর অর্থ "এর চেয়ে কম", এক্সএমএলে এটি "একটি ট্যাগ খোলে"। ভিবিতে "=" এর অর্থ "সমান সমান" হতে পারে, যখন জাভাতে এটি কেবল অ্যাসাইনমেন্টের জন্য ব্যবহৃত হয়। ইত্যাদি এটি আশ্চর্যের সাথেই অবাক হয় না যে বিভিন্ন ভাষা একই জিনিস বোঝাতে বিভিন্ন চিহ্ন ব্যবহার করে বা একই প্রতীকটি বিভিন্ন জিনিস বোঝায়।
জয়

এটি আপনার উত্তরের খোঁজ ছিল না। এটা ছিল মাত্র একটি মন্তব্য। আমি কেবল ইঙ্গিত করছিলাম যে জাভা থেকে আরও আধুনিক ভাষা ==আপনাকে শেষের দিকে যেমনটি উল্লেখ করেছে ঠিক তেমনই এর অর্থটি আবার ডিজাইন করার সুযোগ নিয়েছিল ।
আন্দ্রেস এফ

@AndresF। এবং আমার উত্তরটি আপনার মন্তব্যে কোনও খুঁতখুঁতে নয়, কেবল এই বলে যে বিভিন্ন ভাষাগুলি বিভিন্নভাবে এই সমস্যাগুলির দিকে এগিয়ে যায়। :-) আমি আসলে ভিবিটি যেভাবে পরিচালনা করে তা পছন্দ করি ... ভিবি বিদ্বেষীদের কাছ থেকে থিসিস এবং বুসের জন্য বিরতি দিন ... "=" সর্বদা মান (সিস্টেম-সংজ্ঞায়িত প্রকারের জন্য) তুলনা করে, আদিম বা বস্তু কিনা। "ইস" দুটি বস্তুর হ্যান্ডলগুলির তুলনা করে। এটি আমার কাছে আরও স্বজ্ঞাত বলে মনে হচ্ছে।
জে

অবশ্যই। তবে স্কালা ভিজ্যুয়াল বেসিকের তুলনায় জাভার কাছাকাছি। আমি ভাবতে চাই যে স্কালার ডিজাইনাররা বুঝতে পেরেছিলেন যে জাভার ব্যবহার ==ত্রুটিযুক্ত ছিল।
আন্দ্রেস এফ

0

এই জন্য একটি বৈধ প্রশ্ন হল Strings, এবং না শুধুমাত্র স্ট্রিং জন্য, কিন্তু অন্যান্য অপরিবর্তনীয় কিছু "মান" প্রতিনিধিত্বমূলক অবজেক্টস, যেমন জন্য Double, BigIntegerএবং এমনকি InetAddress

==স্ট্রিংস এবং অন্যান্য মান-শ্রেণীর সাহায্যে অপারেটরকে ব্যবহারযোগ্য করে তোলার জন্য , আমি তিনটি বিকল্প দেখতে পাচ্ছি:

  • সংকলককে এই সমস্ত মান-শ্রেণি এবং তাদের বিষয়বস্তুর তুলনা করার উপায় সম্পর্কে জানুন। যদি এটি java.langপ্যাকেজ থেকে কেবল কয়েক মুঠো ক্লাস হত তবে আমি এটি বিবেচনা করতাম, তবে এটি ইনটএড্রেসের মতো মামলাগুলি কভার করে না।

  • অপারেটরকে ওভারলোডিংকে মঞ্জুরি দিন যাতে কোনও শ্রেণি তার ==তুলনা আচরণটি সংজ্ঞায়িত করে ।

  • সর্বজনীন নির্মাতাদের সরান এবং একটি পুল থেকে দৃষ্টান্ত ফিরিয়ে দেওয়ার স্থির পদ্ধতি রয়েছে, সর্বদা একই মানের জন্য একই উদাহরণটি ফিরে আসে। মেমোরি ফাঁস এড়াতে, আপনার পুলটিতে সফ্টরাইফারেন্সের মতো কিছু দরকার যা জাভা ০.০ এ বিদ্যমান ছিল না। এবং এখন, সামঞ্জস্যতা বজায় রাখতে, String()নির্মাণকারীদের আর সরানো যাবে না।

আজও কেবল যে কাজটি করা যেতে পারে তা হ'ল অপারেটর ওভারলোডিং প্রবর্তন করা এবং ব্যক্তিগতভাবে আমি জাভাটিকে সেই পথে যেতে চাই না।

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

জাভার তুলনাগুলির মাত্র একটি দিক রয়েছে যা আমাকে বিরক্ত করে: অটো-বক্সিং এবং আনবক্সিংয়ের প্রভাব। এটি আদিম এবং মোড়ক প্রকারের মধ্যে পার্থক্য লুকায়। আপনি যখন তাদের সাথে তুলনা করেন ==, তখন এগুলি অনেক আলাদা।

    int i=123456;
    Integer j=123456;
    Integer k=123456;
    System.out.println(i==j);  // true or false? Do you know without reading the specs?
    System.out.println(j==k);  // true or false? Do you know without reading the specs?
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.