অ্যাপাচি কমন্স সমান / হ্যাশকোড নির্মাতা [বন্ধ]


155

আমি জানতে আগ্রহী, এখানকার লোকেরা org.apache.commons.lang.builder EqualsBuilder/ HashCodeBuilder প্রয়োগের জন্য equals/ ব্যবহার সম্পর্কে কী ভাবেন hashCode? এটি নিজের লেখার চেয়ে ভাল অনুশীলন হবে? এটি কি হাইবারনেটের সাথে ভাল খেলে? তোমার মতামত কি?


16
শুধু reflectionEqualsএবং reflectionHashcodeকার্য দ্বারা প্রলোভিত না হন ; কর্মক্ষমতা একটি পরম ঘাতক।
স্কাফম্যান

14
আমি গতকাল সমান সম্পর্কে এখানে কিছু আলোচনা দেখেছি এবং কিছুটা ফ্রি সময় পেয়েছি, তাই আমি একটি দ্রুত পরীক্ষা করেছি did আমার কাছে বিভিন্ন সমান বাস্তবায়ন সহ 4 টি অবজেক্ট ছিল। গ্রহনটি উত্পন্ন, সমতুল্য বিল্ডার.অ্যাপেন্ড, সমতুল্য বিল্ডার.প্রকাশ এবং পোজোমেটিক টিকা। বেসলাইনটি ছিল গ্রহন। equalsbuilder.append 3.7x নিয়েছে। পোজোমেটিক 5x নিয়েছে। প্রতিবিম্ব ভিত্তিক 25.8x নিয়েছে। এটি বেশ নিরুৎসাহজনক ছিল কারণ আমি প্রতিফলনের উপর ভিত্তি করে সরলতা পছন্দ করি এবং আমি "পোজোমেটিক" নামটি দাঁড়াতে পারি না।
ডিজিটালজেল

5
আরেকটি বিকল্প হ'ল প্রকল্প লম্বোক; এটি প্রতিবিম্বের পরিবর্তে বাইকোড জেনারেশন ব্যবহার করে তাই এটি গ্রহ-উত্পন্ন উত্সের পাশাপাশি সম্পাদন করা উচিত। প্রোজেক্টলম্বোক.আর.এফএচারস
মাইলস

উত্তর:


212

কমন্স / ল্যাং বিল্ডাররা দুর্দান্ত এবং আমি বছরের পর বছর ধরে এগুলি ব্যবহারযোগ্য পারফরম্যান্স ওভারহেড ছাড়াই (হাইবারনেট সহ এবং না) ব্যবহার করে আসছি। তবে আলাইন যেমন লিখেছেন, পেয়ারা পথটি আরও সুন্দর:

এখানে বিনের একটি নমুনা দেওয়া হয়েছে:

public class Bean{

    private String name;
    private int length;
    private List<Bean> children;

}

কমন্স / ল্যাং এর সাথে এখানে সমান () এবং হ্যাশকোড () প্রয়োগ করা হয়েছে:

@Override
public int hashCode(){
    return new HashCodeBuilder()
        .append(name)
        .append(length)
        .append(children)
        .toHashCode();
}

@Override
public boolean equals(final Object obj){
    if(obj instanceof Bean){
        final Bean other = (Bean) obj;
        return new EqualsBuilder()
            .append(name, other.name)
            .append(length, other.length)
            .append(children, other.children)
            .isEquals();
    } else{
        return false;
    }
}

এবং এখানে জাভা 7 বা উচ্চতর (পেয়ারা দ্বারা অনুপ্রাণিত) সহ:

@Override
public int hashCode(){
    return Objects.hash(name, length, children);
}

@Override
public boolean equals(final Object obj){
    if(obj instanceof Bean){
        final Bean other = (Bean) obj;
        return Objects.equals(name, other.name)
            && length == other.length // special handling for primitives
            && Objects.equals(children, other.children);
    } else{
        return false;
    }
}

দ্রষ্টব্য: এই কোডটি মূলত পেয়ারা রেফারেন্স করেছে, কিন্তু মতামত হিসাবে উল্লেখ করা হয়েছে যে, এই কার্যকারিতাটি তখন থেকে জেডিকে-তে প্রবর্তিত হয়েছে, সুতরাং পেয়ারা আর প্রয়োজন হয় না।

