Usporedba verzija na Javi

1. Pregled

S napretkom tehnologija DevOps uobičajeno je graditi i implementirati aplikaciju više puta dnevno.

Stoga, svakoj gradnji se dodjeljuje jedinstveni broj verzije kako bismo mogli razlikovati gradnje. Ponekad se pojavi potreba za programskom usporedbom nizova verzije.

U ovom ćemo članku istražiti nekoliko načina za usporedbu nizova verzija u Javi kroz razne knjižnice. Napokon ćemo napisati prilagođeni program za obradu generičke usporedbe niza verzija.

2. Korištenje maven-artefakt

Za početak istražimo kako Maven podnosi usporedbu verzije.

2.1. Ovisnost Mavena

Prvo ćemo dodati najnovije maven-artefakt Mavenova ovisnost o našoj pom.xml:

 org.apache.maven maven-artefakt 3.6.3 

2.2. ComparableVersion

Istražimo ComparableVersion razred. Pruža a generička implementacija usporedbe verzija s neograničenim brojem komponenata verzije.

Sadrži a usporediTo , a rezultat usporedbe bit će veći ili manji od 0 kada je jedna verzija veća ili manja od druge:

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

Ovdje možemo potvrditi da je verzija 1.1 manja od verzije 1.2, a verzija 1.3 veća od verzije 1.2.

Međutim, dobit ćemo 0 kao rezultat prilikom usporedbe istih verzija:

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

2.3. Separatori i kvalifikatori verzija

Uz to, ComparableVersion razred poštuje točku (.) i crticu (-) kao razdvajače, pri čemu točka razdvaja glavnu i manju verziju, a crtica definira kvalifikatore:

ComparableVersion version1_1_alpha = nova ComparableVersion ("1.1-alfa"); assertTrue (version1_1.compareTo (version1_1_alpha)> 0);

Ovdje možemo potvrditi da je verzija 1.1 veća od verzije 1.1-alfa.

Postoji nekoliko poznatih kvalifikacija koje podržava ComparableVersion poput alfa, beta, prekretnica, RC, i snimak (redoslijedom od najnižeg do najvišeg):

