জাভাতে বনাম অ্যারে.ইকুয়াল সমান


209

জাভাতে অ্যারে তুলনা করার সময়, নিম্নলিখিত 2 টি স্টেটমেন্টের মধ্যে কি কোনও পার্থক্য রয়েছে?

Object[] array1, array2;
array1.equals(array2);
Arrays.equals(array1, array2);

এবং যদি তাই হয়, তারা কি?


উত্তর:


299

array1.equals(array2)একই হিসাবে হয় array1 == array2, এটি একই অ্যারে হয়। @ আলফ যেমন উল্লেখ করেছেন এটি বেশিরভাগ লোকেরা প্রত্যাশা করে না।

Arrays.equals(array1, array2) অ্যারেগুলির বিষয়বস্তুর তুলনা করে।


একইভাবে array.toString()খুব দরকারী নাও হতে পারে এবং আপনার ব্যবহারের প্রয়োজন Arrays.toString(array)


59
দ্রষ্টব্য যে Arrays.equals()বহুমাত্রিক অ্যারেগুলির জন্য প্রত্যাশার মতো কাজ করে না, এটি কেবল রেফারেন্স সাম্যের জন্য 1 ম মাত্রার আইটেমগুলির সাথে তুলনা করে। অ্যাপাচি কমন্স ArrayUtils.isEqualsবহুমাত্রিক অ্যারেগুলির সাথে কাজ করে।
অ্যাডাম পার্কিন

4
আমি হতবাক। দৈর্ঘ্য এবং প্রতিটি বস্তুর তুলনা না করে পয়েন্টার তুলনাতে অ্যারে.একুয়ালগুলি কার্যকর করার কোনও কারণ আছে কি?
লেকটি

2
@ লেক হ'ল অ্যারের দৈর্ঘ্য এবং এতে থাকা বস্তুর তুলনা করা হয় তবে এটি যা করে না তা একটি গভীর তুলনা। অ্যারেগুলির জন্য প্রত্যাশার সাথে ফ্যাক্ট সমান কাজ করে, এটি প্রথম স্থানে সমস্যা হওয়া উচিত নয়।
পিটার লরি

48
@ অ্যাডাম পারকিন এই কারণেই আমাদের আছে Arrays.deepEquals(Object[], Object[])
এলিয়ট ফ্রিচ

3
@ জীবন্তসামারভিরা এই পদ্ধতির সংজ্ঞা, তবে .equalsএটি সামগ্রীর সাথে তুলনা করে না যার কারণে আপনার এই পদ্ধতির দরকার।
পিটার ল্যারি

86

এটি একটি কুখ্যাত সমস্যা: .equals()অ্যারেগুলি খারাপভাবে ভেঙে গেছে, কেবল কখনও এটি ব্যবহার করবেন না।

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

এখন এর জন্য প্রত্যাশিত আচরণটি equalsহ'ল ডেটা তুলনা করা। ডিফল্ট আচরণটি হ'ল পরিচয়টি তুলনা করা, যেমন Objectকোনও ডেটা নেই (পিউরিস্টদের জন্য: হ্যাঁ এটি রয়েছে, তবে এটি বিন্দু নয়); অনুমানটি হ'ল, যদি আপনার equalsসাবক্লাসগুলির প্রয়োজন হয় তবে আপনি এটি প্রয়োগ করবেন। অ্যারেগুলিতে, আপনার জন্য কোনও বাস্তবায়ন নেই, সুতরাং এটি ব্যবহার করার কথা আপনি ভাবেন না।

সুতরাং পার্থক্যটি হল, যেমনটি আপনি প্রত্যাশা করেছিলেন তেমনArrays.equals(array1, array2) কাজ করে (যেমন সামগ্রীর সাথে তুলনা করে), বাস্তবায়নে ফিরে আসে , যা পরিবর্তনের সাথে পরিচয়ের তুলনা করে, এবং এভাবে আরও ভাল প্রতিস্থাপন করা হয় (পিউরিস্টদের জন্য: হ্যাঁ আমি জানি )।array1.equals(array2)Object.equals==null