আপনি দেখতে পাচ্ছেন পেয়ারা / জেডি কে সংস্করণটি ছোট এবং অতিরিক্ত অতিরিক্ত সহায়ক সামগ্রীগুলি এড়িয়ে চলে। সমতার ক্ষেত্রে এটি এমনকি মূল্যায়ন শর্ট সার্কিট করার অনুমতি দেয় যদি পূর্ববর্তী Object.equals()কলটি মিথ্যা বলে প্রত্যাবর্তন করে (ন্যায্য হতে পারে: কমন্স / ল্যাং এর ObjectUtils.equals(obj1, obj2)সাথে অভিন্ন শব্দার্থবিজ্ঞানের একটি পদ্ধতি রয়েছে যা EqualsBuilderউপরের মতো শর্ট সার্কিটের অনুমতি দেওয়ার পরিবর্তে ব্যবহার করা যেতে পারে )।

সুতরাং: হ্যাঁ, কমন্স ল্যাং বিল্ডাররা ম্যানুয়ালি নির্মিত equals()এবং hashCode()পদ্ধতিগুলির তুলনায় খুব পছন্দনীয় (বা সেই ভয়ঙ্কর দানবগ্রহণ আপনার জন্য গ্রহন করবে) তবে জাভা 7+ / গুয়ারা সংস্করণগুলি আরও ভাল।

এবং হাইবারনেট সম্পর্কে একটি নোট:

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


দ্রষ্টব্য (সমান (সম্পর্কে)):

ক) উপরের সমান উভয় সংস্করণে (), আপনি এই শর্টকাটগুলির একটি বা উভয় ব্যবহার করতে চাইতে পারেন:

@Override
public boolean equals(final Object obj){
    if(obj == this) return true;  // test for reference equality
    if(obj == null) return false; // test for null
    // continue as above

খ) সমান () চুক্তির আপনার ব্যাখ্যার উপর নির্ভর করে আপনি লাইনও পরিবর্তন করতে পারেন

    if(obj instanceof Bean){

প্রতি

    // make sure you run a null check before this
    if(obj.getClass() == getClass()){ 

আপনি যদি দ্বিতীয় সংস্করণ ব্যবহার করেন তবে আপনি সম্ভবত super(equals())আপনার equals()পদ্ধতির অভ্যন্তরে কল করতে চান । মতামত এখানে পৃথক, এই প্রশ্নে বিষয়টি আলোচনা করা হয়:

একটি পেয়ারা অবজেক্টস.হ্যাশকোড () বাস্তবায়নে সুপারক্লাসকে যুক্ত করার সঠিক উপায়?

(যদিও এটি প্রায় hashCode(), একই ক্ষেত্রে প্রযোজ্য equals())


দ্রষ্টব্য ( কায়াহারের মন্তব্য দ্বারা অনুপ্রাণিত )

Objects.hashCode(..)(ঠিক যেমন অন্তর্নিহিত Arrays.hashCode(...)) খারাপ কাজ করতে পারে আপনার যদি অনেক আদিম ক্ষেত্র থাকে। এই ধরনের ক্ষেত্রে, EqualsBuilderআসলে ভাল সমাধান হতে পারে।


34
জাভা 7 অবজেক্টস.ওয়াক্যালের সাথে একই হবে: download.oracle.com/javase/7/docs/api/java/util/…
থমাস জং

3
আমি যদি এটি সঠিকভাবে পড়ছি, জোশ ব্লচ কার্যকর জাভাতে , আইটেম 8-তে বলেছেন যে আপনার সমতুল্য () পদ্ধতিতে আপনার getClass () ব্যবহার করা উচিত নয়; বরং আপনার উদাহরণ ব্যবহার করা উচিত।
জেফ ওলসন

6
@ সানপ্যাট্রিকফ্লোয়েড পেয়ারা পথটি কেবল ভারাজদের জন্য একটি অ্যারে অবজেক্ট তৈরি করে না, এটি সমস্ত পরামিতিগুলিকেও বস্তুতে রূপান্তরিত করে। সুতরাং আপনি যখন এটিতে 10 টি মান মান পাস করেন তখন আপনি 10 পূর্ণসংখ্যার অবজেক্ট এবং একটি অ্যারে অবজেক্টের সাথে সমাপ্ত হন। কমন্স-ল্যাং সমাধানটি কেবলমাত্র একটি একক অবজেক্ট তৈরি করে, আপনি হ্যাশ কোডটিতে কতগুলি মান যুক্ত করেন তা বিবেচনা করেই। একই সমস্যা equals। পেয়ারা সমস্ত মানকে বস্তুতে রূপান্তর করে, কমন্স-ল্যাং কেবল একটি একক নতুন অবজেক্ট তৈরি করে।
কায়াহর

1
@ ওহেহে আমি দৃ strongly়ভাবে একমত নই যে এটি আরও ভাল। হ্যাশ কোড গণনা করার জন্য প্রতিবিম্ব ব্যবহার করা এমন কিছু নয় যা আমি কখনও করতাম। ওভারহেডের পারফরম্যান্স সম্ভবত উপেক্ষিত, তবে এটি কেবল ভুল অনুভব করে।
শন প্যাট্রিক ফ্লয়েড

1
@ কৌশিক একটি ক্লাস ফাইনাল করা আসলে উভয় সংস্করণের সম্ভাব্য সমস্যাগুলি সমাধান করে (উদাহরণস্বরূপ এবং গেটক্লাস ()), যতক্ষণ আপনি কেবল পাতার ক্লাসে আপনার সমান () প্রয়োগ করেন না
সান প্যাট্রিক ফ্লয়েড

18

ভাবী, জাগো! জাভা 7 যেহেতু স্ট্যান্ডার্ড লাইব্রেরিতে সমান এবং হ্যাশকোডের জন্য সহায়ক পদ্ধতি রয়েছে । তাদের ব্যবহার পুরোপুরি পেয়ারা পদ্ধতি ব্যবহারের সমতুল্য।


ক) এই প্রশ্নটি জিজ্ঞাসা করার সময়, জাভা 7 এখনও ছিল না খ) প্রযুক্তিগতভাবে, তারা যথেষ্ট সমতুল্য নয়। jdk এর পেয়ার অবজেক্টস.একোয়াল পদ্ধতি বনাম Objects.equals পদ্ধতি রয়েছে। আমি কেবল পেয়ারার সংস্করণ দিয়ে স্থিতিশীল আমদানি ব্যবহার করতে পারি। এটি কেবল প্রসাধনী, আমি জানি, তবে এটি অ-পেয়ারা লক্ষণীয়ভাবে আরও বিশৃঙ্খল করে তোলে।
সান প্যাট্রিক ফ্লয়েড

