String.charAt () возвращает странный результат в Java - PullRequest
0 голосов
/ 29 августа 2018

у меня есть следующий код

String[] alphabet = new String[] { "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"};

если я сделаю

 String str = "aa";
 for(int i=0;i<str.length();i++) {
    chars.add(Arrays.asList(alphabet).indexOf(str.charAt(i)));
 }

значения в символах

0 = -1
1 = -1 

как результат, возвращаемый Arrays.asList (алфавит) .indexOf (str.charAt (i)) равен 'a'97, а не "a" следовательно, это не соответствует, из-за которого возвращается -1

Мне нужно Arrays.asList(alphabet).indexOf(str.charAt(i)), чтобы вернуть «а» вот что я думал charAt возвращает, что просто "а", а не это "а" 97

любая альтернатива?

Ответы [ 6 ]

0 голосов
/ 29 августа 2018

Можно делать целочисленные операции над char - это целочисленный тип (отображается как символ). Примеры: 'b' - 'a' == 1, 'c' - 'a' == 2 и т. Д. (На самом деле 'a' == 97, его значение в Unicode).

Для данного кода нет необходимости в массиве или списке, его можно записать как

for (int i=0; i<str.length(); i++) {
    chars.add(str.charAt(i) - 'a');
}

уверен, что цикл можно записать как

for (char ch : str.toCharArray()) {
    chars.add(ch - 'a');
}

или даже используя потоки:

str.chars().map(ch -> ch - 'a').forEach(chars::add)

отсутствует тип chars, я просто предположил, что это List<Integer>

0 голосов
/ 29 августа 2018

Вы можете преобразовать строку в массив символов и выполнить итерацию:

    List<Integer> indices = new ArrayList<>();

    String str = "abc";

    for ( Character character : str.toCharArray() )
    {
        indices.add(Arrays.asList(alphabet).indexOf(character.toString()));
    }
0 голосов
/ 29 августа 2018

Это потому, что char != string в Java,

Итак, чтобы решить вашу проблему,

Arrays.<String>asList(alphabet).indexOf(Character.toString(str.charAt(i)))

Теперь вы получите результат, как и ожидалось.

Итак, проблема была в том, что вы создали List of String и искали символ в строке, поэтому java не смог его найти. Так что вернулось -1.

0 голосов
/ 29 августа 2018

Arrays.asList(alphabet) является List<String>. Он не содержит ничего типа Character.

Если вы хотите найти строку, состоящую из этого единственного символа, создайте строку из этого единственного символа:

Arrays.asList(alphabet).indexOf(Character.toString(str.charAt(i)))

или

Arrays.asList(alphabet).indexOf(str.substring(i, i+1))
0 голосов
/ 29 августа 2018

Важно отметить, что символы и строки - это не одно и то же в Java. char - это примитивный числовой тип, и его литералы задаются в одинарных кавычках (например, 'a'). String - это ссылочный тип, который логически состоит из нескольких символов.

Самое простое решение было бы сделать ваш алфавит одной строкой:

String alphabet = "abcdef...";

и отсканировать эту строку при поиске индекса:

 chars.add(alphabet.indexOf(str.charAt(i)));

Обратите внимание, что теперь используется String.indexOf, а не метод List indexOf, который вы использовали ранее.

Также можно преобразовать alphabet в массив символов:

char[] alphabet = new char[] {'a', 'b', /* ... */ };
0 голосов
/ 29 августа 2018

str.charAt(i) возвращает char, а List содержит String элементов.
Поскольку char не является String, а String.equals() и Character.equals() не могут взаимодействовать между ними ("a".equals('a') и Character.valueOf('a').equals("a") return false), stringList.indexOf(anyChar) всегда будет возвращать -1.

Вы можете заменить:

chars.add(Arrays.asList(alphabet).indexOf(str.charAt(i)));
                ^----- List<String>          ^----- char (that will be boxed to Character)

по:

chars.add(Arrays.asList(alphabet).indexOf(String.valueOf(str.charAt(i))));
                ^----- List<String>             ^----- String

для сравнения String с String.

Или в качестве альтернативы сравните char с char, полагаясь на char[] вместо String[], например:

char[] alphabet = 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'}; 

Таким образом, это скомпилирует нормально:

List<Character> charList = IntStream.range(0, alphabet.length)
                                          .mapToObj(i -> alphabet[i])
                                          .collect(Collectors.toList());
chars.add(charList.indexOf(str.charAt(i))); 
            ^------- List<Character>      ^------ char (that will be boxed to Character)

Не ваш прямой вопрос, но создание одного и того же List на каждой итерации нелогично и немного бесполезно.
Создание его один раз, прежде чем цикл станет более эффективным:

List<String> alphabetList = Arrays.asList(alphabet);
String str = "aa";
for(int i=0;i<str.length();i++) {
   chars.add(alphabetList.indexOf(String.valueOf(str.charAt(i))));
}
...