How to Copy an Array in Java - Baeldung

文章推薦指數: 80 %
投票人數:10人

Let's start with the core Java library, System.arrayCopy(). This copies an array from a source array to a destination array, starting the ... StartHereCourses ▼▲ RESTwithSpring ThecanonicalreferenceforbuildingaproductiongradeAPIwithSpring LearnSpringSecurity ▼▲ THEuniqueSpringSecurityeducationifyou’reworkingwithJavatoday LearnSpringSecurityCore FocusontheCoreofSpringSecurity5 LearnSpringSecurityOAuth FocusonthenewOAuth2stackinSpringSecurity5 LearnSpring Fromnoexperiencetoactuallybuildingstuff​ LearnSpringDataJPA ThefullguidetopersistencewithSpringDataJPA Guides ▼▲ Persistence ThePersistencewithSpringguides REST TheguidesonbuildingRESTAPIswithSpring Security TheSpringSecurityguides About ▼▲ FullArchive Thehighleveloverviewofallthearticlesonthesite. BaeldungEbooks DiscoverallofoureBooks WriteforBaeldung Becomeawriteronthesite AboutBaeldung AboutBaeldung. JavaTop GetstartedwithSpring5andSpringBoot2,throughtheLearnSpringcourse: >CHECKOUTTHECOURSE 1.Overview Inthisquicktutorial,we’lldiscussthedifferentarraycopyingmethodsinJava.Arraycopyingmayseemlikeatrivialtask,butitcancauseunexpectedresultsandprogrambehaviorsifnotdonecarefully. 2.TheSystemClass Let'sstartwiththecoreJavalibrary,System.arrayCopy().Thiscopiesanarrayfromasourcearraytoadestinationarray,startingthecopyactionfromthesourcepositiontothetargetpositionuntilthespecifiedlength. Thenumberofelementscopiedtothetargetarrayequalsthespecifiedlength.Itprovidesaneasywaytocopyasub-sequenceofanarraytoanother. Ifanyofthearrayargumentsisnull,itthrowsaNullPointerException.Ifanyoftheintegerargumentsisnegativeoroutofrange,itthrowsanIndexOutOfBoundException. Let’slookatanexampleofcopyingafullarraytoanotherusingthejava.util.Systemclass: int[]array={23,43,55}; int[]copiedArray=newint[3]; System.arraycopy(array,0,copiedArray,0,3); Thismethodtakesthefollowingarguments:asourcearray,thestartingpositiontocopyfromthesourcearray,adestinationarray,thestartingpositioninthedestinationarray,andthenumberofelementstobecopied. Let'slookatanotherexampleofcopyingasub-sequencefromasourcearraytoadestination: int[]array={23,43,55,12,65,88,92}; int[]copiedArray=newint[3]; System.arraycopy(array,2,copiedArray,0,3); assertTrue(3==copiedArray.length); assertTrue(copiedArray[0]==array[2]); assertTrue(copiedArray[1]==array[3]); assertTrue(copiedArray[2]==array[4]); 3.TheArraysClass TheArraysclassalsooffersmultipleoverloadedmethodstocopyanarraytoanother.Internally,itusesthesameapproachprovidedbytheSystemclassthatwepreviouslyexamined.Itmainlyprovidestwomethods,copyOf(…)andcopyRangeOf(…). Let'slookatcopyOffirst: int[]array={23,43,55,12}; intnewLength=array.length; int[]copiedArray=Arrays.copyOf(array,newLength); It'simportanttonotethattheArraysclassusesMath.min(…)forselectingtheminimumofthesourcearraylength,andthevalueofthenewlengthparametertodeterminethesizeoftheresultingarray. Arrays.copyOfRange()takes2parameters,‘from'and‘to',inadditiontothesourcearrayparameter.Theresultingarrayincludesthe‘from'index,butthe‘to'indexisexcluded: int[]array={23,43,55,12,65,88,92}; int[]copiedArray=Arrays.copyOfRange(array,1,4); assertTrue(3==copiedArray.length); assertTrue(copiedArray[0]==array[1]); assertTrue(copiedArray[1]==array[2]); assertTrue(copiedArray[2]==array[3]); Bothofthesemethodsdoashallowcopyofobjectsifappliedonanarrayofnon-primitiveobjecttypes: Employee[]copiedArray=Arrays.copyOf(employees,employees.length); employees[0].setName(employees[0].getName()+"_Changed"); assertArrayEquals(copiedArray,array); Becausetheresultisashallowcopy,thechangeintheemployeenameoftheelementoftheoriginalarraycausedthechangeinthecopyarray. Ifwewanttodoadeepcopyofnon-primitivetypes,wecanoptforoneoftheotheroptionsdescribedintheupcomingsections. 4.ArrayCopyWithObject.clone() Object.clone()isinheritedfromtheObjectclassinanarray. First,we'llcopyanarrayofprimitivetypesusingtheclonemethod: int[]array={23,43,55,12}; int[]copiedArray=array.clone(); Here'sproofthatitworks: assertArrayEquals(copiedArray,array); array[0]=9; assertTrue(copiedArray[0]!=array[0]); Theaboveexampleshowstheyhavethesamecontentaftercloning,buttheyholddifferentreferences,soanychangeinoneofthemwon'taffecttheotherone. Ontheotherhand,ifwecloneanarrayofnon-primitivetypesusingthesamemethod,thentheresultswillbedifferent. Itcreatesashallowcopyofthenon-primitivetypearrayelements,eveniftheenclosedobject'sclassimplementstheCloneableinterfaceandoverridestheclone()methodfromtheObjectclass. Let'shavealookatanexample: publicclassAddressimplementsCloneable{ //... @Override protectedObjectclone()throwsCloneNotSupportedException{ super.clone(); Addressaddress=newAddress(); address.setCity(this.city); returnaddress; } } Wecantestourimplementationbycreatinganewarrayofaddresses,andinvokingourclone()method: Address[]addresses=createAddressArray(); Address[]copiedArray=addresses.clone(); addresses[0].setCity(addresses[0].getCity()+"_Changed"); assertArrayEquals(copiedArray,addresses); Thisexampleshowsthatanychangeintheoriginalorcopiedarraywillcauseachangeintheotherone,evenwhentheenclosedobjectsareCloneable. 5.UsingtheStreamAPI Asitturnsout,wecanusetheStreamAPIforcopyingarraystoo: String[]strArray={"orange","red","green'"}; String[]copiedArray=Arrays.stream(strArray).toArray(String[]::new); Forthenon-primitivetypes,it'llalsodoashallowcopyofobjects.TolearnmoreaboutJava8Streams,wecanstarthere. 6.ExternalLibraries ApacheCommons3offersautilityclasscalledSerializationUtils,whichprovidesaclone(…)method.It'sveryusefulifweneedtodoadeepcopyofanarrayofnon-primitivetypes.Itcanbedownloadedhere,anditsMavendependencyis: org.apache.commons commons-lang3 3.12.0 Let'shavealookatatestcase: publicclassEmployeeimplementsSerializable{ //fields //standardgettersandsetters } Employee[]employees=createEmployeesArray(); Employee[]copiedArray=SerializationUtils.clone(employees); employees[0].setName(employees[0].getName()+"_Changed"); assertFalse( copiedArray[0].getName().equals(employees[0].getName())); ThisclassrequiresthateachobjectshouldimplementtheSerializableinterface.Intermsofperformance,it'sslowerthantheclonemethodswrittenmanuallyforeachoftheobjectsinourobjectgraphtocopy. 7.Conclusion Inthisarticle,wediscussedthevariousoptionstocopyanarrayinJava. Themethodwechoosetouseismainlydependentupontheexactscenario.Aslongaswe'reusingaprimitivetypearray,wecanuseanyofthemethodsofferedbytheSystemandArraysclasses.Thereshouldn'tbeanydifferenceinperformance. Fornon-primitivetypes,ifweneedtodoadeepcopyofanarray,wecaneitherusetheSerializationUtilsoraddclonemethodstoourclassesexplicitly. Asalways,theexamplesshowninthisarticleareavailableonoveronGitHub. Javabottom GetstartedwithSpring5andSpringBoot2,throughtheLearnSpringcourse: >>CHECKOUTTHECOURSE Genericfooterbanner LearningtobuildyourAPIwithSpring? DownloadtheE-book Commentsareclosedonthisarticle! Javasidebarbanner BuildingaRESTAPIwithSpring5? DownloadtheE-book Followthe Java Category FollowtheJavacategorytogetregularinfoaboutthenewarticlesandtutorialswepublishhere. FOLLOWTHEJAVACATEGORY



請為這篇文章評分?