JavaRush /جاوا بلاگ /Random-SD /جاوا ۾ hashCode() ۽ equals() طريقن سان ڪم ڪرڻ
Lenchik854
سطح
Chernihiv

جاوا ۾ hashCode() ۽ equals() طريقن سان ڪم ڪرڻ

گروپ ۾ شايع ٿيل
هن پوسٽ ۾ آئون طريقن جي منهنجي سمجھ کي بيان ڪندس hashCode()۽ equals(). مان انهن جي ڊفالٽ عمل درآمد بابت ڳالهائڻ چاهيان ٿو، انهي سان گڏ انهن کي ڪيئن صحيح طريقي سان ختم ڪجي. آئون انهن طريقن کي لاڳو ڪرڻ بابت پڻ لکندس اپاچي عام پيڪيج جي مددگار طبقن کي استعمال ڪندي. جاوا ۾ hashCode() ۽ equals() طريقن سان ڪم ڪرڻ - 1هن پوسٽ جو مواد:
  1. استعمال ڪندي hashCode()۽ equals().
  2. ڊفالٽ رويي کي ختم ڪريو.
  3. اوور رائڊنگ hashCode()۽ equals()استعمال ڪندي Apache Commons Lang.
  4. ڪجهه ياد رکڻ ضروري آهي.
  5. خاص ڌيان جڏهن ORM استعمال ڪندي.
hashCode()۽ طريقن جي equals()وضاحت ڪئي وئي ڪلاس ۾ Object، جيڪا جاوا شين لاء والدين طبقي آهي. تنهن ڪري، سڀئي جاوا شيون انهن طريقن مان ڊفالٽ عمل درآمد ڪن ٿا.

استعمال ڪندي hashCode() ۽ equals()

اهو طريقو hashCode()استعمال ڪيو ويندو آهي هڪ ڏنل اعتراض لاء هڪ منفرد عدد نمبر حاصل ڪرڻ لاء. جڏهن هڪ شئي کي هش ٽيبل ۾ ڊيٽا جي ڍانچي جي طور تي ذخيرو ڪرڻ جي ضرورت آهي (جنهن کي بالٽ پڻ سڏيو ويندو آهي)، اهو نمبر استعمال ڪيو ويندو آهي ان جي جڳهه کي طئي ڪرڻ لاءِ ٽيبل ۾. ڊفالٽ طور، هڪ اعتراض جو طريقو hashCode()ميموري جي جڳهه جو تعداد واپس ڏئي ٿو جتي اعتراض ذخيرو ٿيل آهي. طريقو equals()، جيئن ان جو نالو مشورو ڏئي ٿو، صرف ٻن شين جي برابري کي جانچڻ لاء استعمال ڪيو ويندو آهي. هن طريقي جو ڊفالٽ عمل صرف ٻن شين جي حوالن کي چيڪ ڪري ٿو ته اهي برابر آهن.

ڊفالٽ رويي کي ختم ڪرڻ

