आप जावा में दो संस्करण स्ट्रिंग्स की तुलना कैसे करते हैं?


155

क्या संस्करण संख्याओं की तुलना करने के लिए एक मानक मुहावरा है? मैं सीधे स्ट्रिंग्स तुलना का उपयोग नहीं कर सकता क्योंकि मुझे अभी तक पता नहीं है कि वहां अधिकतम कितने अंक रिलीज़ होंगे। मुझे संस्करणों की तुलना करने की आवश्यकता है और निम्नलिखित पकड़ सही है:

1.0 < 1.1
1.0.1 < 1.1
1.9 < 1.10

क्या आपने डॉट्स को हटाने की कोशिश की है और परिणामस्वरूप स्ट्रिंग को पूर्णांक के रूप में पार्स किया है? मैं वर्तमान में निम्नलिखित के लिए कुछ इसी तरह का उपयोग कर रहा: String version = "1.1.2".replace(".", ""); int number = Integer.parseInt(version); // = 112। आप संख्या की दूसरे से तुलना कर सकते हैं और इस प्रकार वह संस्करण खोज सकते हैं जो हाल ही में आया है। इसके अतिरिक्त आप जांच सकते हैं कि क्या versionस्ट्रिंग कुछ निश्चित पैटर्न से मेल खाती है जैसे \\d+\\.\\d+\\.\\dकि परिणाम में कम से कम 3 अंक हैं।
रजिस्टर्डयूजर

4
@RegisteredUser कुछ इस तरह से काम करेगा: 1.12.1 और 1.1.34?
kojow7

आपको यह सुनिश्चित करना होगा कि प्रत्येक भाग की लंबाई समान हो। इसलिए अपने उदाहरण के दो संस्करणों की तुलना करने के लिए उन्हें कुछ इस तरह होना चाहिए: 1.12.01 और 1.01.34। जावा में आप इसे पहले .पात्र में विभाजित करके और प्रत्येक तत्वों की लंबाई की तुलना करके प्राप्त कर सकते हैं । बाद में बस सभी तत्वों को एक स्ट्रिंग में रखें, फिर इसे int के रूप में पार्स करें और फिर दूसरे संस्करण से इसकी तुलना करें जिसे उसी तरह से परिवर्तित किया गया है
RegisteredUser

बस यह साझा करना चाहता था कि यह आश्चर्यजनक रूप से groovy stackoverflow.com/
//7737400

जवाबों:


58

डॉट को सीमांकक के रूप में स्ट्रिंग्स को टोकें और फिर बाईं ओर से पूर्णांक अनुवाद पक्ष की तुलना करें।


1
यह वही है जो मुझे संदेह था कि मुझे इसका सहारा लेना होगा। इसमें दो संस्करण स्ट्रिंग्स के छोटे में टोकन पर लूपिंग भी शामिल है। पुष्टि करने के लिए धन्यवाद।
छिपकली

38
और मत भूलो कि आपके पास हमेशा केवल नंबर नहीं हो सकते हैं। कुछ ऐप में बिल्ड नंबर शामिल होंगे, और बीटा / आदि के लिए 1.0.1b जैसी चीजें शामिल हो सकती हैं।
जॉन गार्डनर

2
आप यह कैसे करते हैं?
बिग मैकलेरज्यूज

आप एक रेगेक्स लिखते हैं जो स्ट्रिंग को अंक और गैर-अंक वर्गों में विभाजित करता है। अंकों के वर्गों की तुलना संख्यात्मक रूप से करें और गैर-अंकीय अनुभागों को शाब्दिक रूप से। (शायद डॉट्स पर विभाजित भी।)
टूलफोर्गर

179

इस पुराने पोस्ट का एक और समाधान (उन लोगों के लिए जो इसे मदद कर सकता है):

public class Version implements Comparable<Version> {

    private String version;

    public final String get() {
        return this.version;
    }

    public Version(String version) {
        if(version == null)
            throw new IllegalArgumentException("Version can not be null");
        if(!version.matches("[0-9]+(\\.[0-9]+)*"))
            throw new IllegalArgumentException("Invalid version format");
        this.version = version;
    }

    @Override public int compareTo(Version that) {
        if(that == null)
            return 1;
        String[] thisParts = this.get().split("\\.");
        String[] thatParts = that.get().split("\\.");
        int length = Math.max(thisParts.length, thatParts.length);
        for(int i = 0; i < length; i++) {
            int thisPart = i < thisParts.length ?
                Integer.parseInt(thisParts[i]) : 0;
            int thatPart = i < thatParts.length ?
                Integer.parseInt(thatParts[i]) : 0;
            if(thisPart < thatPart)
                return -1;
            if(thisPart > thatPart)
                return 1;
        }
        return 0;
    }

    @Override public boolean equals(Object that) {
        if(this == that)
            return true;
        if(that == null)
            return false;
        if(this.getClass() != that.getClass())
            return false;
        return this.compareTo((Version) that) == 0;
    }

}

Version a = new Version("1.1");
Version b = new Version("1.1.1");
a.compareTo(b) // return -1 (a<b)
a.equals(b)    // return false

Version a = new Version("2.0");
Version b = new Version("1.9.9");
a.compareTo(b) // return 1 (a>b)
a.equals(b)    // return false

Version a = new Version("1.0");
Version b = new Version("1");
a.compareTo(b) // return 0 (a=b)
a.equals(b)    // return true

Version a = new Version("1");
Version b = null;
a.compareTo(b) // return 1 (a>b)
a.equals(b)    // return false

List<Version> versions = new ArrayList<Version>();
versions.add(new Version("2"));
versions.add(new Version("1.0.5"));
versions.add(new Version("1.01.0"));
versions.add(new Version("1.00.1"));
Collections.min(versions).get() // return min version
Collections.max(versions).get() // return max version

// WARNING
Version a = new Version("2.06");
Version b = new Version("2.060");
a.equals(b)    // return false

संपादित करें:

@daiscog: आपकी टिप्पणी के लिए धन्यवाद, इस कोड को एंड्रॉइड प्लेटफ़ॉर्म के लिए विकसित किया गया है और जैसा कि Google द्वारा अनुशंसित है, विधि "मैच" जावा के विपरीत पूरे स्ट्रिंग की जांच करती है जो एक नियामक पैटर्न का उपयोग करती है। ( Android प्रलेखन - जावा प्रलेखन )


