Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Arrays.asList(charArray).indexOf always return -1?

So I am trying to make a method that you send a simple string to, which is then broken up char by char in a for loop, with each char from the array "alpha" transformed into its equivalent value in "beta", they are then all concatenated using StringBuilder and sent back as the "output", as shown here:

Code: I have simplified the entire class and all variable names to improve readability.

import java.util.Arrays;

public class Test {
    private final char[] alpha = {  'A', 'B', 'C', 'D', 'E',
                                    'F', 'G', 'H', 'I', 'J',
                                    'K', 'L', 'M', 'N', 'O',
                                    'P', 'Q', 'R', 'S', 'T',
                                    'U', 'V', 'W', 'X', 'Y', 'Z'};

    public String getAlpha(String input) {

        StringBuilder output = new StringBuilder();

        for (int i = 0; i < input.length(); i++) {

            char c = input.charAt(i);
            int index;

            if (Character.isLetter(c)) {
                try {
                    index = Arrays.asList(alpha).indexOf(Character.toUpperCase(c));

                    System.out.println(c); //debug
                    System.out.println(index); //debug

                    //output.append(beta[index]); //gets the index and applies it to beta (unnecessary for this example)
                } catch(ArrayIndexOutOfBoundsException e) {
                    e.printStackTrace();
                }
            } else {
                output.append(c);
            }
        }

        return output.toString();
    }

    public static void main(String[] args) {
        Test test1 = new Test();

        test1.getAlpha("Hello");
    }
}

The problem I am having is that my index for each char consistently causes an ArrayIndexOutOfBounds exception, due to the indexOf not being able to find the chars equivalent in the array "alpha".

Am I doing something wrong? Obviousy, but I cannot understand what / why its is not getting any index for any char. Any help would be appreciated thanks.

Input:

"Hello"

Output: debug

H
-1
e
-1
l
-1
l
-1
o
-1
like image 363
Daedric Avatar asked Dec 15 '22 08:12

Daedric


1 Answers

char[] alpha = {...};
index = Arrays.asList(alpha).indexOf(Character.toUpperCase(c));

The problem is subtle. Arrays.asList(T...) expects an array of T where T extends Object. It doesn't work like you'd expect if you pass an array of primitives. In that case, it thinks T = char[] and gives you back a List<char[]> containing a single element, alpha.

A List<char[]> contains char arrays, not chars, so the indexOf call always returns -1.

You might wonder why you don't get a compile-time error. Shouldn't indexOf expect to be passed a char[] reference if it's being called on a List<char[]>? Well, surprisingly, no. indexOf's signature is int indexOf(Object): it accepts any type of object, even ones unrelated to T.

You could use Arrays.binarySearch. That would work since your array is sorted. Or you could use a String instead of a char[] array.

Another method would be to do some simple math if the character is in range.

char uc = Character.toUpperCase(c);
if (uc >= 'A' && uc <= 'Z') {
    index = uc - 'A';
}
like image 165
John Kugelman Avatar answered Jan 06 '23 02:01

John Kugelman