Integer.parseInt () encapsulate করার ভাল উপায়


93

আমার একটি প্রকল্প রয়েছে যা আমরা প্রায়শই Integer.parseInt()একটি স্ট্রিংকে একটি ইনটেমে রূপান্তর করতে ব্যবহার করি । যখন কোনও কিছু ভুল হয়ে যায় (উদাহরণস্বরূপ, এটি Stringএকটি সংখ্যা নয় তবে চিঠি a, বা যাই হোক না কেন) এই পদ্ধতিটি একটি ব্যতিক্রম ছুঁড়ে দেবে। যাইহোক, যদি আমার কোডটিতে আমাকে সর্বত্র ব্যতিক্রমগুলি পরিচালনা করতে হয় তবে এটি খুব তাড়াতাড়ি দেখতে খুব কুরুচিপূর্ণ হতে শুরু করে। আমি এটি একটি পদ্ধতিতে রাখতে চাই, তবে রূপান্তরটি ভুল হয়ে গেছে তা দেখানোর জন্য কীভাবে পরিষ্কার মান ফিরিয়ে আনতে হবে তার আমার কোনও ধারণা নেই।

সি ++ তে আমি এমন একটি পদ্ধতি তৈরি করতে পারতাম যা কোনও পয়েন্টারকে কোন প্রকারের কাছে গ্রহণ করে এবং পদ্ধতিটি নিজেই সত্য বা মিথ্যা ফিরে আসতে দেয়। তবে যতদূর আমি জানি, জাভাতে এটি সম্ভব নয়। আমি এমন একটি বস্তুও তৈরি করতে পারি যাতে সত্য / মিথ্যা ভেরিয়েবল এবং রূপান্তরিত মান থাকে তবে এটি আদর্শ বলেও মনে হয় না। একই জিনিসটি বিশ্বব্যাপী মানের জন্য যায় এবং এটি মাল্টিথ্রেডিংয়ের সাথে আমাকে কিছুটা সমস্যা দিতে পারে।

সুতরাং এটি করার একটি পরিষ্কার উপায় আছে?


স্ট্রিং অক্ষর সব দশমিক সংখ্যা, যে প্রথম অক্ষর ছাড়া হতে হবে ... । কোডের সর্বত্র ব্যতিক্রমগুলি পরিচালনা করার পরিবর্তে, পার্স পদ্ধতিতে কল করার আগে কেবল স্ট্রিং বিন্যাসটি পরীক্ষা করুন।
লাইটম্যান

এমন একটি রেজেেক্স লেখা অসম্ভবের পরে যা বৈধ 32-বিট স্বাক্ষরিত পূর্ণসংখ্যার এবং কোনও অবৈধকে ক্যাপচার করবে। 2147483647 একটি আইনী intযখন 2147483648 না।
সেবা আলেক্সিয়েভ

উত্তর:


142

পার্স ব্যর্থতায় ফিরে আপনি কোনওটির Integerপরিবর্তে একটি ফিরিয়ে দিতে পারেন ।intnull

এটি একটি লজ্জার বিষয় যা জাভা অভ্যন্তরীণভাবে ছড়িয়ে দেওয়া ব্যতিক্রম ছাড়া এটি করার কোনও উপায় প্রদান করে না - আপনি ব্যতিক্রমটি আড়াল করতে পারেন (এটি ধরে এবং নাল ফিরে দিয়ে) তবে আপনি যদি শত শতকে পার্স করছেন তবে এটি পারফরম্যান্সের সমস্যা হতে পারে ব্যবহারকারী দ্বারা সরবরাহিত ডেটা হাজার হাজার বিট।

সম্পাদনা: এ জাতীয় পদ্ধতির কোড:

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

মনে রাখবেন যে আমি textশূন্য হলে আমার মাথার উপরের অংশটি নিশ্চিত নয় যে এটি কী করবে । আপনার এটি বিবেচনা করা উচিত - যদি এটি কোনও ত্রুটি উপস্থাপন করে (যেমন আপনার কোডটি একটি অবৈধ মান ভালভাবে পাস করতে পারে তবে কখনই নাল পাস করা উচিত নয়) তবে একটি ব্যতিক্রম ছুঁড়ে দেওয়া উপযুক্ত; যদি এটি কোনও ত্রুটি উপস্থাপন করে না তবে আপনার অন্য কোনও অবৈধ মান হিসাবে যেমনটি হবে ঠিক তেমন শূন্য হওয়া উচিত।