2
यह सबसे अच्छा समाधान IMHO है। मैंने इसे बदलकर 3 तत्व संस्करण कोड तक सीमित कर दिया है, अगर ((! Version.matches ("[0-9] + (\\। [0-9] +) {0,2}") और एक चर जोड़कर। निजी स्थिर अंतिम int [] PRIME = {2, 3, 5}; मैं उपरोक्त के लिए लापता हैशकोड बनाने में सक्षम था: @Override सार्वजनिक अंतिम int हैशकोड () {अंतिम स्ट्रिंग [] भागों = this.get ()। ("\\"।); int हैशकोड = 0; के लिए (इंट i = 0; मैं <part.length; मैं ++) {अंतिम इंट भाग = Integer.parseInt (भागों [i]); अगर (भाग) 0: { हैशकोड + = PRIME [i] ^ हिस्सा;}} रिटर्न हैशकोड;}
बैरी इरविन

आपको कम से कम निहित कॉल को कैश करना चाहिए Pattern.compile(), यह देखते हुए कि आपके तर्क को O(N log N)जटिलता के साथ कहा जाता है।
लुकास एडर

यह कार्यान्वयन समतुल्य (ऑब्जेक्ट) को ओवरराइड करता है और इसलिए हैशकोड () को ओवरराइड करना चाहिए। दो वस्तुएं जो समान हैं, उसी हैशकोड को वापस करना चाहिए अन्यथा आप परेशानी में पड़ सकते हैं यदि आप इन वस्तुओं का उपयोग हैशेड संग्रह के साथ करते हैं।
कॉलिन फिलिप्स

आप नए संस्करण ("1.0") के बाद से संस्करण स्ट्रिंग पर हैश नहीं कर सकते। बराबर (नया संस्करण ("1") सही लौटेगा। यह काम करेगा, लेकिन अक्षम है ... // अनुबंध: कोई भी दो संस्करण समान हैं, उसी हैशकोड को वापस करना चाहिए। "" 1.0 "के बराबर होने के बाद" 1 ", हम संस्करण स्ट्रिंग के हैशकोड को वापस नहीं कर सकते। @Override public int hashCode () {return 1;}
कॉलिन फिलिप्स

Kotlin पर परिवर्तित stackoverflow.com/a/61795721/6352712
Serg Burlaka

106

मावेन का उपयोग करना वास्तव में आसान है:

import org.apache.maven.artifact.versioning.DefaultArtifactVersion;

DefaultArtifactVersion minVersion = new DefaultArtifactVersion("1.0.1");
DefaultArtifactVersion maxVersion = new DefaultArtifactVersion("1.10");

DefaultArtifactVersion version = new DefaultArtifactVersion("1.11");

if (version.compareTo(minVersion) < 0 || version.compareTo(maxVersion) > 0) {
    System.out.println("Sorry, your version is unsupported");
}

आप इस पृष्ठ से मावेन कलाकारी के लिए सही निर्भरता स्ट्रिंग प्राप्त कर सकते हैं :

<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.0.3</version>
</dependency>

5
मैंने परीक्षणों के साथ एक जिस्ट
yclian

11
बिल्कुल सही, पहिया को सुदृढ़ मत करो!
लुलिस मार्टिनेज

8
सिर्फ एक कारण के लिए उस में फ़ाइलों के बहुत सारे के साथ इस निर्भरता का उपयोग करने - एक वर्ग के लिए - DefaultArtifactVersion: केवल एक ही चिंता है
सत्र

7
@ इज़ स्टोरेज सस्ता है - निश्चित रूप से लिखने, परीक्षण और मूल कोड को बनाए रखने की तुलना में सस्ता है
एलेक्स डीन

11
ध्यान दें कि Comparable.compareTo"एक नकारात्मक पूर्णांक, शून्य, या एक सकारात्मक पूर्णांक" लौटाने के रूप में प्रलेखित किया गया है, इसलिए -1 और +1 की जाँच से बचना एक अच्छी आदत है।
सीन

52

आपको संस्करण स्ट्रिंग्स को सामान्य करने की आवश्यकता है ताकि उनकी तुलना की जा सके। कुछ इस तरह

import java.util.regex.Pattern;

public class Main {
    public static void main(String... args) {
        compare("1.0", "1.1");
        compare("1.0.1", "1.1");
        compare("1.9", "1.10");
        compare("1.a", "1.9");
    }

    private static void compare(String v1, String v2) {
        String s1 = normalisedVersion(v1);
        String s2 = normalisedVersion(v2);
        int cmp = s1.compareTo(s2);
        String cmpStr = cmp < 0 ? "<" : cmp > 0 ? ">" : "==";
        System.out.printf("'%s' %s '%s'%n", v1, cmpStr, v2);
    }

    public static String normalisedVersion(String version) {
        return normalisedVersion(version, ".", 4);
    }

    public static String normalisedVersion(String version, String sep, int maxWidth) {
        String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version);
        StringBuilder sb = new StringBuilder();
        for (String s : split) {
            sb.append(String.format("%" + maxWidth + 's', s));
        }
        return sb.toString();
    }
}

प्रिंटों

'1.0' < '1.1'
'1.0.1' < '1.1'
'1.9' < '1.10'
'1.a' > '1.9'

2
सामान्यीकरण के लिए चेतावनी का अर्थ है कि आपके पास वहां अधिकतम चौड़ाई है।
dlamblin

@IHeartAndroid अच्छा बिंदु, जब तक आप '4.1' == '4.1.0' की उम्मीद करते हैं, मुझे लगता है कि यह एक अर्थ ऑर्डरिंग है।
पीटर लॉरी

मेरे उत्तर की जाँच करें, मैंने यहाँ
अभिनव पुरी '

48

मौजूदा कोड का पुन: उपयोग करने के लिए सबसे अच्छा है, मावेन की तुलना करने योग्य कक्षा लें

फायदे:

  • अपाचे लाइसेंस, संस्करण 2.0,
  • परीक्षण किया है,
  • वसंत-सुरक्षा-कोर, jboss आदि जैसी कई परियोजनाओं में उपयोग (प्रतिलिपि)
  • कई विशेषताएं
  • यह पहले से ही एक java.lang.Comparable है
  • बस उस एक वर्ग को कॉपी-पेस्ट करें, कोई तृतीय-पक्ष निर्भरता न हो

मावेन-कलाकृतियों के लिए निर्भरता को शामिल न करें क्योंकि यह विभिन्न सकरात्मक निर्भरता को खींच लेगा


यह एक विज्ञापन की तरह पढ़ता है और अन्य उत्तरों में कुछ भी नहीं जोड़ता है।
eddie_cat

6
यह सवाल प्रासंगिक है क्योंकि यह संस्करणों की तुलना करने के लिए मानक विधि के बारे में था और मावेन संस्करण की तुलना बहुत मानक है।
दिलीप

5
यह सबसे अच्छा जवाब है। मैं विश्वास नहीं कर सकता कि कितने अन्य (स्वीकार किए गए सहित) परीक्षण के बिना, कुछ हैकी स्ट्रिंग विभाजन की कोशिश करते हैं। इस वर्ग का उपयोग करके कोड उदाहरण:assertTrue(new ComparableVersion("1.1-BETA").compareTo(new ComparableVersion("1.1-RC")) < 0)
फेबियन केसलर

नुकसान: निर्भरता के एक मेजबान में खींचता है, जिसका अर्थ है हमले की सतह का एक मेजबान और संस्करण संघर्षों की क्षमता।
टूलबार

35
// VersionComparator.java
import java.util.Comparator;

public class VersionComparator implements Comparator {

    public boolean equals(Object o1, Object o2) {
        return compare(o1, o2) == 0;
    }

    public int compare(Object o1, Object o2) {
        String version1 = (String) o1;
        String version2 = (String) o2;

        VersionTokenizer tokenizer1 = new VersionTokenizer(version1);
        VersionTokenizer tokenizer2 = new VersionTokenizer(version2);

        int number1 = 0, number2 = 0;
        String suffix1 = "", suffix2 = "";

        while (tokenizer1.MoveNext()) {
            if (!tokenizer2.MoveNext()) {
                do {
                    number1 = tokenizer1.getNumber();
                    suffix1 = tokenizer1.getSuffix();
                    if (number1 != 0 || suffix1.length() != 0) {
                        // Version one is longer than number two, and non-zero
                        return 1;
                    }
                }
                while (tokenizer1.MoveNext());

                // Version one is longer than version two, but zero
                return 0;
            }

            number1 = tokenizer1.getNumber();
            suffix1 = tokenizer1.getSuffix();
            number2 = tokenizer2.getNumber();
            suffix2 = tokenizer2.getSuffix();

            if (number1 < number2) {
                // Number one is less than number two
                return -1;
            }
            if (number1 > number2) {
                // Number one is greater than number two
                return 1;
            }

            boolean empty1 = suffix1.length() == 0;
            boolean empty2 = suffix2.length() == 0;

            if (empty1 && empty2) continue; // No suffixes
            if (empty1) return 1; // First suffix is empty (1.2 > 1.2b)
            if (empty2) return -1; // Second suffix is empty (1.2a < 1.2)

            // Lexical comparison of suffixes
            int result = suffix1.compareTo(suffix2);
            if (result != 0) return result;

        }
        if (tokenizer2.MoveNext()) {
            do {
                number2 = tokenizer2.getNumber();
                suffix2 = tokenizer2.getSuffix();
                if (number2 != 0 || suffix2.length() != 0) {
                    // Version one is longer than version two, and non-zero
                    return -1;
                }
            }
            while (tokenizer2.MoveNext());

            // Version two is longer than version one, but zero
            return 0;
        }
        return 0;
    }
}

// VersionTokenizer.java
public class VersionTokenizer {
    private final String _versionString;
    private final int _length;

    private int _position;
    private int _number;
    private String _suffix;
    private boolean _hasValue;

    public int getNumber() {
        return _number;
    }

    public String getSuffix() {
        return _suffix;
    }

    public boolean hasValue() {
        return _hasValue;
    }

    public VersionTokenizer(String versionString) {
        if (versionString == null)
            throw new IllegalArgumentException("versionString is null");

        _versionString = versionString;
        _length = versionString.length();
    }

    public boolean MoveNext() {
        _number = 0;
        _suffix = "";
        _hasValue = false;

        // No more characters
        if (_position >= _length)
            return false;

        _hasValue = true;

        while (_position < _length) {
            char c = _versionString.charAt(_position);
            if (c < '0' || c > '9') break;
            _number = _number * 10 + (c - '0');
            _position++;
        }

        int suffixStart = _position;

        while (_position < _length) {
            char c = _versionString.charAt(_position);
            if (c == '.') break;
            _position++;
        }

        _suffix = _versionString.substring(suffixStart, _position);

        if (_position < _length) _position++;

        return true;
    }
}

उदाहरण:

public class Main
{
    private static VersionComparator cmp;

    public static void main (String[] args)
    {
        cmp = new VersionComparator();
        Test(new String[]{"1.1.2", "1.2", "1.2.0", "1.2.1", "1.12"});
        Test(new String[]{"1.3", "1.3a", "1.3b", "1.3-SNAPSHOT"});
    }

    private static void Test(String[] versions) {
        for (int i = 0; i < versions.length; i++) {
            for (int j = i; j < versions.length; j++) {
                Test(versions[i], versions[j]);
            }
        }
    }

    private static void Test(String v1, String v2) {
        int result = cmp.compare(v1, v2);
        String op = "==";
        if (result < 0) op = "<";
        if (result > 0) op = ">";
        System.out.printf("%s %s %s\n", v1, op, v2);
    }
}

आउटपुट:

1.1.2 == 1.1.2                --->  same length and value
1.1.2 < 1.2                   --->  first number (1) less than second number (2) => -1
1.1.2 < 1.2.0                 --->  first number (1) less than second number (2) => -1
1.1.2 < 1.2.1                 --->  first number (1) less than second number (2) => -1
1.1.2 < 1.12                  --->  first number (1) less than second number (12) => -1
1.2 == 1.2                    --->  same length and value
1.2 == 1.2.0                  --->  first shorter than second, but zero
1.2 < 1.2.1                   --->  first shorter than second, and non-zero
1.2 < 1.12                    --->  first number (2) less than second number (12) => -1
1.2.0 == 1.2.0                --->  same length and value
1.2.0 < 1.2.1                 --->  first number (0) less than second number (1) => -1
1.2.0 < 1.12                  --->  first number (2) less than second number (12) => -1
1.2.1 == 1.2.1                --->  same length and value
1.2.1 < 1.12                  --->  first number (2) less than second number (12) => -1
1.12 == 1.12                  --->  same length and value

1.3 == 1.3                    --->  same length and value
1.3 > 1.3a                    --->  first suffix ('') is empty, but not second ('a') => 1
1.3 > 1.3b                    --->  first suffix ('') is empty, but not second ('b') => 1
1.3 > 1.3-SNAPSHOT            --->  first suffix ('') is empty, but not second ('-SNAPSHOT') => 1
1.3a == 1.3a                  --->  same length and value
1.3a < 1.3b                   --->  first suffix ('a') compared to second suffix ('b') => -1
1.3a < 1.3-SNAPSHOT           --->  first suffix ('a') compared to second suffix ('-SNAPSHOT') => -1
1.3b == 1.3b                  --->  same length and value
1.3b < 1.3-SNAPSHOT           --->  first suffix ('b') compared to second suffix ('-SNAPSHOT') => -1
1.3-SNAPSHOT == 1.3-SNAPSHOT  --->  same length and value

18

आश्चर्य है कि क्यों हर कोई मानता है कि संस्करण केवल पूर्णांकों से बने हैं - मेरे मामले में यह नहीं था।

पहिया को फिर से मजबूत क्यों करना (संस्करण मानकर सेमर मानक का अनुसरण करता है)

सबसे पहले https://github.com/vdurmont/semver4j मावेन के माध्यम से इंस्टॉल करें

फिर इस पुस्तकालय का उपयोग करें

Semver sem = new Semver("1.2.3");
sem.isGreaterThan("1.2.2"); // true

13
public static int compareVersions(String version1, String version2){

    String[] levels1 = version1.split("\\.");
    String[] levels2 = version2.split("\\.");

    int length = Math.max(levels1.length, levels2.length);
    for (int i = 0; i < length; i++){
        Integer v1 = i < levels1.length ? Integer.parseInt(levels1[i]) : 0;
        Integer v2 = i < levels2.length ? Integer.parseInt(levels2[i]) : 0;
        int compare = v1.compareTo(v2);
        if (compare != 0){
            return compare;
        }
    }

    return 0;
}

1
सरल मामलों के लिए उपयोगी।
क्रिस्टोफ रूसो

आपके विचार के आधार पर stackoverflow.com/a/62532745/2642478
Xan

4

यदि आपके पास पहले से ही जैक्सन है, तो आप इसका उपयोग कर सकते हैं com.fasterxml.jackson.core.Version:

import com.fasterxml.jackson.core.Version;
import org.junit.Test;

import static org.junit.Assert.assertTrue;

public class VersionTest {

    @Test
    public void shouldCompareVersion() {
        Version version1 = new Version(1, 11, 1, null, null, null);
        Version version2 = new Version(1, 12, 1, null, null, null);
        assertTrue(version1.compareTo(version2) < 0);
    }
}

2
public int compare(String v1, String v2) {
        v1 = v1.replaceAll("\\s", "");
        v2 = v2.replaceAll("\\s", "");
        String[] a1 = v1.split("\\.");
        String[] a2 = v2.split("\\.");
        List<String> l1 = Arrays.asList(a1);
        List<String> l2 = Arrays.asList(a2);


        int i=0;
        while(true){
            Double d1 = null;
            Double d2 = null;

            try{
                d1 = Double.parseDouble(l1.get(i));
            }catch(IndexOutOfBoundsException e){
            }

            try{
                d2 = Double.parseDouble(l2.get(i));
            }catch(IndexOutOfBoundsException e){
            }

            if (d1 != null && d2 != null) {
                if (d1.doubleValue() > d2.doubleValue()) {
                    return 1;
                } else if (d1.doubleValue() < d2.doubleValue()) {
                    return -1;
                }
            } else if (d2 == null && d1 != null) {
                if (d1.doubleValue() > 0) {
                    return 1;
                }
            } else if (d1 == null && d2 != null) {
                if (d2.doubleValue() > 0) {
                    return -1;
                }
            } else {
                break;
            }
            i++;
        }
        return 0;
    }

2
/**  
 *  written by: Stan Towianski - May 2018 
 * notes: I make assumption each of 3 version sections a.b.c is not longer then 4 digits: aaaa.bbbb.cccc-MODWORD1(-)modnum2
 * 5.10.13-release-1 becomes 0000500100013.501     6.0-snapshot becomes 0000600000000.100
 * MODWORD1 = -xyz/NotMatching, -SNAPSHOT, -ALPHA, -BETA, -RC, -RELEASE/nothing  return:  .0, .1, .2, .3, .4, .5
 * modnum2 = up to 2 digit/chars second version
 * */
public class VersionCk {

    private static boolean isVersionHigher( String baseVersion, String testVersion )
        {
        System.out.println( "versionToComparable( baseVersion ) =" + versionToComparable( baseVersion ) );
        System.out.println( "versionToComparable( testVersion ) =" + versionToComparable( testVersion ) + " is this higher ?" );
        return versionToComparable( testVersion ).compareTo( versionToComparable( baseVersion ) ) > 0;
        }

    //----  not worrying about += for something so small
    private static String versionToComparable( String version )
        {
//        System.out.println("version - " + version);
        String versionNum = version;
        int at = version.indexOf( '-' );
        if ( at >= 0 )
            versionNum = version.substring( 0, at );

        String[] numAr = versionNum.split( "\\." );
        String versionFormatted = "0";
        for ( String tmp : numAr )
            {
            versionFormatted += String.format( "%4s", tmp ).replace(' ', '0');
            }
        while ( versionFormatted.length() < 12 )  // pad out to aaaa.bbbb.cccc
            {
            versionFormatted += "0000";
            }
//        System.out.println( "converted min version =" + versionFormatted + "=   : " + versionNum );
        return versionFormatted + getVersionModifier( version, at );
        }

    //----  use order low to high: -xyz, -SNAPSHOT, -ALPHA, -BETA, -RC, -RELEASE/nothing  returns: 0, 1, 2, 3, 4, 5
    private static String getVersionModifier( String version, int at )
        {
//        System.out.println("version - " + version );
        String[] wordModsAr = { "-SNAPSHOT", "-ALPHA", "-BETA", "-RC", "-RELEASE" };        

        if ( at < 0 )
            return "." + wordModsAr.length + "00";   // make nothing = RELEASE level

        int i = 1;
        for ( String word : wordModsAr )
            {
            if ( ( at = version.toUpperCase().indexOf( word ) ) > 0 )
                return "." + i + getSecondVersionModifier( version.substring( at + word.length() ) );
            i++;
            }

        return ".000";
        }

    //----  add 2 chars for any number after first modifier.  -rc2 or -rc-2   returns 02
    private static String getSecondVersionModifier( String version )
        {
        System.out.println( "second modifier =" + version + "=" );
        Matcher m = Pattern.compile("(.*?)(\\d+).*").matcher( version );
//        if ( m.matches() )
//            System.out.println( "match ? =" + m.matches() + "=   m.group(1) =" + m.group(1) + "=   m.group(2) =" + m.group(2) + "=   m.group(3) =" + (m.groupCount() >= 3 ? m.group(3) : "x") );
//        else
//            System.out.println( "No match" );
        return m.matches() ? String.format( "%2s", m.group(2) ).replace(' ', '0') : "00";
        }

    public static void main(String[] args) 
        {
        checkVersion( "3.10.0", "3.4.0");
        checkVersion( "5.4.2", "5.4.1");
        checkVersion( "5.4.4", "5.4.5");
        checkVersion( "5.4.9", "5.4.12");
        checkVersion( "5.9.222", "5.10.12");
        checkVersion( "5.10.12", "5.10.12");
        checkVersion( "5.10.13", "5.10.14");
        checkVersion( "6.7.0", "6.8");
        checkVersion( "6.7", "2.7.0");
        checkVersion( "6", "6.3.1");
        checkVersion( "4", "4.0.0");
        checkVersion( "6.3.0", "6");
        checkVersion( "5.10.12-Alpha", "5.10.12-beTA");
        checkVersion( "5.10.13-release", "5.10.14-beta");
        checkVersion( "6.7.0", "6.8-snapshot");
        checkVersion( "6.7.1", "6.7.0-release");
        checkVersion( "6-snapshot", "6.0.0-beta");
        checkVersion( "6.0-snapshot", "6.0.0-whatthe");
        checkVersion( "5.10.12-Alpha-1", "5.10.12-alpha-2");
        checkVersion( "5.10.13-release-1", "5.10.13-release2");
        checkVersion( "10-rc42", "10.0.0-rc53");
        }

    private static void checkVersion(String baseVersion, String testVersion) 
        {
        System.out.println( "baseVersion - " + baseVersion );
        System.out.println( "testVersion - " + testVersion );
        System.out.println( "isVersionHigher = " + isVersionHigher( baseVersion, testVersion ) );
        System.out.println( "---------------");
        }

    }

कुछ आउटपुट:

---------------
baseVersion - 6.7
testVersion - 2.7.0
versionToComparable( baseVersion ) =0000600070000.500
versionToComparable( testVersion ) =0000200070000.500 is this higher ?
isVersionHigher = false
---------------
baseVersion - 6
testVersion - 6.3.1
versionToComparable( baseVersion ) =0000600000000.500
versionToComparable( testVersion ) =0000600030001.500 is this higher ?
isVersionHigher = true
---------------
baseVersion - 4
testVersion - 4.0.0
versionToComparable( baseVersion ) =0000400000000.500
versionToComparable( testVersion ) =0000400000000.500 is this higher ?
isVersionHigher = false
---------------
baseVersion - 6.3.0
testVersion - 6
versionToComparable( baseVersion ) =0000600030000.500
versionToComparable( testVersion ) =0000600000000.500 is this higher ?
isVersionHigher = false
---------------
baseVersion - 5.10.12-Alpha
testVersion - 5.10.12-beTA
second modifier ==
versionToComparable( baseVersion ) =0000500100012.200
second modifier ==
versionToComparable( testVersion ) =0000500100012.300 is this higher ?
second modifier ==
second modifier ==
isVersionHigher = true
---------------
baseVersion - 5.10.13-release
testVersion - 5.10.14-beta
second modifier ==
versionToComparable( baseVersion ) =0000500100013.500
second modifier ==
versionToComparable( testVersion ) =0000500100014.300 is this higher ?
second modifier ==
second modifier ==
isVersionHigher = true
---------------
baseVersion - 6.7.0
testVersion - 6.8-snapshot
versionToComparable( baseVersion ) =0000600070000.500
second modifier ==
versionToComparable( testVersion ) =0000600080000.100 is this higher ?
second modifier ==
isVersionHigher = true
---------------
baseVersion - 6.7.1
testVersion - 6.7.0-release
versionToComparable( baseVersion ) =0000600070001.500
second modifier ==
versionToComparable( testVersion ) =0000600070000.500 is this higher ?
second modifier ==
isVersionHigher = false
---------------
baseVersion - 6-snapshot
testVersion - 6.0.0-beta
second modifier ==
versionToComparable( baseVersion ) =0000600000000.100
second modifier ==
versionToComparable( testVersion ) =0000600000000.300 is this higher ?
second modifier ==
second modifier ==
isVersionHigher = true
---------------
baseVersion - 6.0-snapshot
testVersion - 6.0.0-whatthe
second modifier ==
versionToComparable( baseVersion ) =0000600000000.100
versionToComparable( testVersion ) =0000600000000.000 is this higher ?
second modifier ==
isVersionHigher = false
---------------
baseVersion - 5.10.12-Alpha-1
testVersion - 5.10.12-alpha-2
second modifier =-1=
versionToComparable( baseVersion ) =0000500100012.201
second modifier =-2=
versionToComparable( testVersion ) =0000500100012.202 is this higher ?
second modifier =-2=
second modifier =-1=
isVersionHigher = true
---------------
baseVersion - 5.10.13-release-1
testVersion - 5.10.13-release2
second modifier =-1=
versionToComparable( baseVersion ) =0000500100013.501
second modifier =2=
versionToComparable( testVersion ) =0000500100013.502 is this higher ?
second modifier =2=
second modifier =-1=
isVersionHigher = true
---------------
baseVersion - 10-rc42
testVersion - 10.0.0-rc53
second modifier =42=
versionToComparable( baseVersion ) =0001000000000.442
second modifier =53=
versionToComparable( testVersion ) =0001000000000.453 is this higher ?
second modifier =53=
second modifier =42=
isVersionHigher = true
---------------

2

मैंने MgntUtils नामक एक ओपन सोर्स लाइब्रेरी लिखी जिसमें एक उपयोगिता है जो स्ट्रिंग संस्करणों के साथ काम करती है। यह उनकी तुलना सही ढंग से करता है, संस्करण रेंज और इसके बाद के संस्करण के साथ काम करता है। यहाँ इस पुस्तकालय javadoc देखें तरीके हैं TextUtils.comapreVersions(...)। इसका भारी उपयोग और अच्छी तरह से परीक्षण किया गया है। यहां वह लेख है जो पुस्तकालय का वर्णन करता है और इसे कहां प्राप्त करना है। यह मावेन विरूपण साक्ष्य के रूप में और गीथूब (स्रोतों और जावाडॉक के साथ) पर उपलब्ध है


1

अपनी परियोजनाओं के लिए मैं अपने कॉमन्स-संस्करण पुस्तकालय का उपयोग करता हूं https://github.com/raydac/commons-version इसमें दो सहायक वर्ग शामिल हैं - पार्स संस्करण के लिए (पार्स किए गए संस्करण की तुलना किसी अन्य संस्करण ऑब्जेक्ट के साथ की जा सकती है क्योंकि यह तुलनीय है एक) और वर्जन सत्यापनकर्ता जो कुछ अभिव्यक्ति की तरह संस्करण की जांच करने की अनुमति देता है!=ide-1.1.1,>idea-1.3.4-SNAPSHOT;<1.2.3


1

मैंने अर्थ वर्जनिंग कन्वेंशन का उपयोग करके एंड्रॉइड प्लेटफॉर्म पर संस्करणों की तुलना करने के लिए सरल उपयोगिता बनाई । तो यह केवल XYZ (Major.Minor.Patch) प्रारूप में स्ट्रिंग्स के लिए काम करता है जहां एक्स, वाई और जेड गैर-नकारात्मक पूर्णांक हैं। आप इसे मेरे GitHub पर पा सकते हैं ।

Method Version.compareVersions (स्ट्रिंग v1, स्ट्रिंग v2) दो वर्जन स्ट्रिंग्स की तुलना करता है। यह संस्करण 0 के बराबर है, तो 1 रिटर्न करता है, अगर संस्करण v1 संस्करण v2 से पहले है, तो -1, यदि संस्करण v1 संस्करण v2 के बाद -1 है, तो यदि संस्करण प्रारूप अमान्य है।


आपका GitHub लिंक नहीं मिला है
aldok

1
public int CompareVersions(String version1, String version2)
{
    String[] string1Vals = version1.split("\\.");
    String[] string2Vals = version2.split("\\.");

    int length = Math.max(string1Vals.length, string2Vals.length);

    for (int i = 0; i < length; i++)
    {
        Integer v1 = (i < string1Vals.length)?Integer.parseInt(string1Vals[i]):0;
        Integer v2 = (i < string2Vals.length)?Integer.parseInt(string2Vals[i]):0;

        //Making sure Version1 bigger than version2
        if (v1 > v2)
        {
            return 1;
        }
        //Making sure Version1 smaller than version2
        else if(v1 < v2)
        {
            return -1;
        }
    }

    //Both are equal
    return 0;
}

0

एक छोटे से समारोह में लिखा था। सूची का उपयोग करते हुए

 public static boolean checkVersionUpdate(String olderVerison, String newVersion) {
        if (olderVerison.length() == 0 || newVersion.length() == 0) {
            return false;
        }
        List<String> newVerList = Arrays.asList(newVersion.split("\\."));
        List<String> oldVerList = Arrays.asList(olderVerison.split("\\."));

        int diff = newVerList.size() - oldVerList.size();
        List<String> newList = new ArrayList<>();
        if (diff > 0) {
            newList.addAll(oldVerList);
            for (int i = 0; i < diff; i++) {
                newList.add("0");
            }
            return examineArray(newList, newVerList, diff);
        } else if (diff < 0) {
            newList.addAll(newVerList);
            for (int i = 0; i < -diff; i++) {
                newList.add("0");
            }
            return examineArray(oldVerList, newList, diff);
        } else {
            return examineArray(oldVerList, newVerList, diff);
        }

    }

    public static boolean examineArray(List<String> oldList, List<String> newList, int diff) {
        boolean newVersionGreater = false;
        for (int i = 0; i < oldList.size(); i++) {
            if (Integer.parseInt(newList.get(i)) > Integer.parseInt(oldList.get(i))) {
                newVersionGreater = true;
                break;
            } else if (Integer.parseInt(newList.get(i)) < Integer.parseInt(oldList.get(i))) {
                newVersionGreater = false;
                break;
            } else {
                newVersionGreater = diff > 0;
            }
        }

        return newVersionGreater;
    }

0

मैंने संस्करण संख्याओं की तुलना के लिए एक छोटा जावा / एंड्रॉइड लाइब्रेरी लिखा है: https://github.com/G00fY2/version-compare

यह मूल रूप से क्या करता है:

  public int compareVersions(String versionA, String versionB) {
    String[] versionTokensA = versionA.split("\\.");
    String[] versionTokensB = versionB.split("\\.");
    List<Integer> versionNumbersA = new ArrayList<>();
    List<Integer> versionNumbersB = new ArrayList<>();

    for (String versionToken : versionTokensA) {
      versionNumbersA.add(Integer.parseInt(versionToken));
    }
    for (String versionToken : versionTokensB) {
      versionNumbersB.add(Integer.parseInt(versionToken));
    }

    final int versionASize = versionNumbersA.size();
    final int versionBSize = versionNumbersB.size();
    int maxSize = Math.max(versionASize, versionBSize);

    for (int i = 0; i < maxSize; i++) {
      if ((i < versionASize ? versionNumbersA.get(i) : 0) > (i < versionBSize ? versionNumbersB.get(i) : 0)) {
        return 1;
      } else if ((i < versionASize ? versionNumbersA.get(i) : 0) < (i < versionBSize ? versionNumbersB.get(i) : 0)) {
        return -1;
      }
    }
    return 0;
  }

यह स्निपेट किसी भी त्रुटि जांच या हैंडलिंग की पेशकश नहीं करता है। इसके अलावा मेरी लाइब्रेरी "1.2-आरसी"> "1.2-बीटा" जैसे प्रत्ययों का भी समर्थन करती है।


0

घटकों में अग्रणी शून्य को बदलने के लिए जावा 8 स्ट्रीम का उपयोग करना। इस कोड ने interviewbit.com पर सभी परीक्षण पारित कर दिए

public int compareVersion(String A, String B) {
    List<String> strList1 = Arrays.stream(A.split("\\."))
                                           .map(s -> s.replaceAll("^0+(?!$)", ""))
                                           .collect(Collectors.toList());
    List<String> strList2 = Arrays.stream(B.split("\\."))
                                           .map(s -> s.replaceAll("^0+(?!$)", ""))
                                           .collect(Collectors.toList());
    int len1 = strList1.size();
    int len2 = strList2.size();
    int i = 0;
    while(i < len1 && i < len2){
        if (strList1.get(i).length() > strList2.get(i).length()) return 1;
        if (strList1.get(i).length() < strList2.get(i).length()) return -1;
        int result = new Long(strList1.get(i)).compareTo(new Long(strList2.get(i)));
        if (result != 0) return result;
        i++;
    }
    while (i < len1){
        if (!strList1.get(i++).equals("0")) return 1;
    }
    while (i < len2){
        if (!strList2.get(i++).equals("0")) return -1;
    }
    return 0;
}

0

चूंकि इस पृष्ठ पर कोई उत्तर मिश्रित पाठ को अच्छी तरह से संभालता है, इसलिए मैंने अपना संस्करण बनाया:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Main {
    static double parseVersion(String v) {
        if (v.isEmpty()) {
            return 0;
        }
        Pattern p = Pattern.compile("^(\\D*)(\\d*)(\\D*)$");
        Matcher m = p.matcher(v);
    m.find();
    if (m.group(2).isEmpty()) {
      // v1.0.0.[preview]
      return -1;
    }
        double i = Integer.parseInt(m.group(2));
    if (!m.group(3).isEmpty()) {
      // v1.0.[0b]
      i -= 0.1;
    }
    return i;
    }

    public static int versionCompare(String str1, String str2) {
        String[] v1 = str1.split("\\.");
        String[] v2 = str2.split("\\.");
        int i = 0;
        for (; i < v1.length && i < v2.length; i++) {
            double iv1 = parseVersion(v1[i]);
            double iv2 = parseVersion(v2[i]);

            if (iv1 != iv2) {
                return iv1 - iv2 < 0 ? -1 : 1;
            }
        }
        if (i < v1.length) {
      // "1.0.1", "1.0"
            double iv1 = parseVersion(v1[i]);
            return iv1 < 0 ? -1 : (int)Math.ceil(iv1);
        }
        if (i < v2.length) {
            double iv2 = parseVersion(v2[i]);
            return - iv2 < 0 ? -1 : (int)Math.ceil(iv2);
        }
        return 0;
    }


  public static void main(String[] args) {
    System.out.println("versionCompare(v1.0.0, 1.0.0)");
    System.out.println(versionCompare("v1.0.0", "1.0.0")); // 0

    System.out.println("versionCompare(v1.0.0b, 1.0.0)");
    System.out.println(versionCompare("v1.0.0b", "1.0.0")); // -1

    System.out.println("versionCompare(v1.0.0.preview, 1.0.0)");
    System.out.println(versionCompare("v1.0.0.preview", "1.0.0")); // -1

    System.out.println("versionCompare(v1.0, 1.0.0)");
    System.out.println(versionCompare("v1.0", "1.0.0")); // 0

    System.out.println("versionCompare(ver1.0, 1.0.1)");
    System.out.println(versionCompare("ver1.0", "1.0.1")); // -1
  }
}

यह उन मामलों पर अभी भी कम है जहां आपको "अल्फा" की तुलना "बीटा" से करने की आवश्यकता है।


0

संस्करण संख्या के आधार पर फोर्स अपडेट अलर्ट दिखाने जा रहे किसी व्यक्ति के लिए मेरे पास निम्नलिखित विचार हैं। एंड्रॉइड करंट ऐप वर्जन और फायरबेस रिमोट कॉन्फिगरेशन वर्जन के बीच के संस्करणों की तुलना करते समय इसका इस्तेमाल किया जा सकता है। यह वास्तव में पूछे गए प्रश्न का उत्तर नहीं है, लेकिन यह निश्चित रूप से किसी की मदद करेगा।

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class Main
{
  static String firebaseVersion = "2.1.3"; // or 2.1
  static String appVersion = "2.1.4";
  static List<String> firebaseVersionArray;
  static List<String> appVersionArray;
  static boolean isNeedToShowAlert = false;
  public static void main (String[]args)
  {
    System.out.println ("Hello World");
    firebaseVersionArray = new ArrayList<String>(Arrays.asList(firebaseVersion.split ("\\.")));
    appVersionArray = new ArrayList<String>(Arrays.asList(appVersion.split ("\\.")));
    if(appVersionArray.size() < firebaseVersionArray.size()) {
        appVersionArray.add("0");
    }
    if(firebaseVersionArray.size() < appVersionArray.size()) {
        firebaseVersionArray.add("0");
    }
    isNeedToShowAlert = needToShowAlert(); //Returns false
    System.out.println (isNeedToShowAlert);

  }
  static boolean needToShowAlert() {
      boolean result = false;
      for(int i = 0 ; i < appVersionArray.size() ; i++) {
          if (Integer.parseInt(appVersionArray.get(i)) == Integer.parseInt(firebaseVersionArray.get(i))) {
              continue;
          } else if (Integer.parseInt(appVersionArray.get(i)) > Integer.parseInt(firebaseVersionArray.get(i))){
             result = false;
             break;
          } else if (Integer.parseInt(appVersionArray.get(i)) < Integer.parseInt(firebaseVersionArray.get(i))) {
             result = true;
             break;  
          }
      }
      return result;
  }
}

आप https://www.onlinegdb.com/online_java_compiler में कॉपी पेस्ट करके इस कोड को चला सकते हैं


0
public static void main(String[] args) {

    String version1 = "1.0";
    String version2 = "1.0.0";
    String[] version1_splits = version1.split("\\.");
    String[] version2_splits = version2.split("\\.");
    int length = version1_splits.length >= version2_splits.length ? version1_splits.length : version2_splits.length;
    int i=0;
    for(;i<length;i++){
        int version1_int = getValue(version1_splits,i);
        int version2_int = getValue(version2_splits,i);
        if(version1_int > version2_int){
            System.out.println("version1 > version2");
            break;
        }
        else if(version1_int < version2_int){
            System.out.println("version2 > version1");
            break;
        }
        else{
            if(i == length-1)
            System.out.println("version1 = version2");
        }
    }
}

private static int getValue(String[] version1_splits, int i) {
    int temp;
    try{
        temp = Integer.valueOf(version1_splits[i]);
    }
    catch(IndexOutOfBoundsException e){
        temp=0;
    }

    return temp;
}

0

मैंने अभी किया और खुद से पूछा, क्या यह सही है? क्योंकि मुझे मेरे से पहले एक सबसे साफ समाधान नहीं मिला है:

आपको इस उदाहरण की तरह केवल स्ट्रिंग संस्करणों ("1.0.0") को विभाजित करने की आवश्यकता है:

userVersion.split("\\.")

फिर आपके पास होगा: {"1", "0", "0"}

अब, मेरे द्वारा की गई विधि का उपयोग करना:

isUpdateAvailable(userVersion.split("\\."), latestVersionSplit.split("\\."));

तरीका:

/**
 * Compare two versions
 *
 * @param userVersionSplit   - User string array with major, minor and patch version from user (exemple: {"5", "2", "70"})
 * @param latestVersionSplit - Latest string array with major, minor and patch version from api (example: {"5", "2", "71"})
 * @return true if user version is smaller than latest version
 */
public static boolean isUpdateAvailable(String[] userVersionSplit, String[] latestVersionSplit) {

    int majorUserVersion = Integer.parseInt(userVersionSplit[0]);
    int minorUserVersion = Integer.parseInt(userVersionSplit[1]);
    int patchUserVersion = Integer.parseInt(userVersionSplit[2]);

    int majorLatestVersion = Integer.parseInt(latestVersionSplit[0]);
    int minorLatestVersion = Integer.parseInt(latestVersionSplit[1]);
    int patchLatestVersion = Integer.parseInt(latestVersionSplit[2]);

    if (majorUserVersion <= majorLatestVersion) {
        if (majorUserVersion < majorLatestVersion) {
            return true;
        } else {
            if (minorUserVersion <= minorLatestVersion) {
                if (minorUserVersion < minorLatestVersion) {
                    return true;
                } else {
                    return patchUserVersion < patchLatestVersion;
                }
            }
        }
    }

    return false;
}

किसी भी प्रतिक्रिया की प्रतीक्षा में :)


0

@ कोटलिन पर एलेक्स की पोस्ट

class Version(inputVersion: String) : Comparable<Version> {

        var version: String
            private set

        override fun compareTo(other: Version) =
            (split() to other.split()).let {(thisParts, thatParts)->
                val length = max(thisParts.size, thatParts.size)
                for (i in 0 until length) {
                    val thisPart = if (i < thisParts.size) thisParts[i].toInt() else 0
                    val thatPart = if (i < thatParts.size) thatParts[i].toInt() else 0
                    if (thisPart < thatPart) return -1
                    if (thisPart > thatPart) return 1
                }
                 0
            }

        init {
            require(inputVersion.matches("[0-9]+(\\.[0-9]+)*".toRegex())) { "Invalid version format" }
            version = inputVersion
        }
    }

    fun Version.split() = version.split(".").toTypedArray()

उपयोग:

Version("1.2.4").compareTo(Version("0.0.5")) //return 1

0

https://stackoverflow.com/a/27891752/2642478 पर आधारित

class Version(private val value: String) : Comparable<Version> {
    private val splitted by lazy { value.split("-").first().split(".").map { it.toIntOrNull() ?: 0 } }

    override fun compareTo(other: Version): Int {
        for (i in 0 until maxOf(splitted.size, other.splitted.size)) {
            val compare = splitted.getOrElse(i) { 0 }.compareTo(other.splitted.getOrElse(i) { 0 })
            if (compare != 0)
                return compare
        }
        return 0
    }
}

आप इस तरह का उपयोग कर सकते हैं:

    System.err.println(Version("1.0").compareTo( Version("1.0")))
    System.err.println(Version("1.0") < Version("1.1"))
    System.err.println(Version("1.10") > Version("1.9"))
    System.err.println(Version("1.10.1") > Version("1.10"))
    System.err.println(Version("0.0.1") < Version("1"))

-1

यह कोड इस प्रकार के तुलना संस्करणों को हल करने का प्रयास करता है।

अधिकांश संस्करण विनिर्देशक, जैसे> = 1.0, स्व-व्याख्यात्मक हैं। विनिर्देशन ~> का एक विशेष अर्थ है, सबसे अच्छा उदाहरण द्वारा दिखाया गया है। ~> 2.0.3> = 2.0.3 और <2.1 के समान है। ~> 2.1> = 2.1 और <3.0 के समान है।

public static boolean apply(String cmpDeviceVersion, String reqDeviceVersion)
{
    Boolean equal           = !cmpDeviceVersion.contains(">") && !cmpDeviceVersion.contains(">=") &&
                              !cmpDeviceVersion.contains("<") && !cmpDeviceVersion.contains("<=") &&
                              !cmpDeviceVersion.contains("~>");

    Boolean between         = cmpDeviceVersion.contains("~>");
    Boolean higher          = cmpDeviceVersion.contains(">") && !cmpDeviceVersion.contains(">=") && !cmpDeviceVersion.contains("~>");
    Boolean higherOrEqual   = cmpDeviceVersion.contains(">=");

    Boolean less            = cmpDeviceVersion.contains("<") && !cmpDeviceVersion.contains("<=");
    Boolean lessOrEqual     = cmpDeviceVersion.contains("<=");

    cmpDeviceVersion        = cmpDeviceVersion.replaceAll("[<>=~]", "");
    cmpDeviceVersion        = cmpDeviceVersion.trim();

    String[] version        = cmpDeviceVersion.split("\\.");
    String[] reqVersion     = reqDeviceVersion.split("\\.");

    if(equal)
    {
        return isEqual(version, reqVersion);
    }
    else if(between)
    {
        return isBetween(version, reqVersion);
    }
    else if(higher)
    {
        return isHigher(version, reqVersion);
    }
    else if(higherOrEqual)
    {
        return isEqual(version, reqVersion) || isHigher(version, reqVersion);
    }
    else if(less)
    {
        return isLess(version, reqVersion);
    }
    else if(lessOrEqual)
    {
        return isEqual(version, reqVersion) || isLess(version, reqVersion);
    }

    return false;
}

private static boolean isEqual(String[] version, String[] reqVersion)
{
    String strVersion = StringUtils.join(version);
    String strReqVersion = StringUtils.join(reqVersion);
    if(version.length > reqVersion.length)
    {
        Integer diff = version.length - reqVersion.length;
        strReqVersion += StringUtils.repeat(".0", diff);
    }
    else if(reqVersion.length > version.length)
    {
        Integer diff = reqVersion.length - version.length;
        strVersion += StringUtils.repeat(".0", diff);
    }

    return strVersion.equals(strReqVersion);
}

private static boolean isHigher(String[] version, String[] reqVersion)
{
    String strVersion = StringUtils.join(version);
    String strReqVersion = StringUtils.join(reqVersion);
    if(version.length > reqVersion.length)
    {
        Integer diff = version.length - reqVersion.length;
        strReqVersion += StringUtils.repeat(".0", diff);
    }
    else if(reqVersion.length > version.length)
    {
        Integer diff = reqVersion.length - version.length;
        strVersion += StringUtils.repeat(".0", diff);
    }

    return strReqVersion.compareTo(strVersion) > 0;
}

private static boolean isLess(String[] version, String[] reqVersion)
{
    String strVersion = StringUtils.join(version);
    String strReqVersion = StringUtils.join(reqVersion);
    if(version.length > reqVersion.length)
    {
        Integer diff = version.length - reqVersion.length;
        strReqVersion += StringUtils.repeat(".0", diff);
    }
    else if(reqVersion.length > version.length)
    {
        Integer diff = reqVersion.length - version.length;
        strVersion += StringUtils.repeat(".0", diff);
    }

    return strReqVersion.compareTo(strVersion) < 0;
}

private static boolean isBetween(String[] version, String[] reqVersion)
{
    return (isEqual(version, reqVersion) || isHigher(version, reqVersion)) &&
            isLess(getNextVersion(version), reqVersion);
}

private static String[] getNextVersion(String[] version)
{
    String[] nextVersion = new String[version.length];
    for(int i = version.length - 1; i >= 0 ; i--)
    {
        if(i == version.length - 1)
        {
            nextVersion[i] = "0";
        }
        else if((i == version.length - 2) && NumberUtils.isNumber(version[i]))
        {
            nextVersion[i] = String.valueOf(NumberUtils.toInt(version[i]) + 1);
        }
        else
        {
            nextVersion[i] = version[i];
        }
    }
    return nextVersion;
}

-1

मुझे @Peter लॉरी का विचार पसंद आया, और मैंने इसे आगे की सीमा तक बढ़ा दिया:

    /**
    * Normalize string array, 
    * Appends zeros if string from the array
    * has length smaller than the maxLen.
    **/
    private String normalize(String[] split, int maxLen){
        StringBuilder sb = new StringBuilder("");
        for(String s : split) {
            for(int i = 0; i<maxLen-s.length(); i++) sb.append('0');
            sb.append(s);
        }
        return sb.toString();
    }

    /**
    * Removes trailing zeros of the form '.00.0...00'
    * (and does not remove zeros from, say, '4.1.100')
    **/
    public String removeTrailingZeros(String s){
        int i = s.length()-1;
        int k = s.length()-1;
        while(i >= 0 && (s.charAt(i) == '.' || s.charAt(i) == '0')){
          if(s.charAt(i) == '.') k = i-1;
          i--;  
        } 
        return s.substring(0,k+1);
    }

    /**
    * Compares two versions(works for alphabets too),
    * Returns 1 if v1 > v2, returns 0 if v1 == v2,
    * and returns -1 if v1 < v2.
    **/
    public int compareVersion(String v1, String v2) {

        // Uncomment below two lines if for you, say, 4.1.0 is equal to 4.1
        // v1 = removeTrailingZeros(v1);
        // v2 = removeTrailingZeros(v2);

        String[] splitv1 = v1.split("\\.");
        String[] splitv2 = v2.split("\\.");
        int maxLen = 0;
        for(String str : splitv1) maxLen = Math.max(maxLen, str.length());
        for(String str : splitv2) maxLen = Math.max(maxLen, str.length());
        int cmp = normalize(splitv1, maxLen).compareTo(normalize(splitv2, maxLen));
        return cmp > 0 ? 1 : (cmp < 0 ? -1 : 0);
    }

आशा है कि यह किसी की मदद करता है। इसने इंटरव्यू और लेटकोड में सभी परीक्षण मामलों को पारित किया (तुलनात्मक कार्य में दो लाइनों को अनसुना करने की आवश्यकता)।

आसानी से परीक्षण!


-2
public class VersionComparator {

    /* loop through both version strings
     * then loop through the inner string to computer the val of the int
     * for each integer read, do num*10+<integer read>
     * and stop when stumbling upon '.'
     * When '.' is encountered...
     * see if '.' is encountered for both strings
     * if it is then compare num1 and num2 
     * if num1 == num2... iterate over p1++, p2++
     * else return (num1 > num2) ? 1 : -1
     * If both the string end then compare(num1, num2) return 0, 1, -1
     * else loop through the longer string and 
     * verify if it only has trailing zeros
     * If it only has trailing zeros then return 0
     * else it is greater than the other string
     */
    public static int compareVersions(String v1, String v2) {
        int num1 = 0;
        int num2 = 0;
        int p1 = 0;
        int p2 = 0;

        while (p1 < v1.length() && p2 < v2.length()) {
            num1 = Integer.parseInt(v1.charAt(p1) + "");
            num2 = Integer.parseInt(v2.charAt(p2) + "");
            p1++;
            p2++;

            while (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) != '.' && v2.charAt(p2) != '.') {
                if (p1 < v1.length()) num1 = num1 * 10 + Integer.parseInt(v1.charAt(p1) + "");
                if (p2 < v2.length()) num2 = num2 * 10 + Integer.parseInt(v2.charAt(p2) + "");
                p1++;
                p2++;
            }

            if (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) == '.' && v2.charAt(p2) == '.') {
                if ((num1 ^ num2) == 0) {
                    p1++;
                    p2++;
                }
                else return (num1 > num2) ? 1 : -1;
            }
            else if (p1 < v1.length() && p2 < v2.length() && v1.charAt(p1) == '.') return -1;
            else if (p1 < v1.length() && p2 < v2.length() && v2.charAt(p2) == '.') return 1;
        }

        if (p1 == v1.length() && p2 == v2.length()) {
            if ((num1 ^ num2) == 0) return 0;
            else return (num1 > num2) ? 1 : -1;
        }
        else if (p1 == v1.length()) {
            if ((num1 ^ num2) == 0) {
                while (p2 < v2.length()) {
                    if (v2.charAt(p2) != '.' && v2.charAt(p2) != '0') return -1;
                    p2++;
                }
                return 0;
            }
            else return (num1 > num2) ? 1 : -1;
        }
        else {
            if ((num1 ^ num2) == 0) {
                while (p1 < v1.length()) {
                    if (v1.charAt(p1) != '.' && v1.charAt(p1) != '0') return 1;
                    p1++;
                }
                return 0;
            }
            else return (num1 > num2) ? 1 : -1;
        }
    }

    public static void main(String[] args) {
        System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1);
        System.out.println(compareVersions("11.21.1.0.0.1.0", "11.23") ^ -1);
        System.out.println(compareVersions("11.23", "11.23.0.0.0.1.0") ^ -1);
        System.out.println(compareVersions("11.2", "11.23") ^ -1);
        System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1);
        System.out.println(compareVersions("1.21.1.0.0.1.0", "2.23") ^ -1);
        System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1);
        System.out.println(compareVersions("11.23.0.0.0.0.0", "11.23") ^ 0);
        System.out.println(compareVersions("11.23", "11.21.1.0.0.1.0") ^ 1);
        System.out.println(compareVersions("1.5.1.3", "1.5.1.3.0") ^ 0);
        System.out.println(compareVersions("1.5.1.4", "1.5.1.3.0") ^ 1);
        System.out.println(compareVersions("1.2.1.3", "1.5.1.3.0") ^ -1);
        System.out.println(compareVersions("1.2.1.3", "1.22.1.3.0") ^ -1);
        System.out.println(compareVersions("1.222.1.3", "1.22.1.3.0") ^ 1);
    }
}

-2

यहाँ एक अनुकूलित कार्यान्वयन है:

public static final Comparator<CharSequence> VERSION_ORDER = new Comparator<CharSequence>() {

  @Override
  public int compare (CharSequence lhs, CharSequence rhs) {
    int ll = lhs.length(), rl = rhs.length(), lv = 0, rv = 0, li = 0, ri = 0;
    char c;
    do {
      lv = rv = 0;
      while (--ll >= 0) {
        c = lhs.charAt(li++);
        if (c < '0' || c > '9')
          break;
        lv = lv*10 + c - '0';
      }
      while (--rl >= 0) {
        c = rhs.charAt(ri++);
        if (c < '0' || c > '9')
          break;
        rv = rv*10 + c - '0';
      }
    } while (lv == rv && (ll >= 0 || rl >= 0));
    return lv - rv;
  }

};

परिणाम:

"0.1" - "1.0" = -1
"1.0" - "1.0" = 0
"1.0" - "1.0.0" = 0
"10" - "1.0" = 9
"3.7.6" - "3.7.11" = -5
"foobar" - "1.0" = -1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.