অবজেক্টস.এককালালস দৃষ্টান্তের .equals পদ্ধতিতে কল করবে এই কারণে যে কোনও বস্তুর সমান পদ্ধতিটি ওভাররাইড করার জন্য এটি একটি ভাল পদ্ধতি নয়। আপনি যদি উদাহরণটির .aquals পদ্ধতির মধ্যে অবজেক্টস.এক.এল.কে কল করেন তবে এটি স্ট্যাকের ওভারফ্লোতে পরিচালিত হবে।
দারদো

আপনি একটি উদাহরণ দিতে পারেন, যখন এটি লুপে পড়ে?
মিখাইল গোলুবতসভ

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

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

8

আপনি যদি কোনও তৃতীয় পক্ষের লাইব্রেরির উপর নির্ভর করতে না চান (সম্ভবত আপনি সীমিত সংস্থান দিয়ে কোনও ডিভাইস চালাচ্ছেন) এবং আপনি নিজের পদ্ধতিগুলিও টাইপ করতে চান না, আপনি আইডিইকে কাজটিও করতে দিতে পারেন, যেমন গ্রহন ব্যবহারের ক্ষেত্রে

Source -> Generate hashCode() and equals()...

আপনি 'নেটিভ' কোড যা আপনি পাবেন পারবেন মত আপনি কনফিগার যা আপনি করতে হবে পরিবর্তন সমর্থন।


উদাহরণ (গ্রহণ জুনো):

import java.util.Arrays;
import java.util.List;

public class FooBar {

    public String string;
    public List<String> stringList;
    public String[] stringArray;

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((string == null) ? 0 : string.hashCode());
        result = prime * result + Arrays.hashCode(stringArray);
        result = prime * result
                + ((stringList == null) ? 0 : stringList.hashCode());
        return result;
    }
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        FooBar other = (FooBar) obj;
        if (string == null) {
            if (other.string != null)
                return false;
        } else if (!string.equals(other.string))
            return false;
        if (!Arrays.equals(stringArray, other.stringArray))
            return false;
        if (stringList == null) {
            if (other.stringList != null)
                return false;
        } else if (!stringList.equals(other.stringList))
            return false;
        return true;
    }

}

14
সত্য, তবে Eclipse দ্বারা উত্পন্ন কোডটি অপঠনযোগ্য এবং অকল্পনীয়।
শান প্যাট্রিক ফ্লয়েড