هر شي ٺيڪ ڪم ڪري ٿي جيستائين توهان پنهنجي ڪلاسن ۾ انهن طريقن مان ڪنهن کي اوور رائيڊ نه ڪيو. پر ڪڏهن ڪڏهن ايپليڪيشنن کي ڪجهه شين جي ڊفالٽ رويي کي تبديل ڪرڻ جي ضرورت آهي. اچو ته هڪ مثال وٺون جتي توهان وٽ آهي Employee. اچو ته اهڙي طبقي جي گهٽ ۾ گهٽ ممڪن جوڙجڪ لکون.
public class Employee
{
    private Integer id;
    private String firstname;
    private String lastName;
    private String department;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getFirstname() {
        return firstname;
    }
    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getDepartment() {
        return department;
    }
    public void setDepartment(String department) {
        this.department = department;
    }
}
مٿي بيان ڪيل طبقي Employee۾ ڪي بنيادي خاصيتون ۽ رسيور طريقا آهن. هاڻي اچو ته هڪ سادي صورتحال تي نظر رکون جتي اسان کي ڪلاس جي ٻن شين جو مقابلو ڪرڻو پوندو Employee.
public class EqualsTest {
    public static void main(String[] args) {
        Employee e1 = new Employee();
        Employee e2 = new Employee();

        e1.setId(100);
        e2.setId(100);
        //Печатает false в консоли
        System.out.println(e1.equals(e2));
    }
}
اهو اندازو ڪرڻ لاءِ ڪو دعويدار نه آهي ته مٿي ڏنل طريقو ”غلط“ موٽندو. پر ڇا اهو اصل ۾ صحيح آهي، ڏنو ويو آهي ته اهي ٻه شيون ساڳيون آهن؟ حقيقي وقت جي ايپليڪيشن ۾، طريقو صحيح موٽڻ گهرجي. صحيح رويي کي حاصل ڪرڻ لاء، اسان کي equals()ھيٺ ڏنل طريقي کي ختم ڪرڻ جي ضرورت آھي.
public boolean equals(Object o) {
        if(o == null)
        {
            return false;
        }
        if (o == this)
        {
           return true;
        }
        if (getClass() != o.getClass())
        {
            return false;
        }
        Employee e = (Employee) o;
        return (this.getId() == e.getId());
}
ھن طريقي کي پنھنجي ڪلاس ۾ شامل ڪريو Employee۽ برابري جي چڪاس موٽندي ”سچو“. بهرحال، اسان سڀ ڪجهه ڪيو آهي؟ اڃا نه. اچو ته اسان جي تبديل ٿيل طبقي کي هڪ وڌيڪ طريقي سان جانچيون.
import java.util.HashSet;
import java.util.Set;

public class EqualsTest
{
    public static void main(String[] args)
    {
        Employee e1 = new Employee();
        Employee e2 = new Employee();

        e1.setId(100);
        e2.setId(100);

        //Печатает 'true'
        System.out.println(e1.equals(e2));

        Set employees = new HashSet();
        employees.add(e1);
        employees.add(e2);
        //Печатает два an object
        System.out.println(employees);
    }
}
حڪم System.out.println(employee)ٻن شين کي پرنٽ ڪري ٿو. جيڪڏهن ٻئي شيون برابر هيون، ۽ Setصرف منفرد شيون شامل آهن، پوء HashSetاتي صرف هڪ مثال هجڻ گهرجي، يعني. ٻئي شيون ڪلاس جي ساڳئي مثالن ڏانهن اشارو ڪن ٿا Employee. اسان ڇا وڃايو آهي؟ اسان ٻيو اهم طريقو وڃائي ڇڏيو hashCode(). جيئن ته جاوا دستاويز چوي ٿو، جيڪڏهن توهان طريقي سان اوور رائڊ ڪيو ٿا equals()، ته پوءِ توهان کي ضرورت آهي ته طريقي کي اوور رائڊ ڪريو hashCode(). سو اچو ته اسان جي ڪلاس ۾ ٻيو طريقو شامل ڪريون Employee.
@Override
 public int hashCode()
 {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + getId();
    return result;
 }
اسان هن طريقي کي هڪ ڀيرو اسان جي ڪلاس ۾ شامل ڪيو، ۽ صرف هڪ اعتراض پرنٽ ڪيو ويندو، ۽ اهڙيء طرح، e1 ۽ e2 جي برابري جي جانچ ڪرڻ صحيح ڏيکاري ٿي.

اوور رائڊنگ hashCode()۽ equals()استعمال ڪندي Apache Commons Lang

Apache Commons مهيا ڪري ٿو ٻه عظيم مددگار طبقن کي ڪال ڪرڻ جي طريقن hashCode()۽ equals(). هيٺ اسين استعمال ڏسون ٿا:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Employee
{
 private Integer id;
 private String firstname;
 private String lastName;
 private String department;
public Integer getId() {
    return id;
 }
 public void setId(Integer id) {
    this.id = id;
 }
 public String getFirstname() {
    return firstname;
 }
 public void setFirstname(String firstname) {
    this.firstname = firstname;
 }
 public String getLastName() {
    return lastName;
 }
 public void setLastName(String lastName) {
    this.lastName = lastName;
 }
 public String getDepartment() {
    return department;
 }
 public void setDepartment(String department) {
    this.department = department;
 }
@Override
 public int hashCode()
 {
    final int PRIME = 31;
    return new HashCodeBuilder(getId()%2==0?getId()+1:getId(), PRIME).
           toHashCode();
 }
@Override
 public boolean equals(Object o) {
    if (o == null)
       return false;
    if (o == this)
       return true;
    if (o.getClass() != getClass())
       return false;
    Employee e = (Employee) o;
       return new EqualsBuilder().
              append(getId(), e.getId()).
              isEquals();
    }
 }