মূলত এই উত্তরটি new Integer(String)নির্মাণকারী ব্যবহার করেছে ; এটি এখন ব্যবহার করে Integer.parseIntএবং একটি বক্সিং অপারেশন; এইভাবে ছোট মানগুলি ক্যাশেড Integerঅবজেক্টগুলিতে বাক্সবন্দী হয়ে যায় এবং এই পরিস্থিতিতে এটি আরও দক্ষ করে তোলে।


4
কিভাবে এই সাহায্য করে? কল সাইটের জন্য এটির প্রয়োজন হবে: <b> টেম্প = ট্রাই পার্স (...); if (টেম্প! = নাল) {টার্গেট = টেম্প; পুনরুদ্ধারের অংশে সম্ভাব্য থ্রো ব্যতিক্রম সহ} অন্যথায় {পুনরুদ্ধারের ক্রিয়া করুন}; </ b>। মূল সূচনায় কল সাইটের জন্য <b> চেষ্টা করে লক্ষ্য = (...) চেষ্টা করা উচিত p ক্যাচ (...) recovery পুনরুদ্ধারের ক্রিয়া করুন} </ b> কেবল ক্যাচ ক্লজটি সরিয়ে পুনরুদ্ধারে বাস্তবায়িত হওয়ার ক্ষেত্রে তুচ্ছ থ্রো ব্যতিক্রম সহ with প্রস্তাবিত সমাধানটি কীভাবে বুঝতে সহজভাবে এটি তৈরি করে (এটিতে একটি যাদু কৌশল রয়েছে) বা কোনওভাবে কোডের পরিমাণ হ্রাস করতে পারে?
ইরা

15
nullনিয়মিতভাবে ব্যতিক্রমগুলি পরিচালনা করার চেয়ে রেফারেন্সগুলির জন্য যাচাই করার জন্য কোডটি সাধারণত পরিষ্কার থাকে।
অ্যাডাম মারাস

এটি মান হিসাবে নালগুলি পাস করা এড়াতে আরও পরিষ্কার তবে এর পরিবর্তে কোনওভাবে ইঙ্গিত দেওয়া হয়েছে যে এন ত্রুটি ঘটেছে; ব্যতিক্রমগুলি প্রবাহ নিয়ন্ত্রণের জন্য ব্যবহার করা উচিত নয়।
এসকো

4
@ স্টিভ কুও: কেন? সুবিধা কোথায়? তারা দুজনেই কি প্রতিটি সময় নতুন পূর্ণসংখ্যা তৈরি করে? যদি কিছু হয় তবে আমি ছোট মানগুলির জন্য ক্যাশে সুবিধা গ্রহণের জন্য Integer.parseInt ব্যবহার করতে এবং অটোবক্সিংটিকে এটির যত্ন নিতে দেই ted
জন স্কিটি

4
@ ভ্ল্যাক এবং কেবল ptionচ্ছিক নয়, অপিমালিকদের জন্য imচ্ছিকরূপের জন্য বিশেষ সংস্করণ।
জোশুয়া টেলর

37

এটি সংখ্যা না হলে আপনি কোন আচরণের প্রত্যাশা করবেন?

উদাহরণস্বরূপ, যদি ইনপুটটি নম্বর না থাকে তবে আপনার প্রায়শই ব্যবহারের জন্য একটি ডিফল্ট মান থাকে, তবে এর মতো কোনও পদ্ধতি কার্যকর হতে পারে:

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

যখন ইনপুটটি বিশ্লেষণ করা যায় না তখন একই রকম পদ্ধতিগুলি বিভিন্ন ডিফল্ট আচরণের জন্য লেখা যেতে পারে।


30