6
অনুগ্রহ করে, কখনও গ্রহনক্ষেত্র দ্বারা উত্পাদিত হিসাবে ভয়ানক কিছু সম্পর্কে কখনও চিন্তা করবেন না equals। আপনি যদি তৃতীয় পক্ষের গ্রন্থাগারের উপর নির্ভর করতে না চান, তবে Objects.equalনিজের মতো এক-লাইন পদ্ধতিটি লিখুন । এমনকি একবার বা দু'বার ব্যবহার করার পরেও কোড কোডটি আরও উন্নত করে!
মার্টিনাস

@ মাআর্টিনাস equals/ hashCodeএক লাইন পদ্ধতি ???
FrVaBe

1
@ মাআর্টিনাস পেয়ারা একটি তৃতীয় পক্ষের গ্রন্থাগার। আমি উল্লেখ করেছি যে আপনি যদি তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করে অ্যাভিড করতে চান তবে আমার সমাধানটি ব্যবহার করা যেতে পারে।
FrVaBe

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

6

ইক্যুয়ালসিল্ডার এবং হ্যাশকোডবিল্ডারের দুটি প্রধান দিক রয়েছে যা ম্যানুয়ালি লিখিত কোড থেকে আলাদা:

  • নাল হ্যান্ডলিং
  • উদাহরণ সৃষ্টি

ইক্যুয়ালসিল্ডার এবং হ্যাশকোডবিল্ডার শূন্য হতে পারে এমন ক্ষেত্রগুলির তুলনা করা আরও সহজ করে। ম্যানুয়ালি কোডিন কোড দিয়ে এটি প্রচুর বয়লারপ্লেট তৈরি করে।

অন্যদিকে ইকুয়ালস বিল্ডার সমান পদ্ধতি কলের জন্য একটি উদাহরণ তৈরি করবে। যদি আপনার সমান পদ্ধতিগুলি প্রায়শই কল করা হয় তবে এটি প্রচুর উদাহরণ তৈরি করবে create

হাইবারনেটের জন্য সমান এবং হ্যাশকোড বাস্তবায়ন কোনও পার্থক্য রাখে না। এগুলি কেবল একটি বাস্তবায়ন বিশদ। হাইবারনেট দিয়ে লোড প্রায় সমস্ত ডোমেন অবজেক্টের জন্য বিল্ডারের রানটাইম ওভারহেড (এমনকি অব্যাহতি বিশ্লেষণ ব্যতীত) উপেক্ষা করা যায় । ডাটাবেস এবং যোগাযোগ ওভারহেড তাৎপর্যপূর্ণ হবে।

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


আমি একমত নই যে প্রতিফলন বাস্তবায়ন "সহজ শ্রেণীর ব্যতীত সকলের পক্ষে সঠিক হবে না।" আপনি যদি চান তবে নির্মাতাদের সাথে আপনি ক্ষেত্রগুলি স্পষ্টভাবে বাদ দিতে পারেন, তাই বাস্তবায়নটি আপনার ব্যবসায়ের কী সংজ্ঞায় নির্ভর করে। দুর্ভাগ্যক্রমে, আমি প্রতিফলন ভিত্তিক বাস্তবায়নের পারফরম্যান্স দিকটির সাথে একমত হতে পারি না।
ডিজিটালজেল

1
@ ডিজিটালজোয়েল হ্যাঁ, আপনি ক্ষেত্রগুলি বাদ দিতে পারেন, তবে এই সংজ্ঞাগুলি সেভ রিফ্যাক্টরিং করছে না। সুতরাং আমি উদ্দেশ্য হিসাবে তাদের উল্লেখ না।
থমাস জঙ্গ


0

যদি আপনি কেবল আইটি প্রাথমিক কী হিসাবে সত্তার শিমের সাথে কাজ করে থাকেন তবে আপনি সহজ করতে পারেন।

   @Override
   public boolean equals(Object other)
   {
      if (this == other) { return true; }
      if ((other == null) || (other.getClass() != this.getClass())) { return false; }

      EntityBean castOther = (EntityBean) other;
      return new EqualsBuilder().append(this.getId(), castOther.getId()).isEquals();
   }

0

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

হ্যাশকোড () এবং সমান () ব্যবহার করার জন্য তাদের দুটি প্রধান দৃশ্যকল্প হ'ল:

  • আপনি যখন একটি সেটে অবিচ্ছিন্ন ক্লাসগুলির উদাহরণ রাখেন (বহু-মূল্যবান সংঘগুলি উপস্থাপনের প্রস্তাবিত উপায়) এবং
  • যখন আপনি বিচ্ছিন্ন দৃষ্টান্তগুলির পুনরায় সংযুক্তি ব্যবহার করেন