ٻئي طرف، جيڪڏهن توهان ڪوڊ ايڊيٽرن مان هڪ استعمال ڪريو ٿا، انهن کي پڻ توهان جي لاء ڪجهه سٺيون اڏاوتون سڏڻ جي قابل هوندا. مثال طور، جيڪڏهن Eclipse IDE ۾ توهان class>> source> Generating hashCode() ۽ equals() تي صحيح ڪلڪ ڪريو ... اهو توهان لاءِ تمام سٺو عمل پيدا ڪندو. جاوا ۾ hashCode() ۽ equals() طريقن سان ڪم ڪرڻ - 2ڪجهه ياد رکڻ ضروري آهي.
  1. hashCode()ٻنهي ۽ ۽ کي سڏڻ لاءِ هميشه ساڳيون شيون استعمال ڪريو equals(). بس اسان جي صورت ۾، اسان استعمال ڪيو employee id.
  2. طريقو equals()مسلسل هجڻ گهرجي (جيڪڏهن اعتراض تبديل نه ڪيو ويو آهي، طريقو ساڳيو قدر واپس ڪرڻ گهرجي).
  3. جڏهن ته a.equals(b)، پوء a.hashCode()ساڳيو هجڻ گهرجي b.hashCode().
  4. جيڪڏھن توھان ھڪڙي طريقي کي ختم ڪريو ٿا، توھان کي ٻئي کي ختم ڪرڻ گھرجي.

خاص ڌيان جڏهن ORM استعمال ڪندي

جيڪڏهن توهان ORM (ru.wikipedia.org/wiki/ORM) سان ڪم ڪري رهيا آهيو، ته پوءِ هميشه getters استعمال ڪريو ۽ ڪڏهن به فيلڊ ريفرنس استعمال نه ڪريو hashCode(). equals()اهو ئي سبب آهي ته هڪ ORM ۾، وقت بوقت فيلڊز سست لوڊ استعمال ڪندي لوڊ ڪيا ويندا آهن ۽ رسائي نه هوندا آهن جيستائين انهن جي حاصل ڪندڙن کي سڏيو وڃي. مثال طور، اسان جي ڪلاس ۾ Employee، اسان استعمال ڪندا آهيون e1.id == e2.id. اهو مڪمل طور تي ممڪن آهي ته iڊي فيلڊس لوڊ ٿيل آهن سست لوڊ ڪندي استعمال ڪندي. فيلڊ مان ھڪڙو 0 يا null ٿي سگھي ٿو ۽ اسان کي غلط رويي ملندو. پر، جيڪڏهن استعمال ڪيو ويو آهي e1.getId() == e2.getId()، اسان پڪ ڪري سگهون ٿا جيتوڻيڪ فيلڊ سست لوڊ ڪندي لوڊ ڪيو ويو آهي؛ حاصل ڪندڙ کي سڏڻ پهرين فيلڊ کي آباد ڪندو. اهو سڀ ڪجهه آئون ڄاڻان ٿو hashCode()۽ طريقن بابت equals(). اميد آهي ته هي ڪنهن جي مدد ڪري ٿي. توهان جي پڙهائي سان سٺي قسمت !! پي ايس ترجمي ۾ منهنجي پهرين ڪوشش آهي. مون ڪوشش ڪئي ته هر شيءِ کي جيترو ممڪن ٿي سگهي ويجهو پهچايو وڃي ته ليکڪ ڇا چوڻ چاهي ٿو. جيڪڏهن توهان وٽ ڪي رايا آهن، مهرباني ڪري تبصرن ۾ لکندا. سختي سان فيصلو نه ڪريو :-))) اصل مضمون
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION