Versjonssammenligning i Java

1. Oversikt

Med utviklingen av DevOps-teknologier er det vanlig å bygge og distribuere en applikasjon flere ganger på en dag.

Derfor, hver build tildeles et unikt versjonsnummer slik at vi kan skille mellom builds. Noen ganger oppstår et behov for å sammenligne versjonstrengene programmatisk.

I denne artikkelen vil vi utforske noen måter å sammenligne versjonstrenger i Java gjennom forskjellige biblioteker. Til slutt vil vi skrive et tilpasset program for å håndtere generisk versjon-streng sammenligning.

2. Bruke maven-artefakt

Til å begynne med, la oss undersøke hvordan Maven håndterer versjonssammenligning.

2.1. Maven avhengighet

Først legger vi til det siste maven-artefakt Maven avhengighet til vår pom.xml:

 org.apache.maven maven-artifact 3.6.3 

2.2. ComparableVersion

La oss utforske ComparableVersion klasse. Det gir en generisk implementering av versjonssammenligning med et ubegrenset antall versjonskomponenter.

Den inneholder en sammenligne med metode, og resultatet av sammenligningen vil være større enn eller mindre enn 0 når en versjon er henholdsvis større enn eller mindre enn den andre:

ComparableVersion version1_1 = ny ComparableVersion ("1.1"); ComparableVersion version1_2 = ny ComparableVersion ("1.2"); ComparableVersion version1_3 = ny ComparableVersion ("1.3"); assertTrue (version1_1.compareTo (version1_2) 0);

Her kan vi bekrefte at 1.1-versjonen er mindre enn 1.2-versjonen, og 1.3-versjonen er større enn 1.2-versjonen.

Imidlertid får vi 0 som resultat når vi sammenligner de samme versjonene:

ComparableVersion version1_1_0 = ny ComparableVersion ("1.1.0"); assertEquals (0, version1_1.compareTo (version1_1_0));

2.3. Versjonsskillere og kvalifiseringer

I tillegg har ComparableVersion klasse respekterer prikken (.) og bindestrek (-) som skilletegn, der dot skiller hoved- og mindreversjoner, og bindestreket definerer kvalifiseringskrav:

ComparableVersion version1_1_alpha = new ComparableVersion ("1.1-alpha"); assertTrue (version1_1.compareTo (version1_1_alpha)> 0);

Her kan vi bekrefte at 1.1-versjonen er større enn 1.1-alfa-versjonen.

Det er noen få kjente kvalifikasjoner som støttes av ComparableVersion som alfa, beta, milepæl, RC, og øyeblikksbilde (i rekkefølgen fra laveste til høyeste):

ComparableVersion version1_1_beta = ny ComparableVersion ("1.1-beta"); ComparableVersion version1_1_milestone = ny ComparableVersion ("1.1-milepæl"); ComparableVersion version1_1_rc = ny ComparableVersion ("1.1-rc"); ComparableVersion version1_1_snapshot = ny ComparableVersion ("1.1-øyeblikksbilde"); assertTrue (versjon1_1_alpha.compareTo (versjon1_1_beta) <0); assertTrue (version1_1_beta.compareTo (version1_1_milestone) <0); assertTrue (version1_1_rc.compareTo (version1_1_snapshot) <0); assertTrue (version1_1_snapshot.compareTo (version1_1) <0);

Også det tillater oss å definere ukjente kvalifiseringskilder og respekterer deres rekkefølge, etter de allerede omtalte kjente kvalifiseringskampene, med små og store bokstaver:

ComparableVersion version1_1_c = ny ComparableVersion ("1.1-c"); ComparableVersion version1_1_z = ny ComparableVersion ("1.1-z"); ComparableVersion version1_1_1 = ny ComparableVersion ("1.1.1"); assertTrue (version1_1_c.compareTo (version1_1_z) <0); assertTrue (version1_1_z.compareTo (version1_1_1) <0);

3. Bruke graderkjerne

I likhet med Maven har Gradle også den innebygde muligheten til å håndtere versjonssammenligning.

3.1. Maven avhengighet

La oss først legge til det siste graderkjerne Maven-avhengighet fra replikken Gradle Releases:

 org.gradle gradle-core 6.1.1 

3.2. Versjonsnummer

