-1

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;
    }
  • 2
    Are you sure it's not an ArrayIndexOutOfBoundsException? – shmosel May 16 '22 at 01:52
  • 3
    Why do you have looping code? Don't you only need to test the first character to see if it is a number or capital letter? There is no way we can solve a NullPointerException for you. We have no idea what data you pass to the method. – camickr May 16 '22 at 01:55
  • @camickr The loop is looping through an array of `Strings`. – fireshadow52 May 16 '22 at 01:56
  • 2
    can you add the sample input ? – Prog_G May 16 '22 at 01:58
  • there are elements, 10 elements of a string array. I'm reading it from a file. – pureRose May 16 '22 at 02:22
  • The question from @camickr is valid. The question header implies there is one string. But, the loop appears to be an attempt to ask "Is there at least one string that begins with an uppercase letter or a digit." – Old Dog Programmer May 16 '22 at 13:03
  • My mistake. If `arr` is empty, that code doesn't throw a `NullPointerException` (NPE). If `arr` is empty, the `for` loop exits right away, and `isCapOrDigit` returns `false`. There are two ways that code can throw a NPE: 1) `arr` is null. 2) At least one of the elements of `arr` is null. – Old Dog Programmer May 18 '22 at 00:11

3 Answers3

3

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;
  }
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

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.
        … 
    }
}
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
-2

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

  • 2
    This misses the point of the question. The title is wrong - OP is actually looking for debugging help, and the problem is with iterating through an array of strings, not with the logic applied to each string. – Karl Knechtel May 16 '22 at 02:12