Daedric
Daedric

Reputation: 500

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

Upvotes: 4

Views: 1817

Answers (4)

Brian
Brian

Reputation: 312

The indexOf() is doing a comparison of objects. The Character.toUpperCase() returns a Character, but every item in the array is a char, so none match.

If you change the char[] to a Character[], you'll get the behaviour you expect.

Upvotes: 0

John Kugelman
John Kugelman

Reputation: 361605

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

Upvotes: 12

OneCricketeer
OneCricketeer

Reputation: 191743

Is this what you are trying to do?

You can avoid the OutOfBounds (or linear/binary search) entirely by taking advantage of the fact that char values are mapped to ASCII int values and you can do simply math on them to get character positions.

Output

H
8
e
5
l
12
l
12
o
15

private final String alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

public String getAlpha(String input) {

    StringBuilder output = new StringBuilder();

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

        char c = input.charAt(i);

        if (Character.isLetter(c)) {
            int index = Character.toUpperCase(c) - 'A' + 1;
            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)

        } else {
            output.append(c);
        }
    }

    return output.toString();
}

Upvotes: 1

edge
edge

Reputation: 267

Try this: index = new String(alpha).indexOf(Character.toUpperCase(c));

Upvotes: -1

Related Questions