it involves methods, strings, arrays, and files.
This is part of my code: There is a nullpointer exception when I try to call in main. pls, help.
public static boolean isCapOrDigit(String[] arr){
for(int i=0;i<arr[i].length();i ){
if(Character.isUpperCase(arr[i].charAt(0)) && Character.isDigit(arr[i].charAt(0))){
return true;
}
}
return false;
}
CodePudding user response:
Your bug is subtle.
for (int i = 0; i < arr[i].length(); i ) {
is apparently supposed to iterate over the strings in arr
. But it won't necessarily stop at the end ... because the stop condition for the for
loop is incorrect.
The expression arr[i].length()
gives you the number of characters in the i'th string, not the number of strings in an array. You need this:
for (int i = 0; i < arr.length; i ) {
There could be a second problem as well. The above bug will give you an ArrayIndexOutOfBoundsException
. But if you are getting a NullPointerException
, that implies that your method is being called with an array that contains null
values. To my mind, that is really an error in the code that calls isCapOrDigit
.
And I suspect that the entire method is flawed. Is this method supposed to test one string, or multiple strings?
- In the former case, why are you passing it an array of strings?
- In the latter case, what are you supposed to return if some of the strings match the criteria and others don't?
There are elements, 10 elements of a string array. I'm reading it from a file.
Well it appears that you are not actually reading exactly 10 elements and putting them all into the array correctly. Some of the array elements appear to be null
.
Finally, this is incorrect:
if (Character.isUpperCase(arr[i].charAt(0))
&& Character.isDigit(arr[i].charAt(0))) {
return true;
}
You are testing to see if the character is an uppercase character AND a digit ... at the same time. That's not possible. Digits aren't upper-case. Surely you should be using an OR; i.e.
if (Character.isUpperCase(arr[i].charAt(0))
|| Character.isDigit(arr[i].charAt(0))) {
return true;
}
CodePudding user response:
The Answer by Stephen C is correct, and should be accepted. I’ll suggest some improvements to your code.
For-each loop
You could use simpler code, the for-each syntax.
for ( String s : arr ) {
…
}
Code point, not char
The char
type in Java is legacy, essentially broken. As a 16-bit type, char
is physically incapable of representing most characters.
Instead, use code point integer numbers.
for ( String s : arr ) {
OptionalInt codePoint = s.codePoints().findFirst() ; // If the string is empty, the `OptionalInt` will be empty.
if( codePoint.isPresent() ) {
boolean beginsUppercaseOrDigit = Character.isUpperCase( codePoint.get() ) || Chracter.isDigit( codePoint.get() ) ;
…
} else { // Else string is empty.
…
}
}
CodePudding user response:
Using regex makes it so easy
you can use regex: ^(\\d|[A-Z]).*
which means exactly what you need, matches a string starts with a digit \\d
or |
an uppercase letter [A-Z]
with optional *
anything .
after that
import java.util.regex.*;
public class Main
{
public static void main(String[] args) {
System.out.println(Pattern.matches("^(\\d|[A-Z]).*", "5abc")); // true
System.out.println(Pattern.matches("^(\\d|[A-Z]).*", "Abc")); // true
System.out.println(Pattern.matches("^(\\d|[A-Z]).*", "5")); // true
System.out.println(Pattern.matches("^(\\d|[A-Z]).*", "abc5")); // false
System.out.println(Pattern.matches("^(\\d|[A-Z]).*", "aBc")); // false
System.out.println(Pattern.matches("^(\\d|[A-Z]).*", "a5c")); // false
}
}
You can use this regex as well ^[1-9A-Z].*
produces the same results