সমস্যাটি হ'ল এমনকি Arrays.equals(array1, array2)অ্যারের উপাদানগুলি যদি equalsসঠিকভাবে প্রয়োগ না করে তবে আপনাকে কঠোর কামড় দেবে । এটি একটি খুব নিষ্পাপ বক্তব্য, আমি জানি, তবে একটি খুব কম স্পষ্ট-স্পষ্ট ক্ষেত্রে রয়েছে: একটি 2 ডি অ্যারে বিবেচনা করুন।

জাভাতে 2D অ্যারে অ্যারের একটি অ্যারে, এবং অ্যারেগুলি ' equalsটি ভাঙ্গা (বা আপনি যদি পছন্দ করেন তবে অকেজো), সুতরাং Arrays.equals(array1, array2)2D অ্যারেতে প্রত্যাশা মতো কাজ করবে না।

আশা করি এইটি কাজ করবে.


13
এটি ভাঙ্গা হয়নি, এটি কেবলমাত্র অবজেক্ট থেকে উত্তরাধিকার সূত্রে প্রাপ্ত।
মাইকেল বর্গওয়ার্ট

একটি অ্যারের জন্য একটি কাস্টম বাস্তবায়ন আছে equals()? আমি ভেবেছিলাম অবজেক্ট থেকে ওভাররাইড করা হয়নি।
মার্তিজান আদালত

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

@ মার্তিজন কোর্টওক্স হুবহু সমস্যাটিই :)
আলফ

3
অ্যারেগুলির অ্যারেগুলির জন্য, আপনার প্রয়োজন Arrays.deepEquals--- এটিই যা করা someArray.equalsউচিত সবগুলি পাশাপাশি করা উচিত। (সম্পর্কিত:। Objects.deepEquals)
কেভিন জে চেস

16

এগুলি গভীরভাবে বুঝতে দুটি পদ্ধতির প্রয়োগের ভিতরে দেখুন:

array1.equals(array2);
/**
 * Indicates whether some other object is "equal to" this one.
 * <p>
 * The {@code equals} method implements an equivalence relation
 * on non-null object references:
 * <ul>
 * <li>It is <i>reflexive</i>: for any non-null reference value
 *     {@code x}, {@code x.equals(x)} should return
 *     {@code true}.
 * <li>It is <i>symmetric</i>: for any non-null reference values
 *     {@code x} and {@code y}, {@code x.equals(y)}
 *     should return {@code true} if and only if
 *     {@code y.equals(x)} returns {@code true}.
 * <li>It is <i>transitive</i>: for any non-null reference values
 *     {@code x}, {@code y}, and {@code z}, if
 *     {@code x.equals(y)} returns {@code true} and
 *     {@code y.equals(z)} returns {@code true}, then
 *     {@code x.equals(z)} should return {@code true}.
 * <li>It is <i>consistent</i>: for any non-null reference values
 *     {@code x} and {@code y}, multiple invocations of
 *     {@code x.equals(y)} consistently return {@code true}
 *     or consistently return {@code false}, provided no
 *     information used in {@code equals} comparisons on the
 *     objects is modified.
 * <li>For any non-null reference value {@code x},
 *     {@code x.equals(null)} should return {@code false}.
 * </ul>
 * <p>
 * The {@code equals} method for class {@code Object} implements
 * the most discriminating possible equivalence relation on objects;
 * that is, for any non-null reference values {@code x} and
 * {@code y}, this method returns {@code true} if and only
 * if {@code x} and {@code y} refer to the same object
 * ({@code x == y} has the value {@code true}).
 * <p>
 * Note that it is generally necessary to override the {@code hashCode}
 * method whenever this method is overridden, so as to maintain the
 * general contract for the {@code hashCode} method, which states
 * that equal objects must have equal hash codes.
 *
 * @param   obj   the reference object with which to compare.
 * @return  {@code true} if this object is the same as the obj
 *          argument; {@code false} otherwise.
 * @see     #hashCode()
 * @see     java.util.HashMap
 */
public boolean equals(Object obj) {
    return (this == obj);
}

যখন:

Arrays.equals(array1, array2);
/**
 * Returns <tt>true</tt> if the two specified arrays of Objects are
 * <i>equal</i> to one another.  The two arrays are considered equal if
 * both arrays contain the same number of elements, and all corresponding
 * pairs of elements in the two arrays are equal.  Two objects <tt>e1</tt>
 * and <tt>e2</tt> are considered <i>equal</i> if <tt>(e1==null ? e2==null
 * : e1.equals(e2))</tt>.  In other words, the two arrays are equal if
 * they contain the same elements in the same order.  Also, two array
 * references are considered equal if both are <tt>null</tt>.<p>
 *
 * @param a one array to be tested for equality
 * @param a2 the other array to be tested for equality
 * @return <tt>true</tt> if the two arrays are equal
 */
public static boolean equals(Object[] a, Object[] a2) {
    if (a==a2)
        return true;
    if (a==null || a2==null)
        return false;

    int length = a.length;
    if (a2.length != length)
        return false;

    for (int i=0; i<length; i++) {
        Object o1 = a[i];
        Object o2 = a2[i];
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }

    return true;
}

11

দীর্ঘশ্বাস. 70 এর দশকে আমি আইবিএম 370 সিস্টেমের জন্য "সিস্টেম প্রোগ্রামার" (সিসাদমিন) ছিলাম এবং আমার নিয়োগকর্তা আইবিএম ব্যবহারকারীদের গ্রুপ শেয়ারের সদস্য ছিলেন was এটি কখনও কখনও ঘটেছিল কিছু সিএমএস কমান্ডের কিছু অপ্রত্যাশিত আচরণের বিষয়ে থ্যাটসোমে এপিআর (বাগ রিপোর্ট) জমা দিয়েছিল এবং আইবিএম নোটবগকে প্রতিক্রিয়া জানায়: কমান্ডটি এটি করার জন্য ডিজাইন করা হয়েছে (এবং ডকুমেন্টেশন কী বলে) তা করে does

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

অবজেক্ট.ইকোয়্যালস বাস্তবায়নে কোনও ভুল নেই। অবজেক্টের কোনও ডেটা সদস্য নেই, সুতরাং তুলনার মতো কিছুই নেই। দুটি "অবজেক্ট" গুলি সমান এবং যদি সেগুলি হয় তবে প্রকৃতপক্ষে একই বস্তু (অভ্যন্তরীণভাবে, একই ঠিকানা এবং দৈর্ঘ্য)।

তবে সেই যুক্তি অ্যারেগুলিতে প্রযোজ্য না। অ্যারেতে ডেটা থাকে এবং আপনি ডেটা তুলনা করার জন্য (সমান মাধ্যমে) আশা করেন expect আদর্শভাবে, অ্যারে.ডি.পি.এক.এক.এল.সগুলি যেভাবে করে তবে অন্তত অ্যারে.ইক্যুয়ালগুলি (উপাদানগুলির সাথে অগভীর তুলনা) করে।

সুতরাং সমস্যাটি হ'ল অ্যারে (বিল্ট-ইন অবজেক্ট হিসাবে) অবজেক্ট.ইক্যুয়ালগুলি ওভাররাইড করে না। (ক নামে শ্রেণী হিসেবে) স্ট্রিং করে ওভাররাইড Object.equals এবং ফলাফল আশা দেব।

প্রদত্ত অন্যান্য উত্তরগুলি সঠিক: [...]। সমান ([....]) কেবলমাত্র পয়েন্টারগুলির সাথে তুলনা করে বিষয়গুলি নয়। হয়তো কোনও দিন কেউ এটি সংশোধন করবে। বা নাও হতে পারে: [...]। উপাদানগুলির সাথে আসলে তুলনা করলে কতগুলি বিদ্যমান প্রোগ্রাম ভাঙবে? আমার সন্দেহ নেই, তবে শূন্যেরও বেশি।


5
আমি ব্রোকেন.আস.-ডিজাইন করা সংক্ষিপ্ত বিবরণ পছন্দ করি
ক্রিস

5

অ্যারেগুলি উত্তরাধিকার সূত্রে equals()প্রাপ্ত হয় Objectএবং অতএব কেবল যদি তার বিরুদ্ধে কোনও অ্যারের তুলনা করে তবে তা সত্য করে তুলনা করে।

