अगर स्ट्रिंग एक जावा में पूर्णांक का प्रतिनिधित्व करती है, तो यह जांचने का सबसे अच्छा तरीका क्या है?


214

मैं आम तौर पर निम्नलिखित मुहावरे का उपयोग यह जांचने के लिए करता हूं कि क्या स्ट्रिंग को पूर्णांक में परिवर्तित किया जा सकता है।

public boolean isInteger( String input ) {
    try {
        Integer.parseInt( input );
        return true;
    }
    catch( Exception e ) {
        return false;
    }
}

क्या यह सिर्फ मुझे है, या यह थोड़ा हैकिश लगता है? बेहतर तरीका क्या है?


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


समाधान के लिए RegExp के बारे में आपका क्या विचार है?
अक्षय पैठानी

जवाबों:


171

यदि आप संभावित अतिप्रवाह समस्याओं से चिंतित नहीं हैं, तो यह फ़ंक्शन उपयोग करने की तुलना में लगभग 20-30 गुना तेज प्रदर्शन करेगा Integer.parseInt()

public static boolean isInteger(String str) {
    if (str == null) {
        return false;
    }
    int length = str.length();
    if (length == 0) {
        return false;
    }
    int i = 0;
    if (str.charAt(0) == '-') {
        if (length == 1) {
            return false;
        }
        i = 1;
    }
    for (; i < length; i++) {
        char c = str.charAt(i);
        if (c < '0' || c > '9') {
            return false;
        }
    }
    return true;
}

50
(c <= '/' || c> = ':') देखने में थोड़ा अजीब है। मैंने प्रयोग किया होगा (c <'0' || c> '9') ... जावा में <= और> = ऑपरेटर तेजी से हैं?
बेनामी

3
रेगेक्स का उपयोग क्यों नहीं किया जाता है? ऊपर दिए गए कोड के समान स्ट्रैचेज़ ("^ -? \\ d + $") वापस नहीं है।
मैग्लोब

15
मैं इस विधि या मूल विधि का उपयोग regex से पहले सवाल से करूंगा। यह प्रदर्शन के लिए, कार्यान्वयन की गति और सरासर स्थिरता के लिए मूल विधि है। रेगेक्स समाधान के पास इसके लिए कुछ भी नहीं है।
छिपकली

4
मैं अतिप्रवाह के बारे में चिंतित हूं, लेकिन इस पद्धति को BigInts के लिए अनुकूलित किया जा सकता है और अभी भी अन्य तरीकों की तुलना में तेजी से हो सकता है। यदि कोई सोच रहा है कि मैं इतनी सरल समस्या में इतना प्रयास क्यों कर रहा हूं, तो मैं प्रोजेक्ट यूलर समस्याओं को हल करने में सहायता के लिए एक पुस्तकालय बना रहा हूं।
छिपकली

1
यदि आप चिंतित हैं कि क्या आप वास्तव में स्ट्रिंग को एक इंट या लंबे समय तक पार्स कर सकते हैं तो आपको यह भी जांचना होगा कि क्या पूर्णांक स्ट्रिंग वास्तव में उन डेटा प्रकारों में फिट बैठता है।
जोनास के

65

आपके पास है, लेकिन आपको केवल पकड़ना चाहिए NumberFormatException


7
हाँ, यह आपकी आवश्यकता से अधिक अपवादों को पकड़ने के लिए बुरा रूप माना जाता है।
क्रिस

आप सही हे। NFE एकमात्र ऐसा है जिसे फेंका जा सकता है, लेकिन यह अभी भी एक बुरी आदत है।
छिपकली

मुझे लगता है कि यदि इनपुट शून्य है, तो एक एनपीई फेंका जा सकता है, इसलिए आपकी विधि को संभवत: स्पष्ट रूप से संभालना चाहिए, जिस तरह से आप चाहते हैं।
डॉव वास्समैन

@Dov: आप सही हैं NPE और NFE दोनों को स्पष्ट रूप से पकड़ा जाना चाहिए।
छिपकली का

यह प्रतिक्रिया इस प्रश्न का सही उत्तर होना चाहिए।
3

40

एक त्वरित बेंचमार्क किया। अपवाद वास्तव में ऐसे नहीं होते हैं, जब तक कि आप कई तरीकों को वापस करना शुरू नहीं करते हैं और जेवीएम को निष्पादन ढेर प्राप्त करने के लिए बहुत काम करना पड़ता है। जब एक ही विधि में रहते हैं, तो वे खराब प्रदर्शन नहीं करते हैं।

 public void RunTests()
 {
     String str = "1234567890";

     long startTime = System.currentTimeMillis();
     for(int i = 0; i < 100000; i++)
         IsInt_ByException(str);
     long endTime = System.currentTimeMillis();
     System.out.print("ByException: ");
     System.out.println(endTime - startTime);

     startTime = System.currentTimeMillis();
     for(int i = 0; i < 100000; i++)
         IsInt_ByRegex(str);
     endTime = System.currentTimeMillis();
     System.out.print("ByRegex: ");
     System.out.println(endTime - startTime);

     startTime = System.currentTimeMillis();
     for(int i = 0; i < 100000; i++)
         IsInt_ByJonas(str);
     endTime = System.currentTimeMillis();
     System.out.print("ByJonas: ");
     System.out.println(endTime - startTime);
 }

 private boolean IsInt_ByException(String str)
 {
     try
     {
         Integer.parseInt(str);
         return true;
     }
     catch(NumberFormatException nfe)
     {
         return false;
     }
 }

 private boolean IsInt_ByRegex(String str)
 {
     return str.matches("^-?\\d+$");
 }

 public boolean IsInt_ByJonas(String str)
 {
     if (str == null) {
             return false;
     }
     int length = str.length();
     if (length == 0) {
             return false;
     }
     int i = 0;
     if (str.charAt(0) == '-') {
             if (length == 1) {
                     return false;
             }
             i = 1;
     }
     for (; i < length; i++) {
             char c = str.charAt(i);
             if (c <= '/' || c >= ':') {
                     return false;
             }
     }
     return true;
 }

आउटपुट:

बयाना: 31

ByRegex: 453 (नोट: हर बार पैटर्न को फिर से संकलित करना)

बायजनास: 16

मैं सहमत हूँ कि जोनास के समाधान सबसे मजबूत भी है। लगता है कि वह जीत गया :)


13
तीनों को बेंचमार्क करने का शानदार विचार। रेगेक्स और जोनास विधियों के लिए निष्पक्ष होने के लिए, आपको गैर-पूर्णांक तार के साथ परीक्षण करना चाहिए, क्योंकि यह वही जगह है जहां Integer.parseInt विधि वास्तव में धीमी हो रही है।
छिपकली

4
क्षमा करें लेकिन यह रेगेक्स परीक्षण अच्छा नहीं है। (1) आपको regex इंजन की जांच करने की आवश्यकता नहीं है ^और $दूसरी बार चूंकि matchesपूरे स्ट्रिंग को regex से मेल खाना चाहिए, (2) str.matchesप्रत्येक बार अपना स्वयं का बनाना होगा Patternजो महंगा है। प्रदर्शन कारणों से हमें इस पद्धति के बाहर केवल एक बार ऐसे पैटर्न बनाने चाहिए और इसे अंदर उपयोग करना चाहिए। (3) हम केवल एक मिलानकर्ता ऑब्जेक्ट भी बना सकते हैं और इसका उपयोग reset(CharSequence)उपयोगकर्ता डेटा पास करने और इसके matches()परिणाम को वापस करने के लिए कर सकते हैं ।
Pshemo

इसलिए कुछ private final Matcher m = Pattern.compile("-?\\d+").matcher(""); private boolean byRegex(String str) { return m.reset(str).matches(); }बेहतर प्रदर्शन करना चाहिए।
15

@Phemo Integer.valueOf ("1") और Integer.valueOf ("1") दोनों अपवाद फेंकते हैं इसलिए ^ और $ के लिए जाँच उचित लगती है।
cquezel

1
@ cquezel हां, लेकिन जोड़ने और निहितार्थ के बाद से इसकी आवश्यकता नहीं matchesहै । के परिणाम पर एक नज़र डालें और । आप देखेंगे और । वापस कर दिया जाएगा क्योंकि स्ट्रिंग अंतरिक्ष से शुरू होती है जो इसे regex द्वारा पूरी तरह से मेल खाने से रोकती है। ^$" 123".matches("\\d+")"123".matches("\\d+")falsetruefalse
साहीमो

37

चूंकि संभावना है कि लोग अभी भी यहां आते हैं और बेंचमार्क के बाद रेगेक्स के खिलाफ पक्षपाती होंगे ... इसलिए मैं रेग्क्स के संकलित संस्करण के साथ बेंचमार्क का एक अद्यतन संस्करण देने वाला हूं। जो पिछले बेंचमार्क का विरोध करता है, यह रेगेक्स समाधान वास्तव में लगातार अच्छा प्रदर्शन दिखाता है।

छिपकली के बिल से नकल और संकलित संस्करण के साथ अद्यतन:

private final Pattern pattern = Pattern.compile("^-?\\d+$");

public void runTests() {
    String big_int = "1234567890";
    String non_int = "1234XY7890";

    long startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByException(big_int);
    long endTime = System.currentTimeMillis();
    System.out.print("ByException - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByException(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByException - non-integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByRegex(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByRegex - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByRegex(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByRegex - non-integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++)
            IsInt_ByCompiledRegex(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByCompiledRegex - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++)
            IsInt_ByCompiledRegex(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByCompiledRegex - non-integer data: ");
    System.out.println(endTime - startTime);


    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByJonas(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByJonas - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
            IsInt_ByJonas(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByJonas - non-integer data: ");
    System.out.println(endTime - startTime);
}

private boolean IsInt_ByException(String str)
{
    try
    {
        Integer.parseInt(str);
        return true;
    }
    catch(NumberFormatException nfe)
    {
        return false;
    }
}

private boolean IsInt_ByRegex(String str)
{
    return str.matches("^-?\\d+$");
}

private boolean IsInt_ByCompiledRegex(String str) {
    return pattern.matcher(str).find();
}

public boolean IsInt_ByJonas(String str)
{
    if (str == null) {
            return false;
    }
    int length = str.length();
    if (length == 0) {
            return false;
    }
    int i = 0;
    if (str.charAt(0) == '-') {
            if (length == 1) {
                    return false;
            }
            i = 1;
    }
    for (; i < length; i++) {
            char c = str.charAt(i);
            if (c <= '/' || c >= ':') {
                    return false;
            }
    }
    return true;
}

परिणाम:

ByException - integer data: 45
ByException - non-integer data: 465

ByRegex - integer data: 272
ByRegex - non-integer data: 131

ByCompiledRegex - integer data: 45
ByCompiledRegex - non-integer data: 26

ByJonas - integer data: 8
ByJonas - non-integer data: 2

1
ByCompiledRegex समय को अपने समय के माप में regex को शामिल करने की आवश्यकता है।
मार्टिन कार्नी

2
@MartinCarney मैंने इसे संशोधित किया और पैटर्न संकलन को बेंचमार्क किया। जाहिर है मेरा सीपीयू / जेआईटी तेज है, लेकिन अगर मैं इसे वापस प्रक्षेपित करता हूं, तो संकलन समय है 336
tedder42

2
स्पष्ट होना, कि 336 (एमएस) क्या होता है जब पैटर्न संकलन 100k बार किया जाता है, अन्य सभी लाइनों की तरह। इस निहितार्थ के साथ कि यह केवल एक बार किया गया है, इसका समय मूल रूप से शून्य है।
tedder42

संकलित रेगेक्स समय पर सीधे रिकॉर्ड स्थापित करने के लिए धन्यवाद।
लार्स नोव

शायद और "^[+-]?\\d+$"भी अच्छा होगा।
एडम

34
org.apache.commons.lang.StringUtils.isNumeric 

हालांकि जावा का मानक काम वास्तव में ऐसे उपयोगिता कार्यों को याद करता है

मुझे लगता है कि अपाचे कॉमन्स हर जावा प्रोग्रामर के लिए "होना चाहिए" है

बहुत बुरा यह अभी तक Java5 के लिए रखी नहीं है


1
इसके साथ एकमात्र समस्या अतिप्रवाह है: SI अभी भी आपको कॉमन्स-लैंग का उल्लेख करने के लिए +1 देता है :)
javamonkey79

2
दूसरी समस्या नकारात्मक संख्या है, लेकिन मैं भी +1 करता हूं, क्योंकि मेरे विचार से यह दृष्टिकोण एक अच्छे समाधान के सबसे करीब है।
सैंड्रीस

22

यह आंशिक रूप से इस बात पर निर्भर करता है कि आपके द्वारा "पूर्णांक में परिवर्तित किया जा सकता है" क्या है।

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

चरित्र-दर-वर्ण चेक कुशलता से "सभी में एक पूर्णांक नहीं" को अस्वीकार कर देगा, "यह एक पूर्णांक है, लेकिन जावा इसे संभाल नहीं सकता है" धीमी अपवाद मार्ग द्वारा पकड़े जाने वाले मामलों को। आप सकता भी हाथ से यह थोड़ा प्रयास करना चाहिए, लेकिन यह एक होगा बहुत अधिक जटिल।


17

Regexp के बारे में सिर्फ एक टिप्पणी। यहाँ दिया गया हर उदाहरण गलत है!। यदि आप regexp का उपयोग करना चाहते हैं, तो यह न भूलें कि पैटर्न को संकलित करने में बहुत समय लगता है। यह:

str.matches("^-?\\d+$")

और यह भी:

Pattern.matches("-?\\d+", input);

हर विधि कॉल में पैटर्न के संकलन का कारण बनता है। इसका सही तरीके से उपयोग करने के लिए:

import java.util.regex.Pattern;

/**
 * @author Rastislav Komara
 */
public class NaturalNumberChecker {
    public static final Pattern PATTERN = Pattern.compile("^\\d+$");

    boolean isNaturalNumber(CharSequence input) {
        return input != null && PATTERN.matcher(input).matches();
    }
}

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

13

अमरूद संस्करण है:

import com.google.common.primitives.Ints;

Integer intValue = Ints.tryParse(stringValue);

यदि यह स्ट्रिंग को पार्स करने में विफल रहता है तो यह अपवाद को फेंकने के बजाय अशक्त हो जाएगा।


3
सबसे अच्छा जवाब IMHO। अपने स्वयं के समाधान को रोल करने के बजाय अच्छी तरह से परीक्षण किए गए पुस्तकालयों का उपयोग करें। ( यहां चर्चा भी देखें ।)
ओलिवियर कैलेक्स

12

मैंने rally25rs उत्तर से कोड कॉपी किया और गैर-पूर्णांक डेटा के लिए कुछ परीक्षण जोड़े। परिणाम अनजाने में जोनास क्लेमिंग द्वारा पोस्ट की गई विधि के पक्ष में हैं। जब आप पूर्णांक डेटा रखते हैं, तो मैं आपके द्वारा मूल रूप से पोस्ट की गई अपवाद विधि के परिणाम बहुत अच्छे होते हैं, लेकिन जब आप नहीं करते हैं तो वे सबसे खराब होते हैं, जबकि RegEx समाधान के लिए परिणाम (मैं बहुत सारे लोगों के उपयोग पर शर्त लगाऊंगा) लगातार खराब थे । संकलित रेगेक्स उदाहरण के लिए फेलिप का उत्तर देखें , जो बहुत तेज है।

public void runTests()
{
    String big_int = "1234567890";
    String non_int = "1234XY7890";

    long startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByException(big_int);
    long endTime = System.currentTimeMillis();
    System.out.print("ByException - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByException(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByException - non-integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByRegex(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByRegex - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByRegex(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByRegex - non-integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByJonas(big_int);
    endTime = System.currentTimeMillis();
    System.out.print("\nByJonas - integer data: ");
    System.out.println(endTime - startTime);

    startTime = System.currentTimeMillis();
    for(int i = 0; i < 100000; i++)
        IsInt_ByJonas(non_int);
    endTime = System.currentTimeMillis();
    System.out.print("ByJonas - non-integer data: ");
    System.out.println(endTime - startTime);
}

private boolean IsInt_ByException(String str)
{
    try
    {
        Integer.parseInt(str);
        return true;
    }
    catch(NumberFormatException nfe)
    {
        return false;
    }
}

private boolean IsInt_ByRegex(String str)
{
    return str.matches("^-?\\d+$");
}

public boolean IsInt_ByJonas(String str)
{
    if (str == null) {
            return false;
    }
    int length = str.length();
    if (length == 0) {
            return false;
    }
    int i = 0;
    if (str.charAt(0) == '-') {
            if (length == 1) {
                    return false;
            }
            i = 1;
    }
    for (; i < length; i++) {
            char c = str.charAt(i);
            if (c <= '/' || c >= ':') {
                    return false;
            }
    }
    return true;
}

परिणाम:

ByException - integer data: 47
ByException - non-integer data: 547

ByRegex - integer data: 390
ByRegex - non-integer data: 313

ByJonas - integer data: 0
ByJonas - non-integer data: 16

6

यह कम है, लेकिन छोटा जरूरी बेहतर नहीं है (और यह पूर्णांक मानों को नहीं पकड़ेगा, जो सीमा से बाहर हैं, जैसा कि डैनटेल की टिप्पणी में बताया गया है ):

input.matches("^-?\\d+$");

निजी तौर पर, चूंकि कार्यान्वयन एक सहायक विधि और शुद्धता ट्रम्प लंबाई में दूर किया जाता है, इसलिए मैं सिर्फ आपके साथ कुछ ऐसा करूंगा जो आपके पास ( Exceptionबजाय आधार वर्ग को पकड़ने वाला NumberFormatException) होता है।


1
और शायद \\ d {1,10} है, हालांकि सही नहीं है, जावा इंटिजर्स को पकड़ने के लिए \\ d + से बेहतर है
मैगलो

6

आप स्ट्रिंग क्लास के मैचों की विधि का उपयोग कर सकते हैं। [0-9] उन सभी मूल्यों का प्रतिनिधित्व करता है, जो हो सकते हैं, + का अर्थ है कि यह कम से कम एक वर्ण लंबा होना चाहिए, और * का अर्थ है कि यह शून्य या अधिक वर्ण लंबा हो सकता है।

boolean isNumeric = yourString.matches("[0-9]+"); // 1 or more characters long, numbers only
boolean isNumeric = yourString.matches("[0-9]*"); // 0 or more characters long, numbers only

1
Nb यह doest "+10" या "-10") से मेल नहीं खाता है, जो आम तौर पर वैध पूर्णांक के रूप में शामिल किया जाएगा
टिम विंटल

4

कैसा रहेगा:

return Pattern.matches("-?\\d+", input);

पूर्णांक 9999999999999999999999999999999999 के बारे में क्या कहेंगे?
danatel

नकारात्मक चिन्ह की जाँच करना न भूलें।
जेरेमी रुटेन

क्या आपको रेगेक्स की शुरुआत और समाप्ति के लिए लंगर डालने की ज़रूरत नहीं है, इसलिए आप "आआ-1999zzz" पास नहीं करेंगे?
टिम हावलैंड 13

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

4

यह जोनास क्लेमिंग के उत्तर का जावा 8 रूपांतर है:

public static boolean isInteger(String str) {
    return str != null && str.length() > 0 &&
         IntStream.range(0, str.length()).allMatch(i -> i == 0 && (str.charAt(i) == '-' || str.charAt(i) == '+')
                  || Character.isDigit(str.charAt(i)));
}

टेस्ट कोड:

public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    Arrays.asList("1231231", "-1232312312", "+12313123131", "qwqe123123211", "2", "0000000001111", "", "123-", "++123",
            "123-23", null, "+-123").forEach(s -> {
        System.out.printf("%15s %s%n", s, isInteger(s));
    });
}

परीक्षण कोड के परिणाम:

        1231231 true
    -1232312312 true
   +12313123131 true
  qwqe123123211 false
              2 true
  0000000001111 true
                false
           123- false
          ++123 false
         123-23 false
           null false
          +-123 false

3

आप बस नंबर की जांच करें अपवाद : -

 String value="123";
 try  
 {  
    int s=Integer.parseInt(any_int_val);
    // do something when integer values comes 
 }  
 catch(NumberFormatException nfe)  
 {  
          // do something when string values comes 
 }  

3

यदि आपके स्ट्रिंग ऐरे में शुद्ध इंटेगर और स्ट्रिंग्स हैं, तो नीचे दिए गए कोड को काम करना चाहिए। आपको केवल पहले चरित्र को देखना होगा। जैसे ["4", "44", "एबीसी", "77", "बॉन्ड"]

if (Character.isDigit(string.charAt(0))) {
    //Do something with int
}

3

आप स्कैनर वर्ग का उपयोग भी कर सकते हैं , और hasNextInt () का उपयोग कर सकते हैं - और यह आपको अन्य प्रकारों के लिए परीक्षण करने की अनुमति देता है, जैसे, फ़्लोट्स, आदि।


इस जवाब ने मुझे एक रिमाइंडर दिया जिसकी मुझे ज़रूरत थी। मैं पूरी तरह से स्कैनर भूल गया था इस तरह के एक समारोह है। टी-अप
हब्रो

2

यदि आप यह जांचना चाहते हैं कि क्या स्ट्रिंग एक पूर्णांक का प्रतिनिधित्व करता है जो एक इंट प्रकार में फिट बैठता है, तो मैंने जोनास के उत्तर में थोड़ा संशोधन किया, ताकि जो तार पूर्णांक से बड़े पूर्णांक का प्रतिनिधित्व करते हैं। MAX_VALUE या Integer.IN_VALUE से छोटा है, अब वापस आएगा असत्य। उदाहरण के लिए: "3147483647" गलत वापस आएगा क्योंकि 3147483647 2147483647 से बड़ा है, और इसी तरह, "-2147483649" भी गलत वापस आएगा क्योंकि -2147483649 -2147483648 से छोटा है।

public static boolean isInt(String s) {
  if(s == null) {
    return false;
  }
  s = s.trim(); //Don't get tricked by whitespaces.
  int len = s.length();
  if(len == 0) {
    return false;
  }
  //The bottom limit of an int is -2147483648 which is 11 chars long.
  //[note that the upper limit (2147483647) is only 10 chars long]
  //Thus any string with more than 11 chars, even if represents a valid integer, 
  //it won't fit in an int.
  if(len > 11) {
    return false;
  }
  char c = s.charAt(0);
  int i = 0;
  //I don't mind the plus sign, so "+13" will return true.
  if(c == '-' || c == '+') {
    //A single "+" or "-" is not a valid integer.
    if(len == 1) {
      return false;
    }
    i = 1;
  }
  //Check if all chars are digits
  for(; i < len; i++) {
    c = s.charAt(i);
    if(c < '0' || c > '9') {
      return false;
    }
  }
  //If we reached this point then we know for sure that the string has at
  //most 11 chars and that they're all digits (the first one might be a '+'
  // or '-' thought).
  //Now we just need to check, for 10 and 11 chars long strings, if the numbers
  //represented by the them don't surpass the limits.
  c = s.charAt(0);
  char l;
  String limit;
  if(len == 10 && c != '-' && c != '+') {
    limit = "2147483647";
    //Now we are going to compare each char of the string with the char in
    //the limit string that has the same index, so if the string is "ABC" and
    //the limit string is "DEF" then we are gonna compare A to D, B to E and so on.
    //c is the current string's char and l is the corresponding limit's char
    //Note that the loop only continues if c == l. Now imagine that our string
    //is "2150000000", 2 == 2 (next), 1 == 1 (next), 5 > 4 as you can see,
    //because 5 > 4 we can guarantee that the string will represent a bigger integer.
    //Similarly, if our string was "2139999999", when we find out that 3 < 4,
    //we can also guarantee that the integer represented will fit in an int.
    for(i = 0; i < len; i++) {
      c = s.charAt(i);
      l = limit.charAt(i);
      if(c > l) {
        return false;
      }
      if(c < l) {
        return true;
      }
    }
  }
  c = s.charAt(0);
  if(len == 11) {
    //If the first char is neither '+' nor '-' then 11 digits represent a 
    //bigger integer than 2147483647 (10 digits).
    if(c != '+' && c != '-') {
      return false;
    }
    limit = (c == '-') ? "-2147483648" : "+2147483647";
    //Here we're applying the same logic that we applied in the previous case
    //ignoring the first char.
    for(i = 1; i < len; i++) {
      c = s.charAt(i);
      l = limit.charAt(i);
      if(c > l) {
        return false;
      }
      if(c < l) {
        return true;
      }
    }
  }
  //The string passed all tests, so it must represent a number that fits
  //in an int...
  return true;
}

1
क्या आप अपना उत्तर संपादित कर सकते हैं और बता सकते हैं कि यह आपके द्वारा बताए गए पिछले उत्तर को कैसे बेहतर बनाता है?
गाइल्स गौइलार्डेट

महान जवाब के लिए धन्यवाद। लेकिन "123" अर्थात, 123 के साथ अंतरिक्ष को वैध पूर्णांक माना जाता है।
साईकृष्ण राडारापु

1
@SaikrishnaRadarapu वे trim()इसलिए स्पष्ट रूप से एक जानबूझकर डिजाइन विकल्प का उपयोग करते हैं।
गिल्डनस्टर्न

2

आप अपाचे बर्तनों की कोशिश कर सकते हैं

NumberUtils.isCreatable(myText)

यहां जावदोक देखें


1
ऐसा लगता है कि यह विधि नवीनतम रिलीज़ लिंक में पदावनत है )। isCreateable(String)इसके बजाय आपको स्पष्ट रूप से उपयोग करना चाहिए ।
गिल्डनस्टर्न

अपडेट किया गया। धन्यवाद @ गिल्डनस्टर्न
बोरबज

1

आपको शायद उपयोग के मामले को भी ध्यान में रखना होगा:

यदि अधिकांश समय आप संख्याओं के वैध होने की उम्मीद करते हैं, तो अपवाद को पकड़ना केवल अवैध संख्या को बदलने का प्रयास करते समय एक प्रदर्शन ओवरहेड का कारण बनता है। जबकि कुछ isInteger()विधि को कॉल करना और फिर कन्वर्ट Integer.parseInt()करना हमेशा मान्य नंबरों के लिए एक प्रदर्शन ओवरहेड का कारण होगा - स्ट्रिंग्स को दो बार पार्स किया जाता है, एक बार चेक द्वारा और एक बार रूपांतरण द्वारा।


1

यह जोनास कोड का एक संशोधन है जो यह जांचता है कि स्ट्रिंग पूर्णांक में डाली जाने वाली सीमा के भीतर है या नहीं।

public static boolean isInteger(String str) {
    if (str == null) {
        return false;
    }
    int length = str.length();
    int i = 0;

    // set the length and value for highest positive int or lowest negative int
    int maxlength = 10;
    String maxnum = String.valueOf(Integer.MAX_VALUE);
    if (str.charAt(0) == '-') { 
        maxlength = 11;
        i = 1;
        maxnum = String.valueOf(Integer.MIN_VALUE);
    }  

    // verify digit length does not exceed int range
    if (length > maxlength) { 
        return false; 
    }

    // verify that all characters are numbers
    if (maxlength == 11 && length == 1) {
        return false;
    }
    for (int num = i; num < length; num++) {
        char c = str.charAt(num);
        if (c < '0' || c > '9') {
            return false;
        }
    }

    // verify that number value is within int range
    if (length == maxlength) {
        for (; i < length; i++) {
            if (str.charAt(i) < maxnum.charAt(i)) {
                return true;
            }
            else if (str.charAt(i) > maxnum.charAt(i)) {
                return false;
            }
        }
    }
    return true;
}

1
अच्छा लग रहा है, लेकिन अंतिम फॉर-लूप के लिए मुझे शून्य (या 1 यदि ऋणात्मक संख्या) पर रीसेट करने की आवश्यकता है, क्योंकि लूप जो यह जांचता है कि क्या प्रत्येक अंक एक संख्या है, जिसके परिणामस्वरूप मुझे स्ट्रिंग की लंबाई होगी, इसलिए अंतिम फॉर-लूप कभी नहीं चलेगा। मैं मैजिक नंबरों के बजाय जावा कॉन्स्टेंट इंटेगर.मैक्स_व्यूएल और इंटेगर.आईएन_वैल्यू का भी उपयोग करूंगा।
टिम

@TimtheEnchanter सुझाव के लिए धन्यवाद, मैंने उन्हें पूरी तरह से अनदेखा कर दिया। उन्हें शामिल करने के लिए मेरे संपादन में मैंने लूप के लिए पहली बार एक नया वैरिएबल का उपयोग किया, यदि अतिरिक्त विवरण से बचने के लिए।
वेन

1

यदि आप Android API का उपयोग कर रहे हैं, तो आप इसका उपयोग कर सकते हैं:

TextUtils.isDigitsOnly(str);



0

आपने क्या काम किया है, लेकिन आपको हमेशा उस तरह से जांच नहीं करनी चाहिए। फेंकने वाले अपवादों को "असाधारण" स्थितियों (शायद आपके मामले में फिट बैठता है) के लिए आरक्षित किया जाना चाहिए, और प्रदर्शन के मामले में बहुत महंगा है।


वे केवल महंगा हो अगर वे फेंक दिया हो।
छिपकली का बिल

0
Number number;
try {
    number = NumberFormat.getInstance().parse("123");
} catch (ParseException e) {
    //not a number - do recovery.
    e.printStackTrace();
}
//use number

0

यह केवल सकारात्मक पूर्णांकों के लिए काम करेगा।

public static boolean isInt(String str) {
    if (str != null && str.length() != 0) {
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) return false;
        }
    }
    return true;        
}

4
Stackoverflow में आपका स्वागत है। एक पुराने धागे को पुनर्जीवित करने से पहले पिछली प्रतिक्रियाओं और टिप्पणियों को पढ़ना सुनिश्चित करें। यह विधि (और संभव नुकसान) वास्तव में पहले से ही चर्चा की गई थी।
लेह

0

यह मेरे लिए काम करता है। बस यह पहचानने के लिए कि एक स्ट्रिंग एक आदिम या एक संख्या है।

private boolean isPrimitive(String value){
        boolean status=true;
        if(value.length()<1)
            return false;
        for(int i = 0;i<value.length();i++){
            char c=value.charAt(i);
            if(Character.isDigit(c) || c=='.'){

            }else{
                status=false;
                break;
            }
        }
        return status;
    }

0

सभी आंतरिक वर्णों की जांच करने के लिए, आप बस एक दोहरे नकारात्मक का उपयोग कर सकते हैं।

अगर (! सर्चस्ट्रीमिंगमैचेज़ ("[^ 0-9] + $")) ...

[^ 0-9] + $ चेक यह देखने के लिए कि क्या कोई वर्ण हैं जो पूर्णांक नहीं हैं, इसलिए यदि यह सत्य है तो परीक्षण विफल हो जाता है। बस यह नहीं है और आप सफलता पर सच हो।


