Java中String.charAt()方法返回奇怪的结果

3
我有以下代码:
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)));
 }

chars 中的值为

0 = -1
1 = -1 

作为结果,Arrays.asList(alphabet).indexOf(str.charAt(i))返回的是'a'97而不是"a",因此无法匹配,导致返回-1。
我需要Arrays.asList(alphabet).indexOf(str.charAt(i))返回"a",这就是我认为charAt返回的内容,即仅为"a"而不是'a' 97。
有其他替代方法吗?

2
如果返回-1,那意味着“List”中不包含您要搜索的内容。您正在搜索一个“String”列表以查找一个“char”。 - GBlodgett
你确定 Arrays.asList(alphabet).indexOf(str.charAt(i)) 返回的是 'a' 吗?看起来更像是 -1 - user85421
2
哦,还有char是一种整数类型(有点像),你可以对它进行数学运算:str.charAt(i) - 'a'将返回0表示a,1表示b,...上述代码中不需要数组/列表-或者例如'b' - 'a' == 1 - user85421
6个回答

6

str.charAt(i)返回一个char,而List包含String元素。
由于char不是String,而且String.equals()Character.equals()在它们之间不可互操作("a".equals('a')Character.valueOf('a').equals("a")返回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类型。或者,可以使用char[]数组代替String[]来比较char字符:

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

1
请注意,在Java中,字符和字符串不是同一种东西。一个char是一种原始的数值类型,它的文字使用单引号表示(例如'a')。字符串是一种引用类型,逻辑上由多个字符组成。
最简单的解决方案是将您的字母表作为单个字符串。
String alphabet = "abcdef...";

并在查找索引时扫描该字符串:

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

请注意,现在使用的是 String.indexOf 而不是之前使用的 List 的 indexOf 方法。
或者,将 alphabet 转换为字符数组:
char[] alphabet = new char[] {'a', 'b', /* ... */ };

1

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

这是因为在Java中char != string,

所以要解决您的问题,

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

现在您将按预期获得输出。

问题在于您创建了字符串列表,并正在查找字符串中的字符,因此Java无法找到它。因此它返回-1


0
你可以将字符串转换为字符数组,然后遍历它:
    List<Integer> indices = new ArrayList<>();

    String str = "abc";

    for ( Character character : str.toCharArray() )
    {
        indices.add(Arrays.asList(alphabet).indexOf(character.toString()));
    }

0

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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接