সুতরাং আসুন ধরে নেওয়া যাক আমাদের সত্তাটি এর মতো দেখাচ্ছে:

class Entity {
  protected Long id;
  protected String someProp;
  public Entity(Long id, String someProp);
}

Entity entity1 = new Entity(1, "a");
Entity entity2 = new Entity(1, "b");

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

  1. আপনি যখন সত্তা 2 ইতিমধ্যে উপস্থিত রয়েছে এমন অবিচ্ছিন্ন সেটটিতে রাখেন, এটি দু'বার রাখা হবে এবং প্রতিশ্রুতি দেওয়ার সময় ব্যতিক্রম হবে।
  2. আপনি যদি সেশনে বিচ্ছিন্ন সত্তা 2 সংযুক্ত করতে চান, যেখানে সত্তা 1 ইতিমধ্যে উপস্থিত রয়েছে তারা (সম্ভবত, আমি এটি বিশেষভাবে পরীক্ষা করিনি) সঠিকভাবে মার্জ হবে না।

সুতরাং, আমি যে 99% প্রকল্পটি করি তার জন্য, আমরা বেস সত্তা শ্রেণিতে একবার লিখিত সমান () এবং হ্যাশকোড () ব্যবহার করে যা হাইবারনেট ধারণার সাথে সামঞ্জস্যপূর্ণ:

@Override
public boolean equals(Object obj) {
    if (StringUtils.isEmpty(id))
        return super.equals(obj);

    return getClass().isInstance(obj) && id.equals(((IDomain) obj).getId());
}

@Override
public int hashCode() {
    return StringUtils.isEmpty(id)
        ? super.hashCode()
        : String.format("%s/%s", getClass().getSimpleName(), getId()).hashCode();
}

ক্ষণস্থায়ী সত্তার জন্য আমি হায়ਬਰনেট অধ্যবসায়ের পদক্ষেপে যা করবে তা হ'ল তাই। আমি উদাহরণ ম্যাচ ব্যবহার। অবিরাম অবজেক্টের জন্য আমি অনন্য কীটি তুলনা করি, যা হ'ল টেবিল / আইডি (আমি কখনই সম্মিলিত কী ব্যবহার করি না)।


0

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

ব্যবহারের উদাহরণ:

public int hashCode() {
    return HashCode.hash(HashCode.hash(timestampMillis), name, dateOfBirth); // timestampMillis is long
}

public int hashCode() {
    return HashCode.hash(super.hashCode(), occupation, children);
}

হ্যাশকোড সহায়ক:

public class HashCode {

    public static int hash(Object o1, Object o2) {
        return add(Objects.hashCode(o1), o2);
    }

    public static int hash(Object o1, Object o2, Object o3) {
        return hash(Objects.hashCode(o1), o2, o3);
    }

    ...

    public static int hash(Object o1, Object o2, ..., Object o10) {
        return hash(Objects.hashCode(o1), o2, o3, ..., o10);
    }

    public static int hash(int initial, Object o1, Object o2) {
        return add(add(initial, o1), o2);
    }

    ...

    public static int hash(int initial, Object o1, Object o2, ... Object o10) {
        return add(... add(add(add(initial, o1), o2), o3) ..., o10);
    }

    public static int hash(long value) {
        return (int) (value ^ (value >>> 32));
    }

    public static int hash(int initial, long value) {
        return add(initial, hash(value));
    }

    private static int add(int accumulator, Object o) {
        return 31 * accumulator + Objects.hashCode(o);
    }
}

আমি বুঝতে পেরেছি যে একটি ডোমেন মডেলের 10 টি সর্বোচ্চ যুক্তিসঙ্গত সংখ্যার বৈশিষ্ট্য, আপনার যদি আরও বেশি থাকে তবে আপনার স্ট্রিংস এবং আদিম গুণাগুলির রক্ষণাবেক্ষণের পরিবর্তে আরও ক্লাস চালু করার এবং আরও ক্লাস চালু করার কথা ভাবা উচিত।

ত্রুটিগুলি হ'ল: আপনার যদি প্রাথমিকভাবে আদিম এবং / অথবা অ্যারেগুলি রয়েছে যা আপনাকে গভীরভাবে হ্যাশ করতে হবে তবে এটি কার্যকর নয়। (সাধারণত আপনার ক্ষেত্রে নিয়ন্ত্রণের বাইরে থাকা ফ্ল্যাট (ট্রান্সফার) অবজেক্টগুলির সাথে ডিল করতে হয় এমন ক্ষেত্রে এটি হয়)।

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