কিছু ক্ষেত্রে আপনার ব্যর্থতা-দ্রুত পরিস্থিতিতে হিসাবে পার্সিং ত্রুটিগুলি পরিচালনা করা উচিত, তবে অন্য ক্ষেত্রে যেমন অ্যাপ্লিকেশন কনফিগারেশন, আমি অ্যাপাচি কমন্স ল্যাং 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
সাবধান হও. এর সাথে রেজেক্সটি 0 দিয়ে শুরু হওয়া পূর্ণসংখ্যার সাথে মেলে যা পরে একটি সংখ্যা ফরম্যাটএক্সসেপশন নিক্ষেপ করবে। এই st (?: [1-9] \ d * | 0) $ থেকে স্ট্যাকওভারফ্লো
গুজ

4
এই নির্দিষ্ট রেজেক্সটি নেতিবাচক সংখ্যাগুলি পরিচালনা করবে না।
ব্র্যাড কাপিট

7
এছাড়াও এটি সংখ্যার ব্যাপ্তিগুলিকে অন্তর্ভুক্ত করে না যা পূর্ণসংখ্যার সীমার বাইরে
মোহাম্মদ ইয়াহিয়া

10

নেই Ints.tryParse()মধ্যে পেয়ারা । এটি অ-সংখ্যাসূচক স্ট্রিংয়ে ব্যতিক্রম ছুঁড়ে না, তবে এটি নাল স্ট্রিংয়ে ব্যতিক্রম ছুঁড়ে ফেলে।


4

প্রশ্নের উত্তরগুলি পড়ার পরে আমি মনে করি এনক্যাপসুলেটিং বা প্যাটারিং মোড়ানোর জন্য পার্সইন্ট পদ্ধতিটি প্রয়োজনীয় নয়, এমনকি একটি ভাল ধারণাও নয়।

জনের পরামর্শ অনুসারে আপনি 'নাল' ফিরতে পারেন, তবে এটি নাল-চেকের মাধ্যমে চেষ্টা বা ক্যাপচার প্রতিস্থাপনের জায়গাটি কমবেশি করে দিচ্ছে। আচরণের ক্ষেত্রে সামান্য পার্থক্য রয়েছে যদি আপনি 'ভুলে যান' ত্রুটি পরিচালনা করে: আপনি যদি ব্যতিক্রমটি ধরেন না তবে কোনও অ্যাসাইনমেন্ট নেই এবং বাম দিকের পরিবর্তনশীল এটি পুরানো মান রাখে। যদি আপনি শূন্যতার জন্য পরীক্ষা না করেন তবে আপনি সম্ভবত জেভিএম (এনপিই) এর দ্বারা আঘাত হানবেন।

হ্যাঁর পরামর্শ আমার কাছে আরও মার্জিত দেখাচ্ছে কারণ আমি কিছু ত্রুটি বা ব্যতিক্রমী অবস্থার সিগন্যাল করতে নাল ফিরে ফিরতে পছন্দ করি না। এখন আপনাকে পূর্বনির্ধারিত বস্তুর সাথে রেফারেন্সিয়াল সমতা পরীক্ষা করতে হবে, এটি একটি সমস্যা নির্দেশ করে। তবে, অন্যরা যেমন যুক্তি দেয়, আবার যদি আপনি পরীক্ষা করতে 'ভুলে যান' এবং কোনও স্ট্রিং অপসারণযোগ্য হয় তবে প্রোগ্রামটি আপনার 'ERROR' বা 'NULL' অবজেক্টের অভ্যন্তরে মোড়ানো থাকে।

নিকোলয়ের সমাধানটি আরও বেশি অবজেক্ট ভিত্তিক এবং অন্যান্য রেপার ক্লাসের পাশাপাশি পার্সএক্সএক্সএক্সএক্স পদ্ধতিতে কাজ করবে। তবে শেষ পর্যন্ত, তিনি কেবল অপারেশননোটসপোর্টেড ব্যতিক্রম দ্বারা নাম্বার ফর্ম্যাট এক্সসেপশনটি প্রতিস্থাপন করেছিলেন - আবার আপনাকে অপসারণযোগ্য ইনপুটগুলি পরিচালনা করার জন্য চেষ্টা / ক্যাচ দরকার।