অন্যদিকে, Arrays.equalsঅ্যারের উপাদানগুলির সাথে তুলনা করে।

এই স্নিপেট পার্থক্যটি ব্যাখ্যা করে:

Object o1 = new Object();
Object o2 = new Object();
Object[] a1 = { o1, o2 };
Object[] a2 = { o1, o2 };
System.out.println(a1.equals(a2)); // prints false
System.out.println(Arrays.equals(a1, a2)); // prints true

এছাড়াও দেখুন Arrays.equals()। আরেকটি স্ট্যাটিক পদ্ধতি রয়েছে সুদের হতে পারে: Arrays.deepEquals()


1

দ্য Arrays.equals(array1, array2):

উভয় অ্যারেতে একই সংখ্যক উপাদান রয়েছে কিনা তা পরীক্ষা করে দেখুন এবং দুটি অ্যারেতে সংশ্লিষ্ট সমস্ত সংযুক্ত উপাদান সমান কিনা check

দ্য array1.equals(array2):

বস্তুকে অন্য বস্তুর সাথে তুলনা করুন এবং দুটি বস্তুর রেফারেন্স যদি এর সমান হয় তবেই সত্যটি প্রত্যাবর্তন করুন Object.equals()


0

equals()বিন্যাসের থেকে উত্তরাধিকারসূত্রে হয় Object, তাই এটি arrrays বিষয়বস্তু তাকান না, এটি শুধুমাত্র প্রতিটি অ্যারের নিজেই সমান বিবেচনা করে।

Arrays.equals()পদ্ধতি না অ্যারে 'বিষয়বস্তু তুলনা করুন। সমস্ত আদিম ধরণের জন্য ওভারলোড রয়েছে এবং অবজেক্টগুলির জন্য একটি বস্তুর নিজস্ব equals()পদ্ধতি ব্যবহার করে ।


2
আপনি "অ্যারে বিষয়বস্তু" বলছেন, এর অর্থ কি বহুমাত্রিক অ্যারেগুলিও?
অ্যালানফোস্টার

@ অ্যালানফোস্টার: না বহুমাত্রিক অ্যারেগুলি অ্যারেগুলির অ্যারে হয়, যার অর্থ তারা পদ্ধতিতে অ্যারে.ইক্যুয়ালস (অবজেক্ট [], অবজেক্ট []) আহ্বান করা হবে, যা উপ-অ্যারে'র সমান () পদ্ধতিগুলি বলে
মাইকেল বর্গওয়ার্ট

0
import java.util.Arrays;
public class ArrayDemo {
   public static void main(String[] args) {
   // initializing three object arrays
   Object[] array1 = new Object[] { 1, 123 };
   Object[] array2 = new Object[] { 1, 123, 22, 4 };
   Object[] array3 = new Object[] { 1, 123 };

   // comparing array1 and array2
   boolean retval=Arrays.equals(array1, array2);
   System.out.println("array1 and array2 equal: " + retval);
   System.out.println("array1 and array2 equal: " + array1.equals(array2));

   // comparing array1 and array3
   boolean retval2=Arrays.equals(array1, array3);
   System.out.println("array1 and array3 equal: " + retval2);
   System.out.println("array1 and array3 equal: " + array1.equals(array3));

   }
}

এখানে ফলাফল:

    array1 and array2 equal: false
    array1 and array2 equal: false

    array1 and array3 equal: true
    array1 and array3 equal: false

এই ধরণের সমস্যা দেখে আমি ব্যক্তিগতভাবে Arrays.equals(array1, array2)আপনার প্রশ্ন অনুসারে বিভ্রান্তি এড়াতে যাব ।


এটি সঠিক বলে মনে হচ্ছে তবে অ্যারেগুলিতে উপাদানগুলির ক্রমটিও গুরুত্বপূর্ণ। উদাহরণস্বরূপ, যদি আপনি অন্য অ্যারে অবজেক্ট [] অ্যারে 4 = নতুন অবজেক্ট [] {123, 1 is; Arrays.equals (অ্যারে 3, অ্যারে 4) দিয়ে এটি মিথ্যা ফিরে আসবে।
jiahao
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.