-2

I have (for this example) two ArrayLists. A plaintext alphabet and an enciphered alphabet. I want to take a letter from the plaintext alphabet and get the letter from its' corresponding index from the enciphered alphabet. However, it always returns the index as -1, even if the entry exists.

public class Rotor {
    String currentIndex;
    private ArrayList rotorType = new ArrayList();
    private ArrayList control = new ArrayList();
    private final char[] alpha = new char[]{
        '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'};

    static char[] I = new char[]{
        'E', 'K', 'M', 'F', 'L', 'G', 'D', 'Q',
        'V', 'Z', 'N', 'T', 'O', 'W', 'Y', 'H',
        'X', 'U', 'S', 'T', 'A', 'I', 'B', 'R',
        'C', 'J'};

    public Rotor(char[] rotor) {
        for (int i = 0; i < 25; i++) {
            rotorType.add(rotor[i]);
            control.add(alpha[i]);
        }
    }

    public void convert(String nextCharacter) {
        currentIndex = String.valueOf(rotorType.get(control.indexOf(nextCharacter)));
    }
}

What would cause this to return index -1?

Turing85
  • 18,217
  • 7
  • 33
  • 58

1 Answers1

0

First: The code uses raw types, which we should avoid.

Second: as Sotirios Delimanolis pointed out in a comment, Characters are not Strings. Therefore, if we ask an ArrayList containting Characters, whether it contains a String, it will always return false. This causes the problem.

Third: the alphabet has 26 characters, not 25. Therefore, the for loop should iterate as long as i <= 26, not i <= 25.

I rewrote the code slightly and the results seem to be correct.

import java.util.ArrayList;

public class Main {
    String currentIndex;
    private ArrayList<Character> rotorType = new ArrayList<Character>();
    private ArrayList<Character> control = new ArrayList<Character>();
    
    static 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'};

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

    public Main(char[] rotor) {
        assert (alpha.length == rotor.length) : "rotor must be of same length as alpha.";
        for (int idx = 0; idx < alpha.length; ++idx) {
            rotorType.add(rotor[idx]);
            control.add(alpha[idx]);
        }
    }

    public void convert(char nextCharacter) {
        currentIndex = String.valueOf(rotorType.get(control.indexOf(nextCharacter)));
    }
}
Turing85
  • 18,217
  • 7
  • 33
  • 58
  • `for (int i = 0; i < 26; i++)` - this is hard code, am I right? – Andrew Tobilko Jul 03 '15 at 22:44
  • @AndrewTobilko yes it is, and technically, you are correct to query the array in question of its length or - even better - use a `foreach` loop. But then you should also either assert, that both arrays are of same length or use two `for` loops (one for each array). – Turing85 Jul 03 '15 at 22:48