সুতরাং, এটি আমার সমাপ্তি পার্সেন্ট পদ্ধতিটি আবদ্ধ না করার উপসংহার। আমি কেবল তখনই ক্যাপসুলেট করতাম যদি আমি পাশাপাশি কিছু প্রয়োগ করতে পারি (অ্যাপ্লিকেশন নির্ভর) ত্রুটি পরিচালনাও করতে পারি।


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;
}

}

আমি সম্ভবত প্যাটার্ন ব্যবহার করে আপনার সমাধান পছন্দ করি। খুব হাস্কেল্লি;)
রডরিগেল্প

4
এই সমাধানটি এখন পুরানো হয়েছে কারণ এখানে
জাভা.ইউটি.এই alচ্ছিক

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 । এটি অন্তর্নিহিত, দীর্ঘ এবং বুলিয়ান জন্য সমর্থন রয়েছে যা ব্যতিক্রমগুলি ধরায় নির্ভর করে না। পেয়ারার ইনস.ট্রি পার্সের বিপরীতে এটি ptionচ্ছিকাল / ntচ্ছিকালং / ptionচ্ছিকটি ফেরত দেয়, অনেকটা 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


ওপি রূপান্তরকরণের ফলাফল (একটি রেফারেন্স হিসাবে) এবং আরও একটি ইঙ্গিত দেয় যে রূপান্তরটি সফল হয়েছিল (বা না)।
সোমবার

4
@ ইয়ান: এবং একটি নাল রেফারেন্স ঠিক সেই ইঙ্গিত দেয়।
জন স্কিটি

@ জন স্কিটি: সঠিক তবে আমি তার উদ্দেশ্যটি অন্যভাবে পড়েছি। সাফল্য / ব্যর্থতা + মানের মধ্যে পার্থক্য রাখতে তিনি একটি মধ্যবর্তী বস্তু ব্যবহার করার মতো কিছু লিখেছিলেন। একটি সি ++ ব্যাকগ্রাউন্ড থেকে এসেছি আমি বুঝতে পেরেছিলাম যে তিনি যদি নাল (কোনও বস্তুর পরিবর্তে) ব্যবহার করতে চান তবে তিনি প্রথমে প্রশ্নটি জিজ্ঞাসা করবেন না।
হাই তোলা

"মান" এবং "অবজেক্ট" এর মধ্যে একটি বড় পার্থক্য রয়েছে। নাল রেফারেন্সটি একটি পরিষ্কার মান, তবে কোনও অবজেক্ট নয়।
জন স্কিটি

1. Integer.tryParseস্ট্যান্ডার্ড জাভা Integerক্লাসে নেই। ২. new Integerজাভা স্বয়ংক্রিয়ভাবে বক্সিং এবং আনবক্সিং করার কারণে করণ অপ্রয়োজনীয় (এবং এর বিরুদ্ধে প্রস্তাবিত) is আপনার জাভা কিছুটা মরিচা নয়, এটি খুব মরিচা।
এডিটিসি

1

পার্সইন্ট পদ্ধতিটি কাঁটাচামচ করার বিষয়ে কী ?

এটা সহজ, শুধু বিষয়বস্তু একটি নতুন উপযোগ করতে কপি-পেস্ট করুন আয় Integerবা Optional<Integer>এবং প্রতিস্থাপন আয় সঙ্গে ছোঁড়ার। মনে হচ্ছে অন্তর্নিহিত কোডটিতে কোনও ব্যতিক্রম নেই, তবে আরও ভাল চেক

সম্পূর্ণ ব্যতিক্রম হ্যান্ডলিং স্টাফ এড়িয়ে আপনি অবৈধ ইনপুট কিছু সময় বাঁচাতে পারেন। এবং জেডিকে ১.০ থেকে পদ্ধতিটি রয়েছে, সুতরাং এটি আপ টু ডেট রাখার জন্য আপনাকে বেশি কিছু করতে হবে না সম্ভবত।


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());
 }

মূল পদ্ধতিটি কোডটি ডেমোস করে। পার্সার ইন্টারফেসটি বাস্তবায়নের আরেকটি উপায় হ'ল নির্মাণ থেকে "\ ডি +" সেট করা এবং পদ্ধতিগুলি কিছুই করতে না পারে।