De Versjonsnummer klasse levert av Gradle sammenligner to versjoner, lik Mavens ComparableVersion klasse:

VersionNumber version1_1 = VersionNumber.parse ("1.1"); VersionNumber version1_2 = VersionNumber.parse ("1.2"); VersionNumber version1_3 = VersionNumber.parse ("1.3"); assertTrue (version1_1.compareTo (version1_2) 0); VersionNumber version1_1_0 = VersionNumber.parse ("1.1.0"); assertEquals (0, version1_1.compareTo (version1_1_0)); 

3.3. Versjonskomponenter

i motsetning til ComparableVersion klasse, den Versjonsnummer klasse støtter bare fem versjonskomponenter - Major, Liten, Micro, Lapp, og Kvalifisering:

VersionNumber version1_1_1_1_alpha = VersionNumber.parse ("1.1.1.1-alfa"); assertTrue (version1_1.compareTo (version1_1_1_1_alpha) <0); VersionNumber version1_1_beta = VersionNumber.parse ("1.1.0.0-beta"); assertTrue (version1_1_beta.compareTo (version1_1_1_1_alpha) <0);

3.4. Versjonsskjemaer

Også, Versjonsnummer støtter et par forskjellige versjonsordninger som Major.Minor.Micro-Qualifier og Major.Minor.Micro.Patch-kvalifisering:

VersionNumber version1_1_1_snapshot = VersionNumber.parse ("1.1.1-øyeblikksbilde"); assertTrue (versjon1_1_1_1_alpha.compareTo (versjon1_1_1_snapshot) <0);

4. Bruke jackson-core

4.1. Maven avhengighet

I likhet med andre avhengigheter, la oss legge til det siste jackson-core Maven avhengighet til vår pom.xml:

 com.fasterxml.jackson.core jackson-core 2.11.1 

4.2. Versjon

Deretter kan vi undersøke Jacksons Versjon klasse, som kan inneholde versjonsinformasjon for en komponent sammen med det valgfrie groupId og artefaktId verdier.

Derfor konstruktøren av Versjon klasse tillater oss å definere groupId og artefaktId, sammen med komponenter som Major, Liten, og Lapp:

public Version (int major, int minor, int patchLevel, String snapshotInfo, String groupId, String artifactId) {// ...}

Så, la oss sammenligne noen få versjoner ved hjelp av Versjon klasse:

Versjon versjon1_1 = ny versjon (1, 1, 0, null, null, null); Versjon versjon1_2 = ny versjon (1, 2, 0, null, null, null); Versjon versjon1_3 = ny versjon (1, 3, 0, null, null, null); assertTrue (version1_1.compareTo (version1_2) 0); Versjon versjon1_1_1 = ny versjon (1, 1, 1, null, null, null); assertTrue (version1_1.compareTo (version1_1_1) <0);

4.3. De øyeblikksbildeInfo Komponent

De øyeblikksbildeInfo komponenten brukes ikke mens man sammenligner to versjoner:

Versjon version1_1_snapshot = ny versjon (1, 1, 0, "øyeblikksbilde", null, null); assertEquals (0, version1_1.compareTo (version1_1_snapshot));

I tillegg har Versjon klasse gir isSnapshot metode for å sjekke om versjonen inneholder en øyeblikksbildekomponent:

assertTrue (versjon1_1_snapshot.isSnapshot ());

4.4. De groupId og artefaktId Komponenter

Også, denne klassen sammenligner den leksikale rekkefølgen på groupId og artefaktId versjonskomponenter:

Versjon version1_1_maven = ny versjon (1, 1, 0, null, "org.apache.maven", null); Versjon version1_1_gradle = ny versjon (1, 1, 0, null, "org.gradle", null); assertTrue (version1_1_maven.compareTo (version1_1_gradle) <0);

5. Bruke Semver4J

De Semver4j biblioteket lar oss følge reglene i semantisk versjonsspesifikasjon i Java.

5.1. Maven avhengighet

Først legger vi til det siste semver4j Maven avhengighet:

 com.vdurmont semver4j 3.1.0 

5.2. Semver

Deretter kan vi bruke Semver klasse for å definere en versjon:

Semver version1_1 = ny Semver ("1.1.0"); Semver versjon1_2 = ny Semver ("1.2.0"); Semver version1_3 = ny Semver ("1.3.0"); assertTrue (version1_1.compareTo (version1_2) 0); 

Internt analyserer den en versjon i komponenter som Major, Liten, og Lapp.

5.3. Versjonssammenligning

Også, den Semver klasse kommer med forskjellige innebygde metoder som er større enn, isLowerThan, og er lik for sammenligning av versjoner:

Semver version1_1_alpha = new Semver ("1.1.0-alpha"); assertTrue (versjon1_1.isGreaterThan (versjon1_1_alpha)); Semver version1_1_beta = ny Semver ("1.1.0-beta"); assertTrue (versjon1_1_alpha.isLowerThan (versjon1_1_beta)); assertTrue (versjon1_1.isEqualTo ("1.1.0"));

På samme måte gir den forskjell metode som returnerer hovedforskjellen mellom de to versjonene:

assertEquals (VersionDiff.MAJOR, versjon1_1.diff ("2.1.0")); assertEquals (VersionDiff.MINOR, versjon1_1.diff ("1.2.3")); assertEquals (VersionDiff.PATCH, versjon1_1.diff ("1.1.1"));

5.4. Versjonsstabilitet

Også, den Semver klassen kommer med er stabil metode for å kontrollere stabiliteten til en versjon, bestemt av tilstedeværelsen eller fraværet av et suffiks:

assertTrue (versjon1_1.isStable ()); assertFalse (versjon1_1_alpha.isStable ());

6. Tilpasset løsning

Vi har sett noen få løsninger for å sammenligne versjonstrengene. Hvis de ikke fungerer for en bestemt brukstilfelle, kan det hende vi må skrive en tilpasset løsning.

Her er et enkelt eksempel som fungerer i noen grunnleggende tilfeller - det kan alltid utvides hvis vi trenger noe mer.

Ideen her er å tokenisere versjonsstrengene ved hjelp av en punktavgrenser, og deretter sammenligne heltallskonvertering av hver String token, fra venstre. Hvis tokens heltallverdi er den samme, undersøk neste token, fortsett dette trinnet til vi finner en forskjell (eller til vi når det siste tokenet i en streng):

public static int compareVersions (String version1, String version2) {int comparisonResult = 0; Streng [] versjon1Splits = versjon1.split ("\."); Streng [] version2Splits = version2.split ("\."); int maxLengthOfVersionSplits = Math.max (version1Splits.length, version2Splits.length); for (int i = 0; i <maxLengthOfVersionSplits; i ++) {Heltall v1 = i <version1Splits.length? Integer.parseInt (versjon1Splits [i]): 0; Heltall v2 = i <version2Splits.length? Integer.parseInt (version2Splits [i]): 0; int sammenligne = v1.compareTo (v2); hvis (sammenlign! = 0) {sammenligningsresultat = sammenlign; gå i stykker; }} returner sammenligningResultat; }

La oss verifisere løsningen vår ved å sammenligne noen få versjoner:

assertTrue (VersionCompare.compareVersions ("1.0.1", "1.1.2") <0); assertTrue (VersionCompare.compareVersions ("1.0.1", "1.10") 0); assertTrue (VersionCompare.compareVersions ("1.1.2", "1.2.0") <0); assertEquals (0, VersionCompare.compareVersions ("1.3.0", "1.3"));

Denne koden har en begrensning at den bare kan sammenligne et versjonsnummer laget av heltall avgrenset av prikker.

Derfor, for å sammenligne alfanumeriske versjonsstrenger, kan vi bruke et vanlig uttrykk for å adskille alfabeter og sammenligne den leksikale rekkefølgen.

7. Konklusjon

I denne artikkelen så vi på forskjellige måter å sammenligne versjonstrenger i Java.

Først undersøkte vi innebygde løsninger levert av bygningsrammer som Maven og Gradle, ved hjelp av maven-artefakt og graderkjerne avhengigheter, henholdsvis. Deretter utforsket vi funksjoner for sammenligning av versjoner av jackson-core og semver4j biblioteker.

Sist skrev vi en tilpasset løsning for sammenligning av generisk versjonsstreng.

Som vanlig er alle kodeimplementeringene tilgjengelige på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found