ComparableVersion version1_1_beta = nova ComparableVersion ("1.1-beta"); ComparableVersion version1_1_milestone = nova ComparableVersion ("1,1 milja"); ComparableVersion version1_1_rc = nova ComparableVersion ("1.1-rc"); ComparableVersion version1_1_snapshot = nova ComparableVersion ("1.1-snimka"); assertTrue (version1_1_alpha.compareTo (version1_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);

Također, to omogućuje nam definiranje nepoznatih kvalifikatora i poštivanje njihovog poretka, nakon već raspravljenih poznatih kvalifikatora, s leksičkim redoslijedom koji ne razlikuje velika i mala slova:

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

3. Korištenje gradle-core

Poput Mavena, Gradle također ima ugrađenu sposobnost obrade usporedbe verzija.

3.1. Ovisnost Mavena

Prvo, dodajmo najnovije gradle-core Ovisnost Mavena iz reportaže Gradle Releases:

 org.gradle gradle-core 6.1.1 

3.2. VersionBroj

The VersionBroj razred koji pruža Gradle uspoređuje dvije verzije, slične Mavenovoj ComparableVersion razred:

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. Komponente verzije

Za razliku od ComparableVersion razred, VersionBroj klasa podržava samo pet komponenti verzije - Majore, Maloljetnik, Mikro, Zakrpa, i Kvalifikator:

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. Sheme verzija

Također, VersionBroj podržava nekoliko različitih shema verzija poput Major.Minor.Micro-Qualifier i Major.Minor.Micro.Patch-Qualifier:

VersionNumber version1_1_1_snapshot = VersionNumber.parse ("1.1.1-snimka"); assertTrue (version1_1_1_1_alpha.compareTo (version1_1_1_snapshot) <0);

4. Korištenje jackson-core

4.1. Ovisnost Mavena

Slično ostalim ovisnostima, dodajmo i najnovije jackson-core Mavenova ovisnost o našoj pom.xml:

 com.fasterxml.jackson.core jackson-core 2.11.1 

4.2. Verzija

Zatim možemo ispitati Jacksonove Verzija klase, koja može sadržavati podatke o verzijama komponente zajedno s opcijskim groupId i artefaktId vrijednosti.

Stoga je konstruktor Verzija klasa omogućuje nam definiranje groupId i artefaktId, zajedno sa komponentama poput Majore, Maloljetnik, i Zakrpa:

javna verzija (int major, int minor, int patchLevel, String snapshotInfo, String groupId, String artifactId) {// ...}

Dakle, usporedimo nekoliko verzija pomoću Verzija razred:

Verzija version1_1 = nova verzija (1, 1, 0, null, null, null); Verzija version1_2 = nova verzija (1, 2, 0, null, null, null); Verzija version1_3 = nova verzija (1, 3, 0, null, null, null); assertTrue (version1_1.compareTo (version1_2) 0); Verzija version1_1_1 = nova verzija (1, 1, 1, null, null, null); assertTrue (version1_1.compareTo (version1_1_1) <0);

4.3. The snapshotInfo Komponenta

The snapshotInfo komponenta se ne koristi prilikom usporedbe dviju verzija:

Verzija version1_1_snapshot = nova verzija (1, 1, 0, "snapshot", null, null); assertEquals (0, version1_1.compareTo (version1_1_snapshot));

Uz to, Verzija razred pruža isSnapshot metoda za provjeru sadrži li verzija komponentu snimke:

assertTrue (verzija1_1_snapshot.isSnapshot ());

4.4. The groupId i artefaktId Komponente

Također, ova klasa uspoređuje leksički poredak groupId i artefaktId komponente verzije:

Verzija version1_1_maven = nova verzija (1, 1, 0, null, "org.apache.maven", null); Verzija version1_1_gradle = nova verzija (1, 1, 0, null, "org.gradle", null); assertTrue (version1_1_maven.compareTo (version1_1_gradle) <0);

5. Korištenje Semver4J

The Semver4j Biblioteka nam omogućuje slijediti pravila semantičke specifikacije verzija u Javi.

5.1. Ovisnost Mavena

Prvo ćemo dodati najnovije semver4j Ovisnost o Mavenu:

 com.vdurmont semver4j 3.1.0 

5.2. Semver

Tada možemo koristiti Semver klasa za definiranje verzije:

Semver verzija1_1 = novi Semver ("1.1.0"); Semver verzija1_2 = novi Semver ("1.2.0"); Semver verzija1_3 = novi Semver ("1.3.0"); assertTrue (version1_1.compareTo (version1_2) 0); 

Interno raščlanjuje verziju na komponente poput Majore, Maloljetnik, i Zakrpa.

5.3. Usporedba verzije

Također, Semver klasa dolazi s raznim ugrađenim metodama poput jeVećeNego, isLowerThan, i jednako je za usporedbu verzije:

Semver verzija1_1_alpha = novi Semver ("1.1.0-alfa"); assertTrue (verzija1_1.isGreaterThan (verzija1_1_alfa)); Semver verzija1_1_beta = novi Semver ("1.1.0-beta"); assertTrue (version1_1_alpha.isLowerThan (version1_1_beta)); assertTrue (verzija1_1.isEqualTo ("1.1.0"));

Isto tako, pruža razl metoda koja vraća glavnu razliku između dvije verzije:

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

5.4. Stabilnost verzije

Također, Semver razred dolazi s jeStabilan metoda za provjeru stabilnosti verzije, određena prisutnošću ili odsutnošću sufiksa:

assertTrue (verzija1_1.isStable ()); assertFalse (verzija1_1_alpha.isStable ());

6. Prilagođeno rješenje

Vidjeli smo nekoliko rješenja za usporedbu nizova verzija. Ako ne rade za određeni slučaj upotrebe, možda ćemo morati napisati prilagođeno rješenje.

Evo jednostavnog primjera koji vrijedi za neke osnovne slučajeve - uvijek se može proširiti ako nam treba nešto više.

Ideja je ovdje tokenizirati verzijske nizove pomoću razdjelnika točkica, a zatim usporediti cjelobrojnu pretvorbu svake Niz token, počevši s lijeve strane. Ako je cijela vrijednost tokena ista, ispitajte sljedeći token, nastavljajući ovaj korak dok ne pronađemo razliku (ili dok ne dosegnemo zadnji token u bilo kojem nizu):

javna statička int compareVersions (niz verzija1, niz verzija2) {int usporedbaResult = 0; String [] version1Splits = version1.split ("\."); String [] version2Splits = version2.split ("\."); int maxLengthOfVersionSplits = Math.max (version1Splits.length, version2Splits.length); za (int i = 0; i <maxLengthOfVersionSplits; i ++) {Integer v1 = i <version1Splits.length? Integer.parseInt (version1Splits [i]): 0; Cijeli broj v2 = i <version2Splits.length? Integer.parseInt (version2Splits [i]): 0; int usporedi = v1.compareTo (v2); if (usporedi! = 0) {usporedbaResult = usporedi; pauza; }} return returnResult; }

Provjerimo svoje rješenje usporedbom nekoliko verzija:

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"));

Ovaj kôd ima ograničenje da može uspoređivati ​​samo broj verzije izrađen od cijelih brojeva odvojenih točkama.

Stoga za usporedbu alfanumeričkih nizova verzija možemo upotrijebiti regularni izraz za odvajanje abeceda i usporedbu leksičkog poretka.

7. Zaključak

U ovom smo članku istražili razne načine za usporedbu nizova verzija u Javi.

Isprva smo ispitivali ugrađena rješenja koja pružaju okviri za izgradnju poput Maven i Gradle, koristeći maven-artefakt i gradle-core ovisnosti. Zatim smo istražili značajke za usporedbu verzija jackson-core i semver4j knjižnice.

Na kraju smo napisali prilagođeno rješenje za usporedbu niza generičke verzije.

Kao i obično, sve implementacije koda dostupne su na GitHubu.


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