java中charAt()方法的使用及说明

 更新时间:2023年07月28日 09:23:37   作者:骑着蜗牛@you  
这篇文章主要介绍了java中charAt()方法的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

java charAt()方法的使用

描述

java.lang.String.charAt() 方法返回指定索引处的char值。

索引范围是从0到length() - 1。

对于数组索引,序列的第一个char值是在索引为0,索引1,依此类推

声明  

以下是声明java.lang.String.charAt()方法

public char charAt(int index)

参数

index -- 这是该指数的char值

返回值  

此方法返回这个字符串的指定索引处的char值。第一个char值的索引为0.

异常

IndexOutOfBoundsException -- 如果index参数为负或不小于该字符串的长度.

实例      

public class Test {
    public static void main(String[] args) {
        String s ="abc";
        System.out.println(s.charAt(1));
    }
}

运行结果是:

b

java使用charAt(),length()可能会遇到的乱码问题

charAt()和length()都是经常使用到的命令,这两个命令在遇到某些特殊字符的时候会出现一些问题。

比如:

public class Demo{
    public static void main(String args[]){
        String s = "👲";
        char c = s.charAt(0);
        System.out.println(s.length());
        System.out.println(c);
    }
}

可以发现这个特殊字符(或者叫表情符号会好一些)的长度居然是2,而且我把他作为字符输出的时候居然输出了一个问号,这是为什么?

原因是

length()方法是跟据UTF-16的代码单元数量来计算字符串的长度的,在UTF-16中常用字符用一个代码单元就可以表示,而有些字符则需要两个代码单元表示,比如"👲",所以我们才会看到这个字符串竟然占据了2个长度。

那为什么变量c会输出问号呢?,没错,charAt()方法也是根据代码单元来获取字符的,变量c只获取了👲的第一个代码单元所以编译器并不能识别。

这在遍历字符串的时候可能会出现很严重的问题:

public class Demo {
    public static void main(String[] args) {
        String str = "👲🎁🔜😀😁🤣";
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            System.out.println(c);
        }
    }
}

另外,当我把println换成print再输出后却得到了正确的字符。

可以看出当两个特定的代码单元组合后编译器会把它当作一个字符看待。

解决方法

最好的解决办法就是不使用charAt()和length()方法(除非你能保证接收的字符串都是常用的字符)。

首先说length()方法取字符数量错误的问题,要解决这个问题先要了解一个术语,叫“码点”,有人也叫“代码点”,码点指的是一个编码表中的某个字符所对应的代码值,所以码点的数量才是字符串中字符的数量。

方法一:要想得到码点数量可以用codePointCount(0,str.length())方法,然后再用offsetByCodePoints(0,i)获取码点的索引值index,根据index用codePointAt(index)方法得出码点值,最后用Character.toString(cp)取出字符(返回的其实是字符串,要想真正的取出char类型的值是不可能的)。

方法二:用codePoints()生成一个流,再用toArray()使其返回一个码点值的数组,然后根据这个数组使用Character.toString(codePoints(i))方法循环输出。

附完整代码:

public class Demo {
    public static void main(String[] args) {
        String str = "👲🎁🔜😀😁🤣";
        //方法一
        for (int i = 0; i < str.codePointCount(0,str.length()); i++) {
            int index = str.offsetByCodePoints(0,i);
            int cp = str.codePointAt(index);
            System.out.println(Character.toString(cp));
        }
        System.out.println("-------------------------------------");
        //方法二
        int[] codePoints = str.codePoints().toArray();
        for (int i = 0; i < codePoints.length; i++) {
            System.out.println(Character.toString(codePoints[i]));
        }
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java pdf和jpg互转案例

    Java pdf和jpg互转案例

    这篇文章主要介绍了Java pdf和jpg互转案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • SpringBoot和VUE源码直接整合打包成jar的踩坑记录

    SpringBoot和VUE源码直接整合打包成jar的踩坑记录

    这篇文章主要介绍了SpringBoot和VUE源码直接整合打包成jar的踩坑记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Springboot实现XSS漏洞过滤的示例代码

    Springboot实现XSS漏洞过滤的示例代码

    这篇文章主要介绍了Springboot实现XSS漏洞过滤的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java编程实现对象克隆(复制)代码详解

    Java编程实现对象克隆(复制)代码详解

    这篇文章主要介绍了Java编程实现对象克隆(复制)代码详解,涉及了克隆的原因,如何实现克隆,克隆的一般步骤,深克隆与浅克隆的介绍等相关内容,具有一定借鉴价值,需要的朋友可以参考下。
    2017-11-11
  • 详解MybatisPlus3.4版本之后分页插件的使用

    详解MybatisPlus3.4版本之后分页插件的使用

    从Mybatis Plus 3.4.0版本开始,不再使用旧版本的PaginationInterceptor ,而是使用MybatisPlusInterceptor。本文就详细的介绍一下两者的区别,感兴趣的可以了解一下
    2021-11-11
  • Springboot集成Mybatis-Flex的示例详解

    Springboot集成Mybatis-Flex的示例详解

    Mybatis-Flex 是一个优雅的 Mybatis 增强框架,它非常轻量、同时拥有极高的性能与灵活性,本文主要介绍了Springboot集成Mybatis-Flex的示例详解,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Java并发编程之详解CyclicBarrier线程同步

    Java并发编程之详解CyclicBarrier线程同步

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口,ArrayBlockingQueue,DelayQueue,LinkedBlockingQueue,PriorityBlockingQueue,SynchronousQueue,BlockingDeque接口,ConcurrentHashMap,CountDownLatch,本文为系列文章第十篇,需要的朋友可以参考下
    2021-06-06
  • cmd编译运行java程序的方法

    cmd编译运行java程序的方法

    本文主要介绍了cmd编译运行java程序的方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • SpringSecurity跨域请求伪造(CSRF)的防护实现

    SpringSecurity跨域请求伪造(CSRF)的防护实现

    本文主要介绍了SpringSecurity跨域请求伪造(CSRF)的防护实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Java中锁的实现和内存语义浅析

    Java中锁的实现和内存语义浅析

    这篇文章主要给大家介绍了关于Java中锁的实现和内存语义的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11

最新评论