I want to check is a String I pass to Integer.valueOf(String s) a valid String to parse. If one is not parsable I need to return 0.
I do it in the following way:
try{
Integer.valueOf(String s)
} catch(NumberFormatException e) {
return 0;
}
Is it a bad way to do that?
method 1: use a regular expression to check for validity of being a number
public static int parseStrToInt(String str) {
if (str.matches("\\d+")) {
return Integer.parseInt(str);
} else {
return 0;
}
}
method 2: use Java's built-in java.text.NumberFormat object to see if, after parsing the string the parser position is at the end of the string. If it is, we can assume the entire string is numeric
public static int strToInt(String str) {
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(str, pos);
if (str.length() == pos.getIndex()) {
return Integer.parseInt(str);
} else {
return 0;
}
}
I would have used:
s = s.trim(); // sometimes user inputs white spaces without knowing it
int value;
if (s.length() == 0) {
value = 0; // obviously not a string
} else {
try{
value = Integer.valueOf(s);
} catch(NumberFormatException e) {
value = 0;
}
}
// do whatever you like here
Hi this will do even the number is double or long, which is useful always while parsing.
List<String> myStrings = new ArrayList<String>();
myStrings.add("text");
myStrings.add("25");
myStrings.add("102.23333333");
myStrings.add("22.34");
NumberFormat nf = NumberFormat.getInstance();
for( String text : myStrings){
try {
System.out.println( nf.parse(text));
} catch (ParseException e) {
e.printStackTrace();
}
}
Related
I am currently trying to create a method that turn words into their plural equivalent. In doing this I have some cascaded if's that use the .endsWith() method.
I have a string array of consonants(+y) which I want to use as a parameter for the endsWith() method. But it says that I need to change type consonantandY method to String and not String[]. If I do that, I can't make an array...
How do I get around this?
private String regularPluralForm(String word) {
String s2 = "";
if(word.endsWith("s)")) {
s2 = "es";
} else if(word.endsWith("x)")) {
s2 = "es";
} else if(word.endsWith("z")) {
s2 = "es";
} else if(word.endsWith("ch")) {
s2 = "es";
} else if(word.endsWith("sh")) {
s2 = "es";
} else if(word.endsWith(consonantAndY)) {
}
String correctWord = word+s2;
return correctWord;
}
private static final String[] consonantAndY = {"by","cy","dy","fy",
"gy","hy","jy","ky"
,"ly","my","ny"
,"py","qy","ry","sy"
,"ty","vy","wy","xy"
,"yy","zy"};
}
Rather than looping over consonantAndY, calling endsWith on each element of that array, you can use a regular expression.
} else if (word.matches(".*[bcdfghjklmnpqrstvwxyz]y")) {
Iterate over the array
else {
boolean matches = false;
for(String s : constantAndY) {
if (word.endsWith(s)) {
matches = true;
break;
}
}
but better is apparently the answer above with java 8
With java 8 you can do
if( Arrays.asList(consonantAndY).stream().anyMatch(t -> word.endsWith(t)) ){
// do something
}
Demo
Could make a helper method called endsWith that takes the array as a parameter.
int consonantIndex = -1;
if (...) { ... }
else if((consonantIndex = endsWith(word, consonantAndY)) != -1) {
s2 = consonantAndY[consonantIndex];
}
private int endsWith(String s, String... suffixes) {
for (int i = 0; i < suffixes.length; i++) {
if (s.endsWith(suffixes[i])) {
return i;
}
}
return -1;
}
I'm trying to re-write this code in a cleaner way:
public static void main(String[] args) {
if(checkArgs(args) < 0) return;
return;
}
private static int checkArgs(String[] args) {
if (args.length == 0) {
System.out.println("Error: No Args");
return -1;
}
try{ //If it's a number
int myNumber = Integer.parseInt(args[0]);
System.out.println("My number is: " + myNumber);
}
catch (Exception e) {//If it's a String
try{
String[] myStr = args ;
System.out.print("My String is ");
for (int i=0; i<args.length; i++) {
myStr[i] = args[i];
System.out.print(myStr[i]);
}
System.out.print("\n");
return 0;
}
catch(Exception err){
System.out.println("Error");
return -1;
}
}
return 0;
}
The code checks the program args and tell the user if it's a String or just a number.
Any ideas on how to re-write this code without using try-catch?
First, you don't really need the second try...catch. This code:
String[] myStr = args ;
System.out.print("My String is ");
for (int i=0; i<args.length; i++) {
myStr[i] = args[i];
System.out.print(myStr[i]);
}
System.out.print("\n");
return 0;
Is not throwing any checked exception and is not very likely to ever throw a runtime exception.
Second, this code also has parts that are simply not needed - the myStr array - you assign the args array to it, and then you assign each element individually to it. And it's a local variable so it's going to go away as soon as you return anyway.
So:
System.out.print("My String is ");
for (int i=0; i<args.length; i++) {
System.out.print(args[i]);
}
System.out.print("\n");
return 0;
would do the same thing and is not going to throw exceptions.
Now, as for checking the integer - I think just using it like this and catching the exception is good enough. Just catch NumberFormatException instead of Exception. It's never a good idea to do a catch-all.
But if you insist on a method without try-catch, you could do something like this:
private static boolean checkInt(String str) {
if ( ! str.matches("-?0*[0-9]{1,10}")) {
return false;
}
long l = Long.valueOf(str);
if ( l > Integer.MAX_VALUE || l < Integer.MIN_VALUE) {
return false;
}
System.out.println("My number is: " + myNumber);
return true;
}
This first checks that you have no more than 10 digits with or without a minus sign (and any number of preceding zeros). If so, then it can be safely converted to a long, without exception checking. You can then check if the resulting long is in the range of an integer. It's a workaround that requires no try and catch, but I don't think it's better than the try-catch method.
So, with try-catch, you would have:
private static int checkArgs1(String[] args) {
if (args == null || args.length == 0) {
System.out.println("Error: No Args");
return -1;
}
try { // If it's a number
int myNumber = Integer.parseInt(args[0]);
System.out.println("My number is: " + myNumber);
} catch (NumberFormatException e) {// If it's a String
String[] myStr = args;
System.out.print("My String is ");
for (int i = 0; i < args.length; i++) {
myStr[i] = args[i];
System.out.print(myStr[i]);
}
System.out.print("\n");
return 0;
}
return 0;
}
And without it, using my checkInt() method:
private static int checkArgs2(String[] args) {
if (args == null || args.length == 0) {
System.out.println("Error: No Args");
return -1;
}
if ( ! checkInt(args[0])) {
// If it's a String
String[] myStr = args;
System.out.print("My String is ");
for (int i = 0; i < args.length; i++) {
myStr[i] = args[i];
System.out.print(myStr[i]);
}
System.out.print("\n");
return 0;
}
return 0;
}
I'm not really sure how useful your check is, though. Usually, argument checking is done in preparation for doing something with the args, and you don't save the information about whether it was a number or a string anywhere.
As mentioned in the comments your code has compilation issues. As far as logic is concerned, to find out if an input string contains only digits or not, you can use regex as shown below.
Pattern p = Pattern.compile("^-?[0-9]+$");
if(p.matcher(arg[0]).matches()) {
System.out.println("It's a number!!");
} else {
System.out.println("Not a number.");
}
In this case you don't have to use try/catch block.
Try like this...
public class CheckArgs {
public static void main(String[] args) {
if (args != null && args.length != 0) {
for (String arg : args) {
System.out.println(String.format("<----- %s ----->", arg));
System.out.println(String.format("is number %s", checkIfNumber(arg)));
System.out.println(String.format("is string %s", checkIfString(arg)));
System.out.println(String.format("<-------------->", arg));
}
}
}
private static boolean checkIfString(Object arg) {
if (arg instanceof String) {
return true;
}
return false;
}
private static boolean checkIfNumber(Object arg) {
if (arg instanceof Integer) {
return true;
}
return false;
}
}
So I have a Computer Science course at school in which we learn Java. We were assigned to do a simple text based recreation of the guessing game. I got it done until this point, and I cannot seem to find where I messed up because there is nothing printed when I run the core.
This is the code:
public class GuessGame
{
public static void main(String[] args)
{
new GuessGame();
}
public GuessGame ()
{
char end = 'y';
while (end!='y')
{
System.out.println ("Welcome to the Guessing Game!");
System.out.println ("\nThe computer has picked a number");
System.out.println ("between 1 and 100. Try to guess it.");
int num = (int)(Math.random()*(100-1)+1);
int guess = IBIO.inputInt ("Guess the number: ");
if (guess==num)
System.out.println ("You got it!");
else if (guess>num)
System.out.println ("That is too high.");
else
System.out.println ("That is too low.");
end = IBIO.inputChar ("Exit game? (y/n)");
}
}
}
By the way, IBIO is a class provided by my IB program that we use to make Input/Output statements.
This is IBIO.java:
public class IBIO
{
static void output (String info)
{
System.out.println (info);
}
static void output (char info)
{
System.out.println (info);
}
static void output (byte info)
{
System.out.println (info);
}
static void output (int info)
{
System.out.println (info);
}
static void output (long info)
{
System.out.println (info);
}
static void output (double info)
{
System.out.println (info);
}
static void output (boolean info)
{
System.out.println (info);
}
static String input (String prompt)
{
String inputLine = "";
System.out.print (prompt);
try
{
inputLine = (new java.io.BufferedReader (new java.io.InputStreamReader (System.in))).readLine ();
}
catch (Exception e)
{
String err = e.toString ();
System.out.println (err);
inputLine = "";
}
return inputLine;
}
static String inputString (String prompt)
{
return input (prompt);
}
static String input ()
{
return input ("");
}
static int inputInt ()
{
return inputInt ("");
}
static double inputDouble ()
{
return inputDouble ("");
}
static char inputChar (String prompt)
{
char result = (char) 0;
try
{
result = input (prompt).charAt (0);
}
catch (Exception e)
{
result = (char) 0;
}
return result;
}
static byte inputByte (String prompt)
{
byte result = 0;
try
{
result = Byte.valueOf (input (prompt).trim ()).byteValue ();
}
catch (Exception e)
{
result = 0;
}
return result;
}
static int inputInt (String prompt)
{
int result = 0;
try
{
result = Integer.valueOf (input (prompt).trim ()).intValue ();
}
catch (Exception e)
{
result = 0;
}
return result;
}
static long inputLong (String prompt)
{
long result = 0;
try
{
result = Long.valueOf (input (prompt).trim ()).longValue ();
}
catch (Exception e)
{
result = 0;
}
return result;
}
static double inputDouble (String prompt)
{
double result = 0;
try
{
result = Double.valueOf (input (prompt).trim ()).doubleValue ();
}
catch (Exception e)
{
result = 0;
}
return result;
}
static boolean inputBoolean (String prompt)
{
boolean result = false;
try
{
result = Boolean.valueOf (input (prompt).trim ()).booleanValue ();
}
catch (Exception e)
{
result = false;
}
return result;
}
}
Sorry for the lengthy question. Im new to Java.
The computer is doing exactly what you told it to. When GuessGame's constructor runs:
Declare end as a char local variable and initialise it to contain 'y':
char end = 'y';
Run the loop body while end does not contain 'y':
while (end!='y')
(since end does contain 'y' it does not run the loop body; it skips to the code after the loop).
The problem is that you will never enter the initial loop
char end = 'y';
while (end!='y')
You instantiate end to y, then enter only if end is not y which will always be false, hence never enter the loop.
Simply change the default value of end
char end = 'n';
Also, you don't have to cast the value 0 in your IBIO class
result = (char) 0;
You can simply do result = 0 and it will take the ASCII value.
I would also declare num and guess outside of the loop to avoid re-declaring them each time, as you did for end.
Finally, instead of declaring 7 output method with different paremeter type which simply do a System.out.println of the received parameter I would directly call System.out.println(value).
I would apply the same logic for all other methods that only call one method with the received parameter.
These two lines clearly contradict each other, the while loop will never execute. Initialize end to be a different value.
char end = 'y';
while (end!='y')
You initialize the variable char end with value 'y'.
char end = 'y';
Then the condition for your loop is
while (end!='y')
This condition is never fulfilled, that's why it's out of the loop. Change the initial value of the variable end.
I am trying with a Utility function to get int and check if bad input results in
NumberFormat Exceptions,is there a way to work with Non-decimal Int for below function
//--- Utility function to get int using a dialog.
public static int getInt(String mess) {
int val;
while (true) { // loop until we get a valid int
String s = JOptionPane.showInputDialog(null, mess);
try {
val = Integer.parseInt(s);
break; // exit loop with valid int
} catch (NumberFormatException nx) {
JOptionPane.showMessageDialog(null, "Enter valid integer");
}
}
return val;
}
//end getInt
If I understand you... maybe you can do this:
public static int getInt(String mess) {
int val;
while (true) { // loop until we get a valid int
String s = JOptionPane.showInputDialog(null, mess);
try {
if(mess.match("^\d+$")){ // Check if it's only numbers (no comma, no dot, only numeric characters)
val = Integer.parseInt(s); // Check if it's in the range for Integer numbers.
break; // exit loop with valid int
} else {
JOptionPane.showMessageDialog(null, "Enter valid integer");
}
} catch (NumberFormatException nx) {
JOptionPane.showMessageDialog(null, "Enter valid integer");
}
}
return val;
}
Try what u want , one for decimal checker and one for non-decimal int
// for deciaml
public static Boolean numberValidate(String text) {
String expression = "^[+-]?(?:\\d+\\.?\\d*|\\d*\\.?\\d+)[\\r\\n]*$";
CharSequence inputStr = text;
Pattern pattern = Pattern.compile(expression);
Matcher matcher = pattern.matcher(inputStr);
if (matcher.find()) {
MatchResult mResult = matcher.toMatchResult();
String result = mResult.group();
return true;
}
return false;
}
// non-decimal int
public static Boolean numberValidate(String text) {
String expression = "[a-zA-Z]";
CharSequence inputStr = text;
Pattern pattern = Pattern.compile(expression);
Matcher matcher = pattern.matcher(inputStr);
if (matcher.find()) {
MatchResult mResult = matcher.toMatchResult();
String result = mResult.group();
return true;
}
return false;
}
I have been storing phone numbers as longs and I would like to simply add hyphens when printing the phone number as a string.
I tried using DecimalFormat but that doesn't like the hyphen. Probably because it is meant for formatting decimal numbers and not longs.
long phoneFmt = 123456789L;
DecimalFormat phoneFmt = new DecimalFormat("###-###-####");
System.out.println(phoneFmt.format(phoneNum)); //doesn't work as I had hoped
Ideally, I would like to have parenthesis on the area code too.
new DecimalFormat("(###)-###-####");
What is the correct way to do this?
You can use String.replaceFirst with regex method like
long phoneNum = 123456789L;
System.out.println(String.valueOf(phoneNum).replaceFirst("(\\d{3})(\\d{3})(\\d+)", "($1)-$2-$3"));
To get your desired output:
long phoneFmt = 123456789L;
//get a 12 digits String, filling with left '0' (on the prefix)
DecimalFormat phoneDecimalFmt = new DecimalFormat("0000000000");
String phoneRawString= phoneDecimalFmt.format(phoneFmt);
java.text.MessageFormat phoneMsgFmt=new java.text.MessageFormat("({0})-{1}-{2}");
//suposing a grouping of 3-3-4
String[] phoneNumArr={phoneRawString.substring(0, 3),
phoneRawString.substring(3,6),
phoneRawString.substring(6)};
System.out.println(phoneMsgFmt.format(phoneNumArr));
The result at the Console looks like this:
(012)-345-6789
For storing phone numbers, you should consider using a data type other than numbers.
The easiest way to do this is by using the built in MaskFormatter in the javax.swing.text library.
You can do something like this :
import javax.swing.text.MaskFormatter;
String phoneMask= "###-###-####";
String phoneNumber= "123423452345";
MaskFormatter maskFormatter= new MaskFormatter(phoneMask);
maskFormatter.setValueContainsLiteralCharacters(false);
maskFormatter.valueToString(phoneNumber) ;
If you really need the right way then you can use Google's recently open sourced libphonenumber
You could also use https://github.com/googlei18n/libphonenumber. Here is an example:
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
String s = "18005551234";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber phoneNumber = phoneUtil.parse(s, Locale.US.getCountry());
String formatted = phoneUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
Here you can get the library on your classpath: http://mvnrepository.com/artifact/com.googlecode.libphonenumber/libphonenumber
The worst possible solution would be:
StringBuilder sb = new StringBuilder();
long tmp = phoneFmt;
sb.append("(");
sb.append(tmp / 10000000);
tmp = tmp % 10000000;
sb.append(")-");
sb.apppend(tmp / 10000);
tmp = tmp % 10000000;
sb.append("-");
sb.append(tmp);
This is how I ended up doing it:
private String printPhone(Long phoneNum) {
StringBuilder sb = new StringBuilder(15);
StringBuilder temp = new StringBuilder(phoneNum.toString());
while (temp.length() < 10)
temp.insert(0, "0");
char[] chars = temp.toString().toCharArray();
sb.append("(");
for (int i = 0; i < chars.length; i++) {
if (i == 3)
sb.append(") ");
else if (i == 6)
sb.append("-");
sb.append(chars[i]);
}
return sb.toString();
}
I understand that this does not support international numbers, but I'm not writing a "real" application so I'm not concerned about that. I only accept a 10 character long as a phone number. I just wanted to print it with some formatting.
Thanks for the responses.
You can implement your own method to do that for you, I recommend you to use something such as this. Using DecimalFormat and MessageFormat. With this method you can use pretty much whatever you want (String,Integer,Float,Double) and the output will be always right.
import java.text.DecimalFormat;
import java.text.MessageFormat;
/**
* Created by Yamil Garcia Hernandez on 25/4/16.
*/
public class test {
// Constants
public static final DecimalFormat phoneFormatD = new DecimalFormat("0000000000");
public static final MessageFormat phoneFormatM = new MessageFormat("({0}) {1}-{2}");
// Example Method on a Main Class
public static void main(String... args) {
try {
System.out.println(formatPhoneNumber("8091231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("18091231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("451231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("11231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("1231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber(""));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber(0));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber(8091231234f));
} catch (Exception e) {
e.printStackTrace();
}
}
// Magic
public static String formatPhoneNumber(Object phone) throws Exception {
double p = 0;
if (phone instanceof String)
p = Double.valueOf((String) phone);
if (phone instanceof Integer)
p = (Integer) phone;
if (phone instanceof Float)
p = (Float) phone;
if (phone instanceof Double)
p = (Double) phone;
if (p == 0 || String.valueOf(p) == "" || String.valueOf(p).length() < 7)
throw new Exception("Paramenter is no valid");
String fot = phoneFormatD.format(p);
String extra = fot.length() > 10 ? fot.substring(0, fot.length() - 10) : "";
fot = fot.length() > 10 ? fot.substring(fot.length() - 10, fot.length()) : fot;
String[] arr = {
(fot.charAt(0) != '0') ? fot.substring(0, 3) : (fot.charAt(1) != '0') ? fot.substring(1, 3) : fot.substring(2, 3),
fot.substring(3, 6),
fot.substring(6)
};
String r = phoneFormatM.format(arr);
r = (r.contains("(0)")) ? r.replace("(0) ", "") : r;
r = (extra != "") ? ("+" + extra + " " + r) : r;
return (r);
}
}
Result will be
(809) 123-1234
+1 (809) 123-1234
(45) 123-1234
(1) 123-1234
123-1234
023-1234
java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.lang.Double.valueOf(Double.java:502)
at test.formatPhoneNumber(test.java:66)
at test.main(test.java:45)
java.lang.Exception: Paramenter is no valid
at test.formatPhoneNumber(test.java:78)
at test.main(test.java:50)
(809) 123-1232
DecimalFormat doesn't allow arbitrary text within the number to be formatted, just as a prefix or a suffix. So it won't be able to help you there.
In my opinion, storing a phone number as a numeric value is wrong, entirely. What if I want to store an international number? Many countries use + to indicate a country code (e.g. +1 for USA/Canda), others use 00 (e.g. 001).
Both of those can't really be represented in a numeric data type ("Is that number 1555123 or 001555123?")
You could use the substring and concatenation for easy formatting too.
telephoneNumber = "("+telephoneNumber.substring(0, 3)+")-"+telephoneNumber.substring(3, 6)+"-"+telephoneNumber.substring(6, 10);
But one thing to note is that you must check for the lenght of the telephone number field just to make sure that your formatting is safe.
U can format any string containing non numeric characters also to your desired format use my util class to format
usage is very simple
public static void main(String[] args){
String num = "ab12345*&67890";
System.out.println(PhoneNumberUtil.formateToPhoneNumber(num,"(XXX)-XXX-XXXX",10));
}
output: (123)-456-7890
u can specify any foramt such as XXX-XXX-XXXX and length of the phone number , if input length is greater than specified length then string will be trimmed.
Get my class from here: https://github.com/gajeralalji/PhoneNumberUtil/blob/master/PhoneNumberUtil.java
Pattern phoneNumber = Pattern.compile("(\\d{3})(\\d{3})(\\d{4})");
// ...
Matcher matcher = phoneNumber(numberAsLineOf10Symbols);
if (matcher.matches) {
return "(" + matcher.group(1) + ")-" +matcher.group(2) + "-" + matcher.group(3);
}
I'd have thought you need to use a MessageFormat rather than DecimalFormat. That should be more flexible.
String formatterPhone = String.format("%s-%s-%s", phoneNumber.substring(0, 3), phoneNumber.substring(3, 6), phoneNumber.substring(6, 10));
Using StringBuilder for performance.
long number = 12345678L;
System.out.println(getPhoneFormat(String.valueOf(number)));
public static String getPhoneFormat(String number)
{
if (number == null || number.isEmpty() || number.length() < 6 || number.length() > 15)
{
return number;
}
return new StringBuilder("(").append(number.substring(0, 3))
.append(") ").append(number.substring(3, 6))
.append("-").append(number.substring(6))
.toString();
}
Kotlin
val number = 088899998888
val phone = number.phoneFormatter()
fun String.phoneFormatter(): String { return this.replace("\\B(?=(\\d{4})+(?!\\d))".toRegex(), "-") }
The result will be 0888-9999-8888
I used this one
String columValue = "1234567890
String number = columValue.replaceFirst("(\d{3})(\d{3})(\d+)", "($1) $2-$3");