Tải bản đầy đủ - 0 (trang)
Recipe 1.6 Automating hashCode( ) and equals( )

Recipe 1.6 Automating hashCode( ) and equals( )

Tải bản đầy đủ - 0trang

//Constructors-omittedforbrevity



//get/setmethods-omittedforbrevity



//AhashCodewhichcreatesahashfromthetwouniqueiden

publicinthashCode(){

returnnewHashCodeBuilder(17,37)

.append(firstName)

.append(lastName).toHashCode();

}



//Anequalswhichcomparestwouniqueidentifiers

publicbooleanequals(Objecto){

booleanequals=false;

if(o!=null&&

PoliticalCandidate.class.isAssignableFrom(o)){

PoliticalCandidatepc=(PoliticalCandidate)o;

equals=(newEqualsBuilder()



.append(firstName,ps.firstName)



.append(lastName,ps.lastName)).isEquals

}

returnequals;

}

}



Discussion

HashCodeBuilderhasaconstructorthattakestwointeger

primitives.Theseprimitivesareusedasanoffsetwhencreating

ahashcode;bothnumbersshouldbeodd,nonzero,andprime.

TheHashCodeBuilderinExample1-2isconfiguredtousethe

firstNameandthelastNameofthePoliticalCandidate

object;therefore,twoPoliticalCandidateobjectswiththe

samefirstandlastnamewillhaveidenticalhashcodes.Ifa

hashcodedependsoneveryfieldinaclass,youmayuse

reflectiontogenerateahashcode:

publicinthashCode(){

returnHashCodeBuilder.reflectionHashCode(this);

}



LikeToStringBuilderandHashCodeBuilder,the

EqualsBuilderisalsoconfiguredviaanappend()method,

whichtakestwoargumentstocompare.EqualsBuilder's

append()methodacceptsallprimitives,objects,andarrays,

andoneadvantageofEqualsBuilderistheabilitytocompare

twoarraysbysimplypassingthemtoappend().Whenthis

happens,EqualsBuildercompareseveryelementofanarray:

int[]array1=newint[]{1,3,4,2,5,3,4,5,3,4};

int[]array2=newint[]{1,3,4,2,5,3,4,5,3,4};

int[]array3=newint[]{3,3,3,3,3,3,3,3,3,3};



EqualsBuilderbuilder=newEqualsBuilder();

builder.append(array1,array2);

booleanfirstTwoEqual=builder.isEquals();