0

আপনি পারে আপনার নিজের রোল, কিন্তু এটা ঠিক যেমন সহজ ব্যবহার কমন্স থেকে ল্যাঙ এর এর StringUtils.isNumeric() পদ্ধতি । এটি স্ট্রিংয়ের প্রতিটি চরিত্রের পুনরাবৃত্তি করতে ক্যারেক্টার.আইডিজিট () ব্যবহার করে।


তারপরে অঙ্কটিতে খুব বেশি সংখ্যক সংখ্যা থাকলে এটি কাজ করবে না। Integer.parseInt পূর্ণসংখ্যার চেয়ে বড় সংখ্যার জন্য একটি ব্যতিক্রম ছোঁড়ে MA MAX_VALUE (অবশ্যই নেতিবাচক দিকের জন্য)
সেরিলস

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পদ্ধতিটি ব্যবহার করতে পারেন । নীচের কোডটি মূলত অ্যাপাচি কমন এর ইন্টিজারভালিডেটর শ্রেণীর একটি সরল সংস্করণ ।

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();
}

4
System.out.println (একটি খারাপ অভ্যাস) ব্যবহার করবেন না। এটি ব্যবহার করে সমস্যা হচ্ছে, আপনার প্রোগ্রামটি প্রিন্টলান শেষ না হওয়া পর্যন্ত অপেক্ষা করবে। লগিংয়ের কাঠামো ব্যবহার করা আরও ভাল পন্থা।
ওমর হ্রিনকিউইজ

0

এটি 8391979 প্রশ্নের উত্তর, "জাভাতে কি এমন একটি অন্তর্ভুক্ত পার্স রয়েছে যা খারাপ ডেটার জন্য ব্যতিক্রম ঘটায় না? [সদৃশ]" যা বন্ধ এবং এই প্রশ্নের সাথে যুক্ত রয়েছে।

2016 সম্পাদনা করুন 08 17: ltrimZeroes পদ্ধতি যুক্ত করে ট্রাই পার্সে () এ তাদের ডাকা হয়েছে। নম্বর স্ট্রিংয়ে শীর্ষস্থানীয় জিরো ব্যতীত ভুল ফলাফল দিতে পারে (কোডে মন্তব্য দেখুন)। এখানে এখন পাবলিক স্ট্যাটিক স্ট্রিং ltrimZeroes (স্ট্রিং নম্বর স্ট্রিং) পদ্ধতিও রয়েছে যা ইতিবাচক এবং নেতিবাচক "সংখ্যার" জন্য কাজ করে (সমাপ্ত সম্পাদনা)

নীচে আপনি একটি উচ্চ গতির অপ্টিমাইজড ট্রাই পার্স () পদ্ধতি (সি # এর মতোই) এর সাথে আন্তঃসার জন্য একটি প্রাথমিক র‌্যাপার (বক্সিং) শ্রেণি খুঁজে পান যা স্ট্রিংটি নিজেই বিশ্লেষণ করে এবং জাভা থেকে ইন্টিজার.পারসেন্ট (স্ট্রিং) এর থেকে কিছুটা দ্রুত:

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;
    }
}

পরীক্ষার / শ্রেণীর ইন্টারবক্সসিম্পল জন্য উদাহরণ প্রোগ্রাম:

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 ব্যবহার করেন তবে নম্বরের ব্যবহার করে :

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

0

আমি অন্য একটি প্রস্তাব ফেলতে চাই যা যদি বিশেষত কোনও পূর্ণসংখ্যার জন্য অনুরোধ করে তবে তা কার্যকর হয়: ত্রুটি মামলার জন্য সহজভাবে দীর্ঘ ব্যবহার করুন এবং দীর্ঘ ব্যবহার করুন M MIN_VALUE। এটি এমন পদ্ধতির অনুরূপ যা পাঠকের খাতায় অক্ষরের জন্য ব্যবহৃত হয় যেখানে পাঠক ফাঁকা থাকলে পাঠক.রেড () একটি চর বা -1 এর পরিসীমাতে পূর্ণসংখ্যা ফেরত দেয়।

ফ্লোট এবং ডাবলের জন্য, এনএএন একইভাবে ব্যবহার করা যেতে পারে।

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 নম্বর ইউটিলের বিপরীতে ),
  • রিজেক্সপস ব্যবহার করে না যা খুব বেশি সংখ্যক ধরতে পারে না,
  • বক্সিং এড়ানো (পেয়ারা থেকে পৃথক Ints.tryParse()),
  • (অসদৃশ কোনো বরাদ্দ প্রয়োজন হয় না int[], Box, OptionalInt),
  • CharSequenceসম্পূর্ণর পরিবর্তে এর যে কোনও বা কোনও অংশ গ্রহণ করে String,
  • যে কোনও মূলক ব্যবহার করতে Integer.parseIntপারে, যা [২,৩ 2,],
  • কোনও লাইব্রেরির উপর নির্ভর করে না।

একমাত্র ক্ষতি হ'ল 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 প্রতিনিধিত্ব করে ( number 0) নম্বরটি টুইট করতেও পারেন ।


'স্ট্রিং পূর্ণসংখ্যা' স্ট্রিং আক্ষরিক "0" হলে কী হবে? অবৈধ ইনপুট ছিল কিনা তা আপনি কখনই জানতে পারবেন না।
বার্ট কায়ার্স

আমার ধারনা যা দুটি পূর্ণসংখ্যার জন্য অপারেটরটি মান বা রেফারেন্সের তুলনা করে কিনা তার উপর নির্ভর করে। যদি এটি মানগুলির সাথে তুলনা করে তবে সমস্যাটি বিদ্যমান। যদি এটি রেফারেন্সগুলির সাথে তুলনা করে তবে এটি আমার উত্তরের সমতূল্যভাবে কাজ করবে।
অ্যাডাম মারাস

ডাউনটা কেন? আমার উত্তরটি সঠিক এবং আপনি সুবিধাটি (নাল ছাড়িয়ে) উপস্থাপন করেন যা আপনি সর্বদা এনটিপিসের সাথে ডিল করার জন্য আপনাকে স্বস্তির জন্য পূর্ণসংখ্যার (নাল পরিবর্তে) একটি বৈধ উদাহরণ সহকারে ডিল করেন।
হাই তোলা

একটি বাস্তব পূর্ণসংখ্যার থেকে নালকে আলাদা করা যদিও দরকারী । আপনি উচিত অকার্যকরতা জন্য ফলাফলের পরীক্ষা হবে, জানতে পার্স সফল থাকুক বা না থাকুক। পিছনে এবং অন্যথায় ব্যবহারযোগ্য অবজেক্টটি লুকিয়ে রাখা সমস্যাগুলির একটি রেসিপি, আইএমও।
জন স্কিটি

আরও ডাউনভোটস - আকর্ষণীয়! যেহেতু / আমি এসও তে নতুন এবং সমস্ত ভোটার আমাকে কেন ব্যাখ্যা করতে পারেন?
হাই তোলা

-1

আপনার মানগুলি বৈধ করার জন্য আপনাকে ব্যতিক্রমগুলি ব্যবহার করা উচিত নয়

একক চরিত্রের জন্য একটি সহজ সমাধান রয়েছে:

Character.isDigit()

দীর্ঘতর মানগুলির জন্য কিছু ব্যবহার ব্যবহার করা ভাল। আপাচি দ্বারা সরবরাহ করা নম্বরগুলি এখানে নিখুঁতভাবে কাজ করবে:

NumberUtils.isNumber()

দয়া করে https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/NumberUtils.html দেখুন


St স্ট্রিংটি একটি বৈধ জাভা নম্বর কিনা তা যাচাই করে। বৈধ সংখ্যার মধ্যে 0x কোয়ালিফায়ারের সাথে চিহ্নিত হেক্সাডেসিমাল, বৈজ্ঞানিক স্বরলিপি এবং একটি ধরণের কোয়ালিফায়ার (উদাহরণস্বরূপ 123L) দিয়ে চিহ্নিত নম্বর অন্তর্ভুক্ত রয়েছে » এটি যা পার্স করা যায় তা নয় Integer.parseInt
মিহা_এক্স 64
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.