नहीं। आपने स्पष्ट रूप से इसका परीक्षण नहीं किया है। यह केवल सही है अगर स्ट्रिंग में कहीं अंक है, न कि यदि स्ट्रिंग केवल अंक है। matchesविधि पूरी स्ट्रिंग, इसके बारे में अभी नहीं एक हिस्से के खिलाफ मेल खाता है।
दाऊद इब्न करीम

आपको दोहरा नकारात्मक भाग नहीं मिलता है।
रोजर एफ गे

खैर, मुझे दोहरा नकारात्मक नहीं मिला। यह बस काम नहीं करता है। यदि आपके पास अंकों और अक्षरों का मिश्रण है, तो यह ifब्लॉक में जाता है । यह नहीं करना चाहिए
दाऊद इब्न करीम

0

यह उपयोगी हो सकता है:

public static boolean isInteger(String self) {
    try {
        Integer.valueOf(self.trim());
        return true;
    } catch (NumberFormatException nfe) {
        return false;
    }
}

0

मेरा मानना ​​है कि शून्य जोखिम एक अपवाद के रूप में चल रहा है, क्योंकि जैसा कि आप नीचे देख सकते हैं कि आप हमेशा सुरक्षित रूप से पार्स intकरते हैं Stringऔर दूसरे तरीके से नहीं।