System.out.println("Isarray1equaltoarray2?"+firstTwoEqu



EqualsBuilderbuilder=newEqualsBuilder();

builder.append(array2,array3);

booleanlastTwoEqual=builder.isEquals();



System.out.println("Isarray2equaltoarray3?"+lastTwoEqua



TheEqualsBuildercomparesthecontentsoftwoarrays,



checkingtoseethatthecorrespondingelementisequal.The

followingoutputisproduced:

Isarray1equaltoarray2?true

Isarray2equaltoarray3?false



Iftwoclassesareequalonlyifeveryfieldisequal,the

EqualsBuildercancomparetwoobjectsusingreflectionasin

thefollowingcode:

publicbooleanequals(Objecto){

returnEqualsBuilder.reflectionEquals(this,o);

}



BecarefulwhenusingreflectiontoautomatehashCode()andequals(

),youmaygetmorethanyoubargainedfor.InExample1-2,a

candidateisuniquelyidentifiedbyfirstandlastname;ifthisbeanwere

mappedtoatableinarelationaldatabase,firstNameandlastName

wouldbeacompositekeyidentifyingeachuniquerow.AHashMapor

HashSetissimilartoadatabasetableinthattheidentifierisdefinedby

thefieldsusedbyhashCode()andequals();puttinganequalobject

withthesamehashcodeintoaHashMapreplacesthepreviousentry.A

poorlyimplementedhashCode()orequals()canhaveunintended

consequenceswhenstoringobjectsinsuchadatastructure.Inother

words,equals()andhashCode()shouldbebasedoffofthe

propertiesthatuniquelyidentifyaclass.Thisbeingthecase,the

equals()functionshouldreturntrueiftwoPoliticalCandidate

objectshaveidenticalfirstandlastnames,andthehashcodefortwo

equalobjectsshouldbeidentical.ThehashCode()andequals()in

Example1-2arewrittentoonlytakeintoaccountthefirstNameand

lastNameproperties.



Recipe1.7AutomatingcompareTo()

Problem

YouneedaquickwaytoimplementcompareTo()methods.



Solution

CommonsLangCompareToBuilderprovidesabuilderfor

compareTo()methods.CompareToBuildercanperforma

comparisonviareflection,oracomparisoncanbecustomized

bypassingparameterstoaninstanceofCompareToBuilder.

Thefollowingexampledemonstratestheuseofthereflection

buildertoimplementacompareTo()method.This

implementationcomparesallnonstaticandnontransient

membervariablesinbothclasses.

importorg.apache.commons.lang.builder.CompareToBuilder;



//BuildacompareTofunctionfromreflection

publicintcompareTo(Objecto){

returnCompareToBuilder.reflectionCompare(this,obj);

}



Discussion

CompareToBuilder.reflectionCompare()takestwoobjects

andcomparesthenon-static,nontransientmembervariablesof

theseobjects.InExample1-2,thecomparisoninvolvesthe

namepropertiesoftwoPoliticalCandidateobjectsfrom

Example1-3,whichareconsideredequalifbothfirstNameand

lastNameareequal.reflectionCompare()ignoresstatic

fieldsandtransients;therefore,inExample1-3,averageAge

andfullNamedonotcontributetotheautomatedcomparison.



Example1-3.ImplementingcompareTo()usinga

reflectionbuilder

publicclassPoliticalCandidate{



//Staticvariable

privatestaticStringaverageAge;



//Membervariables

privateStringfirstName;

privateStringlastName;

privatetransientStringfullName;



//Constructors



//get/setmethods



//BuildacompareTofunctionfromreflection

publicintcompareTo(Objecto){

returnCompareToBuilder.reflectionCompare(this,obj);

}

}



Inadditiontoacomparisonbyreflection,the

CompareToBuildercanbeconfiguredtocomparetwoobjects

byasetofvariablesinaparticularorder.Theorderof

comparisonsplaysakeyrolewhenacomparisoninvolves

multiplemembervariables;thisorderisnotspecifiedwhen

usingthereflectionCompare()method.Assumethatthe

defaultsortingbehaviorforPoliticalCandidateobjectsshould

belastNameandthenfirstName;iftwoobjectshavethesame

lastName,thensortbythefirstName.Thefollowingexample

demonstratesacustomizationofthecompareTo()method.

Callingappend()specifieswhatvariableswillbecomparedand

inwhatordertheywillbecompared.Theorderofthecallsto

append()arebackwardsimilartopushinganobjectontothe

topofastack.Thelastproperty"pushed"ontothe

CompareToBuilderisthefirstpropertytobecompared.Objects

arecomparedbylastname,andfirstnameisusedasa



"tiebreaker."Example1-4willcomparetwo

PoliticalCandidateobjectsbylastName,fallingbackto

firstNameonlyifthelastNamevalueswereequal.



Example1-4.CustomizingacompareTo()

methodwithCompareToBuilder

//Acomparetothatmimicsthebehaviorofequals()

publicintcompareTo(Objecto){

intcompare=-1;//Bydefaultreturnless-than

if(o!=null&&



PoliticalCandidate.class.isAssignableFrom(o.getClass(

PoliticalCandidatepc=(PoliticalCandidate)o;

compare=(newCompareToBuilder()

.append(firstName,pc.firstName)



.append(lastName,pc.lastName)).toCom

}

returncompare;

}



Remembertokeepthebehaviorofequals()andcompareTo(

)consistenttoavoidproblemswhensortingcollections.



AutomatingthecompareTo()methodviareflectionmaynot

compareobjectsinawaythatisconsistentwithequals().



SeeAlso

compareTo()methodsprovidethenaturalsortingorderfora

setofobjects,andtheyarefrequentlyusedwhensortinga

collectionofJavaBeans©.Ifyouaretryingtosortacollectionof

beans,youarebetteroffusingtheBeanComparator,whichis

describedinRecipe3.10.

InsteadofcapturingcomparisonlogicinacompareTo()

method,considerusingaComparatorobject.TheJakarta

CommonsCollectionsprojectcontainsanumberofsupplements

totheComparatorinterface,suchasutilitiestoreverseand

chaincomparators.Comparatorutilitiesarediscussedin

Chapter4.



Recipe1.8PrintinganArray

Problem

Youneedtoprintthecontentsofanarray.



Solution

UseArrayUtils.toString()toprintthecontentsofanarray.

Thismethodtakesanyarrayasanargumentandprintsoutthe

contentsdelimitedbycommasandsurroundedbybrackets:

int[]intArray=newint[]{2,3,4,5,6};



int[]multiDimension=newint[][]{{1,2,3},{2,3},{5,



System.out.println("intArray:"+ArrayUtils.toString(intArra

System.out.println("multiDimension:"+ArrayUtils.

toString(multiDimension));



Thisexampletakestwoarraysandprintsthemoutusing

ArrayUtils.toString():

intArray:{2,3,4,5,6}



multiDimension:{{1,2,3},{2,3},{5,6,7}}



Discussion

Thissimpleutilitycanbeusedtoprintthecontentsofan

Object[],substitutinganobjectforanullelement:



String[]strings=newString[]{"Blue","Green",null,"Yello



System.out.println("Strings:"+ArrayUtils.toString(strings,



Thisexampleprintsthestringsarray,andwhenArrayUtils

encountersanullelement,itwillprintout"Unknown":

Strings:{Blue,Green,Unknown,Yellow}



Thisutilitycomesinhandywhenyouneedtoprintthecontents

ofaCollectionfordebuggingpurposes.Ifyouneedtoprint

outthecontentsofaCollection,convertittoanarray,and

passthatarraytoArrayUtils.toString():

Listlist=newArrayList();

list.add("Foo");

list.add("Blah");



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Recipe 1.6 Automating hashCode( ) and equals( )

Tải bản đầy đủ ngay(0 tr)

×