Integer.parseInt () को एन्क्रिप्ट करने का अच्छा तरीका


91

मेरे पास एक प्रोजेक्ट है जिसमें हम अक्सर Integer.parseInt()स्ट्रिंग को इंट में बदलने के लिए उपयोग करते हैं। जब कुछ गलत हो जाता है (उदाहरण के लिए, Stringएक संख्या नहीं है लेकिन पत्र a, या जो कुछ भी) यह विधि एक अपवाद को फेंक देगी। हालांकि, अगर मुझे हर जगह अपने कोड में अपवादों को संभालना है, तो यह बहुत जल्दी बदसूरत लगने लगता है। मैं इसे एक विधि में रखना चाहूंगा, हालांकि, मेरे पास कोई सुराग नहीं है कि यह दिखाने के लिए कि स्वच्छ मूल्य कैसे वापस लौटाया जाए ताकि रूपांतरण गलत हो जाए।

C ++ में, मैं एक ऐसा तरीका बना सकता था, जो एक int को पॉइंटर स्वीकार करे और इस विधि को स्वयं सही या गलत लौटा दे। हालाँकि, जहाँ तक मुझे पता है, जावा में यह संभव नहीं है। मैं एक ऐसा ऑब्जेक्ट भी बना सकता हूं जिसमें एक सही / गलत चर और परिवर्तित मूल्य हो, लेकिन यह आदर्श भी नहीं लगता है। यही बात वैश्विक मूल्य के लिए जाती है, और इससे मुझे मल्टीथ्रेडिंग के साथ कुछ परेशानी हो सकती है।

तो क्या ऐसा करने का एक साफ तरीका है?


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

यह असंभव है कि किसी भी रेगेक्स को लिखा जाए जो सभी मान्य 32-बिट हस्ताक्षरित पूर्णांकों को कैप्चर करेगा और कोई भी अमान्य नहीं होगा। 2147483647 कानूनी है intजबकि 2147483648 नहीं है।
सेवा अलेक्सेयेव

जवाबों:


141

आप एक के Integerबजाय वापस आ सकते हैं int, nullपार्स विफलता पर लौट रहे हैं ।

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

संपादित करें: ऐसी विधि के लिए कोड:

public static Integer tryParse(String text) {
  try {
    return Integer.parseInt(text);
  } catch (NumberFormatException e) {
    return null;
  }
}

ध्यान दें कि मुझे यकीन नहीं है कि मेरे सिर के ऊपर से textयह अशक्त है अगर यह क्या करेगा । आपको इस पर विचार करना चाहिए - यदि यह बग का प्रतिनिधित्व करता है (यानी आपका कोड एक अमान्य मान को पारित कर सकता है, लेकिन कभी भी अशक्त नहीं होना चाहिए) तो अपवाद फेंकना उचित है; यदि यह एक बग का प्रतिनिधित्व नहीं करता है, तो आपको संभवतः शून्य वापस करना चाहिए क्योंकि आप किसी अन्य अमान्य मान के लिए करेंगे।

मूल रूप से इस उत्तर में new Integer(String)कंस्ट्रक्टर का उपयोग किया गया था; यह अब उपयोग करता है Integer.parseIntऔर एक बॉक्सिंग ऑपरेशन; इस तरह छोटे मूल्य समाप्त हो जाएंगे कैश्ड Integerवस्तुओं के लिए, यह उन स्थितियों में अधिक कुशल बनाता है।


1
यह कैसे मदद करता है? कॉल साइट की आवश्यकता होगी: <b> अस्थायी = tryParse (...); if (temp! = Null) {target = temp; } और {रिकवरी एक्शन}; </ b> रिकवरी पार्ट में संभावित फेंक अपवाद के साथ। मूल सूत्रीकरण में कॉल साइट के लिए <b> लक्ष्य का प्रयास करें = (...)। ParseInt; कैच (...) {रिकवरी एक्शन} </ b> रिकवरी में एक तुच्छ फेंक अपवाद के साथ बस कैच क्लॉज को हटाकर कार्यान्वित किया जा रहा है। प्रस्तावित समाधान यह समझने के लिए कैसे सरल है (यह एक जादू की चाल है) या किसी भी तरह से कोड की मात्रा को कम करता है?
इरा बैक्सटर

15
आम तौर पर nullसंदर्भों की जांच करने के लिए कोड की सफाई करना एक सामान्य आधार पर अपवादों को संभालना है।
एडम मारस

यह मानों के रूप में गुजरने से बचने के लिए भी क्लीनर है, लेकिन किसी तरह से संकेत मिलता है कि एन त्रुटि उत्पन्न हुई है; प्रवाह नियंत्रण के लिए अपवादों का उपयोग नहीं किया जाना चाहिए।
Esko

2
@ सेते कुओ: क्यों? लाभ कहाँ है? वे दोनों हर बार एक नया इंटेगर बनाते हैं? अगर कुछ भी हो, तो मुझे छोटे मूल्यों के लिए कैश का लाभ उठाने के लिए, Integer.parseInt का उपयोग करने के लिए और ऑटोबॉक्सिंग का ध्यान रखना चाहिए।
जॉन स्कीट

1
@Vlasec और न केवल वैकल्पिक, बल्कि वैकल्पिक के लिए विशेष संस्करण, जैसे OptionalInt।
जोशुआ टेलर

37

जब यह संख्या नहीं है तो आप क्या व्यवहार की उम्मीद करते हैं?

यदि, उदाहरण के लिए, आपके पास अक्सर उपयोग करने के लिए डिफ़ॉल्ट मान होता है जब इनपुट एक नंबर नहीं होता है, तो इस तरह की एक विधि उपयोगी हो सकती है:

public static int parseWithDefault(String number, int defaultVal) {
  try {
    return Integer.parseInt(number);
  } catch (NumberFormatException e) {
    return defaultVal;
  }
}

जब इनपुट पार्स नहीं किया जा सकता है तो इसी तरह के तरीकों को अलग-अलग डिफ़ॉल्ट व्यवहार के लिए लिखा जा सकता है।


29

कुछ मामलों में आपको पार्सिंग त्रुटियों को विफल-तेज़ स्थितियों के रूप में संभालना चाहिए, लेकिन अन्य मामलों में, जैसे कि एप्लिकेशन कॉन्फ़िगरेशन, मैं अपाचे कॉमन्स लैंग 3 नंबर यूटिल्स का उपयोग करके डिफ़ॉल्ट मानों के साथ लापता इनपुट को संभालना पसंद करता हूं

int port = NumberUtils.toInt(properties.getProperty("port"), 8080);

अधिकांश समय आप पहले से ही अपाचे कॉमन्स का उपयोग अन्य कारणों (जैसे स्ट्रिंगरिल्स) की वजह से अपनी परियोजना में कर रहे हैं, जो आसान हो जाता है।
रत्न टाटा जूल

16

अपवादों से निपटने के लिए यह सुनिश्चित करने के लिए एक नियमित अभिव्यक्ति का उपयोग करें कि आपके पास पहले सभी अंक हैं:

//Checking for Regular expression that matches digits
if(value.matches("\\d+")) {
     Integer.parseInt(value);
}

आपके उत्तर के लिए धन्यवाद। मैं इस पृष्ठ पर अधिकांश उत्तरों के माध्यम से पढ़ा, मैंने व्यक्तिगत रूप से कोशिश / पकड़ समाधान लिखा था। हालाँकि, यहाँ मेरा मुद्दा छोटा है, उस समाधान के साथ। जब आप एक लूप के अंदर कोशिश / पकड़ लेंगे, तो अधिकांश आईडीई आपके कोड के प्रवाह का विश्लेषण करने के साथ घुट जाएगा। यही कारण है कि कोशिश / पकड़ के बिना एक समाधान जो मुझे चाहिए था।
विजेता n।

4
सावधान रहे। Regex एक पूर्णांक से मेल खाता है जिसकी शुरुआत 0 से होती है जो बाद में एक NumberFormatException को फेंक देगा। (?: [1-9] \ घ * | 0) ^ इस प्रयास करें $ से stackoverflow.com/questions/12018479/...
हंस

5
यह विशेष रूप से रेगेक्स नकारात्मक संख्याओं को नहीं संभालता है।
ब्रैड कपित

7
यह भी पूर्णांक सीमा से बाहर की संख्या सीमाओं को कवर नहीं करता है
मोहम्मद याहिया

10

नहीं है Ints.tryParse()में अमरूद । यह गैर-संख्यात्मक स्ट्रिंग पर अपवाद नहीं फेंकता है, हालांकि यह अशक्त स्ट्रिंग पर अपवाद को फेंक देता है।


4

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

जॉन ने सुझाव दिया कि आप 'अशक्त' लौटा सकते हैं, लेकिन यह कम-से-कम एक नल-चेक द्वारा एक निर्माण / कैच के निर्माण की जगह है। व्यवहार में थोड़ा सा अंतर है यदि आप त्रुटि को 'भूल जाते हैं': यदि आप अपवाद को नहीं पकड़ते हैं, तो कोई असाइनमेंट नहीं है और बाएं हाथ की ओर वाला चर इसका पुराना मूल्य रखता है। यदि आप अशक्त होने का परीक्षण नहीं करते हैं, तो आप संभवतः JVM (NPE) से टकरा जाएंगे।

यवन का सुझाव मुझे अधिक सुरुचिपूर्ण लगता है, क्योंकि मुझे कुछ त्रुटियों या असाधारण राज्यों को इंगित करने के लिए अशक्त लौटने की तरह नहीं है। अब आपको एक पूर्वनिर्धारित वस्तु के साथ संदर्भगत समानता की जांच करनी होगी, जो एक समस्या को इंगित करता है। लेकिन, जैसा कि अन्य लोग तर्क देते हैं, यदि आप फिर से जांच करने के लिए 'भूल जाते हैं' और एक स्ट्रिंग अप्राप्य है, तो प्रोग्राम आपके 'ERROR' या 'NULL' ऑब्जेक्ट के अंदर लिपटे हुए int के साथ है।

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

तो, यह मेरे निष्कर्ष सादे parseInt विधि encapsulate नहीं है। मैं केवल इनकैप्सुलेट करता हूँ अगर मैं कुछ (एप्लीकेशन डिपेंडेड) एरर हैंडलिंग को भी जोड़ सकता था।


4

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

public class Test {
public interface Option<T> {
    T get();

    T getOrElse(T def);

    boolean hasValue();
}

final static class Some<T> implements Option<T> {

    private final T value;

    public Some(T value) {
        this.value = value;
    }

    @Override
    public T get() {
        return value;
    }

    @Override
    public T getOrElse(T def) {
        return value;
    }

    @Override
    public boolean hasValue() {
        return true;
    }
}

final static class None<T> implements Option<T> {

    @Override
    public T get() {
        throw new UnsupportedOperationException();
    }

    @Override
    public T getOrElse(T def) {
        return def;
    }

    @Override
    public boolean hasValue() {
        return false;
    }

}

public static Option<Integer> parseInt(String s) {
    Option<Integer> result = new None<Integer>();
    try {
        Integer value = Integer.parseInt(s);
        result = new Some<Integer>(value);
    } catch (NumberFormatException e) {
    }
    return result;
}

}

मुझे शायद आपके पैटर्न का उपयोग करके समाधान पसंद है। बहुत हैस्केली;)
रॉडरिगोल्प

1
यह समाधान अब पुराना है क्योंकि जावा 8 के बाद से java.util.Optional है:
Vlasec

2

आप सी ++ व्यवहार को भी दोहरा सकते हैं जो आप बहुत सरलता से चाहते हैं

public static boolean parseInt(String str, int[] byRef) {
    if(byRef==null) return false;
    try {
       byRef[0] = Integer.parseInt(prop);
       return true;
    } catch (NumberFormatException ex) {
       return false;
    }
}

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

int[] byRef = new int[1];
boolean result = parseInt("123",byRef);

चर के बाद resultयह सच है अगर सब कुछ ठीक हो गया और byRef[0]इसमें पार्स मूल्य शामिल है।

व्यक्तिगत रूप से, मैं अपवाद को पकड़ने के लिए चिपकूंगा।


2

जॉन स्कीट द्वारा दिया गया जवाब ठीक है, लेकिन मुझे एक nullइंटेगर ऑब्जेक्ट वापस देना पसंद नहीं है । मैं इस उलझन का उपयोग करने के लिए लगता है। जावा 8 के बाद से एक बेहतर विकल्प है (मेरी राय में), का उपयोग करते हुए OptionalInt:

public static OptionalInt tryParse(String value) {
 try {
     return OptionalInt.of(Integer.parseInt(value));
  } catch (NumberFormatException e) {
     return OptionalInt.empty();
  }
}

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


2

यदि आप जावा 8 या ऊपर का उपयोग कर रहे हैं, तो आप मेरे द्वारा जारी एक पुस्तकालय का उपयोग कर सकते हैं: https://github.com/robtimus/try-parse । इसमें इंट, लॉन्ग और बूलियन का समर्थन है जो अपवादों को पकड़ने पर भरोसा नहीं करता है। अमरूद के Ints.tryParse के विपरीत, यह OptionalInt / OptionalLong / Optional, https://stackoverflow.com/a/38451745/1180351 में बहुत अधिक लेकिन अधिक कुशल है।


1

मेरा जावा थोड़ा कठोर है, लेकिन मुझे देखने दें कि क्या मैं आपको सही दिशा में इंगित कर सकता हूं:

public class Converter {

    public static Integer parseInt(String str) {
        Integer n = null;

        try {
            n = new Integer(Integer.tryParse(str));
        } catch (NumberFormatException ex) {
            // leave n null, the string is invalid
        }

        return n;
    }

}

यदि आपका रिटर्न वैल्यू है null, तो आपके पास खराब वैल्यू है। अन्यथा, आपके पास एक मान्य है Integer


ओपी रूपांतरण परिणाम (संदर्भ के रूप में) के साथ साथ एक संकेत भी चाहता है कि रूपांतरण सफल था (या नहीं)।
जम्हाई २

1
@yawn: और एक अशक्त संदर्भ बिल्कुल यही संकेत देता है।
जॉन स्कीट

@ जॉन स्कीट: सही है लेकिन मैंने उनके इरादे को अलग तरीके से पढ़ा। उन्होंने सफलता / विफलता + मूल्य के बीच अंतर करने के लिए एक मध्यवर्ती वस्तु का उपयोग करने जैसा कुछ लिखा। C ++ बैकग्राउंड से आने से मुझे लगा कि अगर वह अशक्त (किसी वस्तु के बजाय) का उपयोग करना चाहता है, तो उसने पहली बार में सवाल नहीं पूछा होगा।
जवानी

"मूल्य" और "ऑब्जेक्ट" के बीच एक बड़ा अंतर है। एक शून्य संदर्भ एक साफ मूल्य है, लेकिन एक वस्तु नहीं है।
जॉन स्कीट

1. Integer.tryParseमानक जावा Integerवर्ग में कोई नहीं है । 2. करना new Integerअनावश्यक है (और इसके खिलाफ अनुशंसित) क्योंकि जावा बॉक्सिंग और स्वचालित रूप से अनबॉक्सिंग करता है। आपका जावा केवल थोड़ा जंग नहीं है, यह बहुत जंग है।
ADTC

1

क्या parseInt विधि forking के बारे में ?

यह आसान है, बस सामग्री को एक नई उपयोगिता में कॉपी-पेस्ट करें जो रिटर्न देता है Integerया Optional<Integer>रिटर्न के साथ फेंकता को प्रतिस्थापित करता है। ऐसा लगता है कि अंतर्निहित कोड में कोई अपवाद नहीं हैं, लेकिन बेहतर जांच है

पूरे अपवाद हैंडलिंग सामान को छोड़ कर, आप अवैध इनपुट पर कुछ समय बचा सकते हैं। और विधि JDK 1.0 के बाद से है, इसलिए यह संभव नहीं है कि आपको इसे अप-टू-डेट रखने के लिए बहुत कुछ करना होगा।


0

मैं आपको सुझाव दूंगा कि आप एक विधि पर विचार करें

 IntegerUtilities.isValidInteger(String s)

जिसे आप तब लागू करते हैं जब आप फिट दिखते हैं। यदि आप परिणाम वापस चाहते हैं - शायद इसलिए क्योंकि आप वैसे भी Integer.parseInt () का उपयोग करते हैं - आप सरणी ट्रिक का उपयोग कर सकते हैं।

 IntegerUtilities.isValidInteger(String s, int[] result)

जहाँ आप परिणाम को प्राप्त करते हैं [0] इस प्रक्रिया में मिले पूर्णांक मान को।


0

यह कुछ हद तक निकोले के समाधान के समान है:

 private static class Box<T> {
  T me;
  public Box() {}
  public T get() { return me; }
  public void set(T fromParse) { me = fromParse; }
 }

 private interface Parser<T> {
  public void setExclusion(String regex);
  public boolean isExcluded(String s);
  public T parse(String s);
 }

 public static <T> boolean parser(Box<T> ref, Parser<T> p, String toParse) {
  if (!p.isExcluded(toParse)) {
   ref.set(p.parse(toParse));
   return true;
  } else return false;
 }

 public static void main(String args[]) {
  Box<Integer> a = new Box<Integer>();
  Parser<Integer> intParser = new Parser<Integer>() {
   String myExclusion;
   public void setExclusion(String regex) {
    myExclusion = regex;
   }
   public boolean isExcluded(String s) {
    return s.matches(myExclusion);
   }
   public Integer parse(String s) {
    return new Integer(s);
   }
  };
  intParser.setExclusion("\\D+");
  if (parser(a,intParser,"123")) System.out.println(a.get());
  if (!parser(a,intParser,"abc")) System.out.println("didn't parse "+a.get());
 }

मुख्य विधि कोड को डिमोस करती है। पार्सर इंटरफ़ेस को लागू करने का एक और तरीका स्पष्ट रूप से निर्माण से "\ D +" सेट करना होगा, और विधियां कुछ भी नहीं होंगी।


0

आप हो सकता है अपनी खुद की रोल है, लेकिन यह बस के रूप में आसान उपयोग कॉमन्स के लिए लैंग के है StringUtils.isNumeric() विधि । यह स्ट्रिंग में प्रत्येक वर्ण पर पुनरावृति करने के लिए Character.isDigit () का उपयोग करता है ।


यदि अंकों में बहुत बड़ी संख्या होती है तो यह काम नहीं करेगा। Integer.parseInt Integer.MAX_VALUE (नकारात्मक पक्ष के लिए पाठ्यक्रम का एक समान) की तुलना में बड़ी संख्या के लिए एक अपवाद फेंकता है।
Searles

0

वे जिस तरह से मैं इस समस्या को संभालता है वह पुनरावर्ती है। कंसोल से डेटा पढ़ते समय उदाहरण के लिए:

Java.util.Scanner keyboard = new Java.util.Scanner(System.in);

public int GetMyInt(){
    int ret;
    System.out.print("Give me an Int: ");
    try{
        ret = Integer.parseInt(keyboard.NextLine());

    }
    catch(Exception e){
        System.out.println("\nThere was an error try again.\n");
        ret = GetMyInt();
    }
    return ret;
}

0

एक अपवाद से बचने के लिए, आप जावा की Format.parseObjectविधि का उपयोग कर सकते हैं । नीचे दिया गया कोड मूल रूप से Apache Common के IntegerValidator वर्ग का एक सरलीकृत संस्करण है ।

public static boolean tryParse(String s, int[] result)
{
    NumberFormat format = NumberFormat.getIntegerInstance();
    ParsePosition position = new ParsePosition(0);
    Object parsedValue = format.parseObject(s, position);

    if (position.getErrorIndex() > -1)
    {
        return false;
    }

    if (position.getIndex() < s.length())
    {
        return false;
    }

    result[0] = ((Long) parsedValue).intValue();
    return true;
}

आप या तो उपयोग कर सकते हैं AtomicIntegerया int[]सरणी चाल अपनी पसंद पर निर्भर करता है।

यहाँ मेरा परीक्षण है जो इसका उपयोग करता है -

int[] i = new int[1];
Assert.assertTrue(IntUtils.tryParse("123", i));
Assert.assertEquals(123, i[0]);

0

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

private int numberValue(String value, boolean val) throws IOException {
    //prints the value passed by the code implementer
    System.out.println(value);
    //returns 0 is val is passed as false
    Object num = 0;
    while (val) {
        num = br.readLine();
        try {
            Integer numVal = Integer.parseInt((String) num);
            if (numVal instanceof Integer) {
                val = false;
                num = numVal;
            }
        } catch (Exception e) {
            System.out.println("Error. Please input a valid number :-");
        }
    }
    return ((Integer) num).intValue();
}

1
System.out.println (एक बुरा अभ्यास है) का उपयोग न करें। इसका उपयोग करने में समस्या, यह है कि आपका कार्यक्रम तब तक प्रतीक्षा करेगा जब तक कि प्रिंटलाइन समाप्त नहीं हो जाती। लॉगिंग फ्रेमवर्क का उपयोग करने के लिए बेहतर दृष्टिकोण है।
उमर Hrynkiewicz

0

यह प्रश्न 8391979 का उत्तर है, "क्या जावा में एक इंट्रायपर्स है जो खराब डेटा के लिए अपवाद नहीं फेंकता है? [डुप्लिकेट]" जो कि बंद है और इस प्रश्न से जुड़ा हुआ है।

संपादित करें 2016 08 17: ltrimZeroes विधियों को जोड़ा गया और उन्हें tryParse () में बुलाया। संख्या में अग्रणी शून्य के बिना गलत परिणाम दे सकते हैं (कोड में टिप्पणी देखें)। अब सार्वजनिक स्थैतिक स्ट्रिंग ltrimZeroes (स्ट्रिंग क्रमांक) विधि भी है जो सकारात्मक और नकारात्मक "संख्याओं" (END Edit) के लिए काम करती है

नीचे आपको एक अत्यधिक गति अनुकूलित ट्रायपर्स () विधि (C # में समान) के साथ एक अल्पविकसित रैपर (मुक्केबाजी) वर्ग मिल रहा है जो स्ट्रिंग को खुद ही पार्स करता है और जावा से Integer.parseknt (स्ट्रिंग एस) की तुलना में थोड़ा तेज है:

public class IntBoxSimple {
    // IntBoxSimple - Rudimentary class to implement a C#-like tryParse() method for int
    // A full blown IntBox class implementation can be found in my Github project
    // Copyright (c) 2016, Peter Sulzer, Fürth
    // Program is published under the GNU General Public License (GPL) Version 1 or newer

    protected int _n; // this "boxes" the int value

    // BEGIN The following statements are only executed at the
    // first instantiation of an IntBox (i. e. only once) or
    // already compiled into the code at compile time:
    public static final int MAX_INT_LEN =
            String.valueOf(Integer.MAX_VALUE).length();
    public static final int MIN_INT_LEN =
            String.valueOf(Integer.MIN_VALUE).length();
    public static final int MAX_INT_LASTDEC =
            Integer.parseInt(String.valueOf(Integer.MAX_VALUE).substring(1));
    public static final int MAX_INT_FIRSTDIGIT =
            Integer.parseInt(String.valueOf(Integer.MAX_VALUE).substring(0, 1));
    public static final int MIN_INT_LASTDEC =
            -Integer.parseInt(String.valueOf(Integer.MIN_VALUE).substring(2));
    public static final int MIN_INT_FIRSTDIGIT =
            Integer.parseInt(String.valueOf(Integer.MIN_VALUE).substring(1,2));
    // END The following statements...

    // ltrimZeroes() methods added 2016 08 16 (are required by tryParse() methods)
    public static String ltrimZeroes(String s) {
        if (s.charAt(0) == '-')
            return ltrimZeroesNegative(s);
        else
            return ltrimZeroesPositive(s);
    }
    protected static String ltrimZeroesNegative(String s) {
        int i=1;
        for ( ; s.charAt(i) == '0'; i++);
        return ("-"+s.substring(i));
    }
    protected static String ltrimZeroesPositive(String s) {
        int i=0;
        for ( ; s.charAt(i) == '0'; i++);
        return (s.substring(i));
    }

    public static boolean tryParse(String s,IntBoxSimple intBox) {
        if (intBox == null)
            // intBoxSimple=new IntBoxSimple(); // This doesn't work, as
            // intBoxSimple itself is passed by value and cannot changed
            // for the caller. I. e. "out"-arguments of C# cannot be simulated in Java.
            return false; // so we simply return false
        s=s.trim(); // leading and trailing whitespace is allowed for String s
        int len=s.length();
        int rslt=0, d, dfirst=0, i, j;
        char c=s.charAt(0);
        if (c == '-') {
            if (len > MIN_INT_LEN) { // corrected (added) 2016 08 17
                s = ltrimZeroesNegative(s);
                len = s.length();
            }
            if (len >= MIN_INT_LEN) {
                c = s.charAt(1);
                if (!Character.isDigit(c))
                    return false;
                dfirst = c-'0';
                if (len > MIN_INT_LEN || dfirst > MIN_INT_FIRSTDIGIT)
                    return false;
            }
            for (i = len - 1, j = 1; i >= 2; --i, j *= 10) {
                c = s.charAt(i);
                if (!Character.isDigit(c))
                    return false;
                rslt -= (c-'0')*j;
            }
            if (len < MIN_INT_LEN) {
                c = s.charAt(i);
                if (!Character.isDigit(c))
                    return false;
                rslt -= (c-'0')*j;
            } else {
                if (dfirst >= MIN_INT_FIRSTDIGIT && rslt < MIN_INT_LASTDEC)
                    return false;
                rslt -= dfirst * j;
            }
        } else {
            if (len > MAX_INT_LEN) { // corrected (added) 2016 08 16
                s = ltrimZeroesPositive(s);
                len=s.length();
            }
            if (len >= MAX_INT_LEN) {
                c = s.charAt(0);
                if (!Character.isDigit(c))
                    return false;
                dfirst = c-'0';
                if (len > MAX_INT_LEN || dfirst > MAX_INT_FIRSTDIGIT)
                    return false;
            }
            for (i = len - 1, j = 1; i >= 1; --i, j *= 10) {
                c = s.charAt(i);
                if (!Character.isDigit(c))
                    return false;
                rslt += (c-'0')*j;
            }
            if (len < MAX_INT_LEN) {
                c = s.charAt(i);
                if (!Character.isDigit(c))
                    return false;
                rslt += (c-'0')*j;
            }
            if (dfirst >= MAX_INT_FIRSTDIGIT && rslt > MAX_INT_LASTDEC)
                return false;
            rslt += dfirst*j;
        }
        intBox._n=rslt;
        return true;
    }

    // Get the value stored in an IntBoxSimple:
    public int get_n() {
        return _n;
    }
    public int v() { // alternative shorter version, v for "value"
        return _n;
    }
    // Make objects of IntBoxSimple (needed as constructors are not public):
    public static IntBoxSimple makeIntBoxSimple() {
        return new IntBoxSimple();
    }
    public static IntBoxSimple makeIntBoxSimple(int integerNumber) {
        return new IntBoxSimple(integerNumber);
    }

    // constructors are not public(!=:
    protected IntBoxSimple() {} {
        _n=0; // default value an IntBoxSimple holds
    }
    protected IntBoxSimple(int integerNumber) {
        _n=integerNumber;
    }
}

वर्ग IntBoxSimple के लिए परीक्षण / उदाहरण कार्यक्रम:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class IntBoxSimpleTest {
    public static void main (String args[]) {
        IntBoxSimple ibs = IntBoxSimple.makeIntBoxSimple();
        String in = null;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        do {
            System.out.printf(
                    "Enter an integer number in the range %d to %d:%n",
                        Integer.MIN_VALUE, Integer.MAX_VALUE);
            try { in = br.readLine(); } catch (IOException ex) {}
        } while(! IntBoxSimple.tryParse(in, ibs));
        System.out.printf("The number you have entered was: %d%n", ibs.v());
    }
}

0

नियमित अभिव्यक्ति और डिफ़ॉल्ट पैरामीटर तर्क के साथ प्रयास करें

public static int parseIntWithDefault(String str, int defaultInt) {
    return str.matches("-?\\d+") ? Integer.parseInt(str) : defaultInt;
}


int testId = parseIntWithDefault("1001", 0);
System.out.print(testId); // 1001

int testId = parseIntWithDefault("test1001", 0);
System.out.print(testId); // 1001

int testId = parseIntWithDefault("-1001", 0);
System.out.print(testId); // -1001

int testId = parseIntWithDefault("test", 0);
System.out.print(testId); // 0

यदि आप Apache.commons.lang3 का उपयोग कर रहे हैं तो NumberUtils का उपयोग करके :

int testId = NumberUtils.toInt("test", 0);
System.out.print(testId); // 0

0

मैं एक अन्य प्रस्ताव में फेंकना चाहूंगा जो काम करता है अगर कोई विशेष रूप से पूर्णांक का अनुरोध करता है: बस लंबे समय का उपयोग करें और त्रुटि मामलों के लिए Long.MIN_VALUE का उपयोग करें। यह उस दृष्टिकोण के समान है जो रीडर में चार्ट के लिए उपयोग किया जाता है जहां Reader.read () एक चार्जर की रेंज में एक पूर्णांक देता है या -1 यदि रीडर खाली है।

फ्लोट और डबल के लिए, NaN का समान तरीके से उपयोग किया जा सकता है।

public static long parseInteger(String s) {
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {
        return Long.MIN_VALUE;
    }
}


// ...
long l = parseInteger("ABC");
if (l == Long.MIN_VALUE) {
    // ... error
} else {
    int i = (int) l;
}

0

मौजूदा उत्तरों को ध्यान में रखते हुए, मैंने Integer.parseIntकाम करने के लिए कॉपी पेस्ट और बढ़ाया स्रोत कोड , और मेरा समाधान किया है

  • संभावित धीमी कोशिश-कैच ( लैंग 3 नंबर यूटिल्स के विपरीत) का उपयोग नहीं करता है ) का ,
  • regexps का उपयोग नहीं करता है जो बहुत बड़ी संख्या को नहीं पकड़ सकता है,
  • मुक्केबाजी से बचता है (अमरूद के विपरीत) Ints.tryParse() ),
  • किसी भी आवंटन की आवश्यकता नहीं है (के विपरीत int[], Box,OptionalInt ),
  • CharSequenceसंपूर्ण के बजाय किसी भी या इसके एक हिस्से को स्वीकार करता हैString ,
  • किसी भी मूलांक का उपयोग कर सकते हैं Integer.parseInt कर सकते हैं, अर्थात, [2,36],
  • किसी भी पुस्तकालयों पर निर्भर नहीं करता है।

केवल नकारात्मक पक्ष यह है कि toIntOfDefault("-1", -1)और के बीच कोई अंतर नहीं है toIntOrDefault("oops", -1)

public static int toIntOrDefault(CharSequence s, int def) {
    return toIntOrDefault0(s, 0, s.length(), 10, def);
}
public static int toIntOrDefault(CharSequence s, int def, int radix) {
    radixCheck(radix);
    return toIntOrDefault0(s, 0, s.length(), radix, def);
}
public static int toIntOrDefault(CharSequence s, int start, int endExclusive, int def) {
    boundsCheck(start, endExclusive, s.length());
    return toIntOrDefault0(s, start, endExclusive, 10, def);
}
public static int toIntOrDefault(CharSequence s, int start, int endExclusive, int radix, int def) {
    radixCheck(radix);
    boundsCheck(start, endExclusive, s.length());
    return toIntOrDefault0(s, start, endExclusive, radix, def);
}
private static int toIntOrDefault0(CharSequence s, int start, int endExclusive, int radix, int def) {
    if (start == endExclusive) return def; // empty

    boolean negative = false;
    int limit = -Integer.MAX_VALUE;

    char firstChar = s.charAt(start);
    if (firstChar < '0') { // Possible leading "+" or "-"
        if (firstChar == '-') {
            negative = true;
            limit = Integer.MIN_VALUE;
        } else if (firstChar != '+') {
            return def;
        }

        start++;
        // Cannot have lone "+" or "-"
        if (start == endExclusive) return def;
    }
    int multmin = limit / radix;
    int result = 0;
    while (start < endExclusive) {
        // Accumulating negatively avoids surprises near MAX_VALUE
        int digit = Character.digit(s.charAt(start++), radix);
        if (digit < 0 || result < multmin) return def;
        result *= radix;
        if (result < limit + digit) return def;
        result -= digit;
    }
    return negative ? result : -result;
}
private static void radixCheck(int radix) {
    if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
        throw new NumberFormatException(
                "radix=" + radix + " ∉ [" +  Character.MIN_RADIX + "," + Character.MAX_RADIX + "]");
}
private static void boundsCheck(int start, int endExclusive, int len) {
    if (start < 0 || start > len || start > endExclusive)
        throw new IndexOutOfBoundsException("start=" + start + " ∉ [0, min(" + len + ", " + endExclusive + ")]");
    if (endExclusive > len)
        throw new IndexOutOfBoundsException("endExclusive=" + endExclusive + " > s.length=" + len);
}

0

शायद कोई और अधिक सामान्य दृष्टिकोण की तलाश में है, क्योंकि जावा 8 में पैकेज है java.util.functionजो आपूर्तिकर्ता कार्यों को परिभाषित करने की अनुमति देता है। आपके पास एक फ़ंक्शन हो सकता है जो एक सप्लायर और एक डिफ़ॉल्ट मान निम्नानुसार है:

public static <T> T tryGetOrDefault(Supplier<T> supplier, T defaultValue) {
    try {
        return supplier.get();
    } catch (Exception e) {
        return defaultValue;
    }
}

इस फ़ंक्शन के साथ, आप किसी भी पार्सिंग विधि या यहां तक ​​कि अन्य तरीकों को भी निष्पादित कर सकते हैं जो यह सुनिश्चित करते हुए एक अपवाद फेंक सकते हैं कि कोई अपवाद कभी भी फेंका नहीं जा सकता है:

Integer i = tryGetOrDefault(() -> Integer.parseInt(stringValue), 0);
Long l = tryGetOrDefault(() -> Long.parseLong(stringValue), 0l);
Double d = tryGetOrDefault(() -> Double.parseDouble(stringValue), 0d);

-1

आप एक अशक्त वस्तु का उपयोग कर सकते हैं:

public class Convert {

    @SuppressWarnings({"UnnecessaryBoxing"})
    public static final Integer NULL = new Integer(0);

    public static Integer convert(String integer) {

        try {
            return Integer.valueOf(integer);
        } catch (NumberFormatException e) {
            return NULL;
        }

    }

    public static void main(String[] args) {

        Integer a = convert("123");
        System.out.println("a.equals(123) = " + a.equals(123));
        System.out.println("a == NULL " + (a == NULL));

        Integer b = convert("onetwothree");
        System.out.println("b.equals(123) = " + b.equals(123));
        System.out.println("b == NULL " + (b == NULL));

        Integer c = convert("0");
        System.out.println("equals(0) = " + c.equals(0));
        System.out.println("c == NULL " + (c == NULL));

    }

}

इस उदाहरण में मुख्य का परिणाम है:

a.equals(123) = true
a == NULL false
b.equals(123) = false
b == NULL true
c.equals(0) = true
c == NULL false

इस तरह से आप हमेशा असफल रूपांतरण के लिए परीक्षण कर सकते हैं लेकिन फिर भी परिणाम के साथ काम करते हैं। आप NULL प्रतिनिधित्व (। 0) संख्या को भी ट्विक करना चाह सकते हैं ।


क्या होगा अगर 'स्ट्रिंग पूर्णांक' स्ट्रिंग शाब्दिक "0" है? अवैध इनपुट होने पर आपको कभी पता नहीं चलेगा।
बार्ट कियर्स

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

क्यों होता है पतन? मेरा उत्तर सही है और यह लाभ (शून्य से अधिक) प्रदान करता है कि आप हमेशा NPEs से निपटने के लिए राहत देने वाले इंटर्गर (शून्य के बजाय) के एक वैध उदाहरण से निपटते हैं।
जम्हाई

वास्तविक पूर्णांक से अशक्त होना हालांकि उपयोगी है। आपको यह जानने के लिए परिणाम का परीक्षण करना चाहिए कि पार्स सफल हुआ या नहीं। छिपाना कि पीछे और अन्यथा उपयोग करने योग्य वस्तु समस्याओं का एक नुस्खा है, आईएमओ।
जॉन स्कीट

अधिक डाउनवोट्स - दिलचस्प! चूंकि / मैं एसओ के लिए नया था और सभी मतदाता मुझे समझा सकते थे कि क्यों?
जम्हाई

-1

आपको अपने मूल्यों को मान्य करने के लिए अपवादों का उपयोग नहीं करना चाहिए

एकल चरित्र के लिए एक सरल उपाय है:

Character.isDigit()

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

NumberUtils.isNumber()

कृपया https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/NumberUtils.html देखें


«जाँचता है कि स्ट्रिंग एक वैध जावा संख्या है या नहीं। मान्य संख्याओं में 0x क्वालीफायर के साथ चिह्नित हेक्साडेसिमल, वैज्ञानिक संकेतन और एक प्रकार के क्वालीफायर (जैसे 123 एल) के साथ चिह्नित संख्याएं शामिल हैं। » यह वह नहीं है जिसके साथ पार्स किया जा सकता है Integer.parseInt
मिह_x64
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.