इसलिए:

  1. यदि आप जांचते हैं कि आपके स्ट्रिंग में वर्ण का प्रत्येक स्लॉट कम से कम एक अक्षर {"0", "1", "2", "3", "4", "5", "6", "7" से मेल खाता है ? "8", "9"}

    if(aString.substring(j, j+1).equals(String.valueOf(i)))
  2. आप हर समय योग करते हैं जो आपको उपरोक्त पात्रों के स्लॉट में मिला है।

    digits++;
  3. और अंत में आप की जाँच करता है, तो कई बार है कि आप पूर्णांकों का सामना करना पड़ा के रूप में वर्ण दिए गए स्ट्रिंग की लंबाई के साथ बराबर होती है।

    if(digits == aString.length())

और व्यवहार में हमारे पास है:

    String aString = "1234224245";
    int digits = 0;//count how many digits you encountered
    for(int j=0;j<aString.length();j++){
        for(int i=0;i<=9;i++){
            if(aString.substring(j, j+1).equals(String.valueOf(i)))
                    digits++;
        }
    }
    if(digits == aString.length()){
        System.out.println("It's an integer!!");
        }
    else{
        System.out.println("It's not an integer!!");
    }
    
    String anotherString = "1234f22a4245";
    int anotherDigits = 0;//count how many digits you encountered
    for(int j=0;j<anotherString.length();j++){
        for(int i=0;i<=9;i++){
            if(anotherString.substring(j, j+1).equals(String.valueOf(i)))
                    anotherDigits++;
        }
    }
    if(anotherDigits == anotherString.length()){
        System.out.println("It's an integer!!");
        }
    else{
        System.out.println("It's not an integer!!");
    }

और परिणाम हैं:

यह एक पूर्णांक है !!

यह पूर्णांक नहीं है !!

इसी तरह, आप यह सत्यापित कर सकते हैं कि यदि कोई Stringएक floatया एक है, doubleलेकिन उन मामलों में आपको केवल एक मुठभेड़ करना है (डॉट) स्ट्रिंग में और निश्चित रूप से जांचें कि क्या digits == (aString.length()-1)

फिर से, शून्य जोखिम यहां एक अपवाद के रूप में चल रहा है, लेकिन यदि आप एक स्ट्रिंग को पार्स करने की योजना बनाते हैं, तो यह ज्ञात होता है कि इसमें एक संख्या होती है ( मान लें कि इंट डेटा प्रकार) आपको पहले यह जांचना होगा कि क्या यह डेटा प्रकार में फिट बैठता है। अन्यथा आपको इसे डालना होगा।

मुझे उम्मीद है कि मैंने मदद की

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.