美文网首页
《Java编程的逻辑》笔记29--剖析String

《Java编程的逻辑》笔记29--剖析String

作者: 天一方蓝 | 来源:发表于2019-07-13 18:47 被阅读0次
    29.剖析String.png

    基本用法

    String name = "老马说编程";
    String name = new String("老马说编程");
    String可以直接使用+和+=运算符
    String name = "老马"; name+= "说编程"; 
    String descritpion = ",探索编程本质";
    System.out.println(name+descritpion);
    

    输出为:老马说编程,探索编程本质

    方法

    判断字符串是否为空

    public boolean isEmpty()
    

    获取字符串长度

    public int length()
    

    取子字符串

    public String substring(int beginIndex)public String substring(int beginIndex, int endIndex)
    

    在字符串中查找字符或子字符串,返回第一个找到的索引位置,没找到返回-1

     public int indexOf(int ch)
    public int indexOf(String str)
    

    从后面查找字符或子字符串,返回从后面数的第一个索引位置,没找到返回-1

    public int lastIndexOf(int ch)
    public int lastIndexOf(String str)
    

    判断字符串中是否包含指定的字符序列。回顾一下,CharSequence是一个接口,String也实现了CharSequence

    public boolean contains(CharSequence s)
    

    判断字符串是否以给定子字符串开头

    public boolean startsWith(String prefix)
    

    判断字符串是否以给定子字符串结尾

    public boolean endsWith(String suffix)
    

    与其他字符串比较,看内容是否相同

    public boolean equals(Object anObject)
    

    忽略大小写,与其他字符串进行比较,看内容是否相同

    public boolean equalsIgnoreCase(String anotherString)
    

    String也实现了Comparable接口,可以比较字符串大小

     public int compareTo(String anotherString)
    

    还可以忽略大小写,进行大小比较

    public int compareToIgnoreCase(String str)
    

    所有字符转换为大写字符,返回新字符串,原字符串不变

     public String toUpperCase()
    

    所有字符转换为小写字符,返回新字符串,原字符串不变

    public String toLowerCase()
    

    字符串连接,返回当前字符串和参数字符串合并后的字符串,原字符串不变

    public String concat(String str)
    

    字符串替换,替换单个字符,返回新字符串,原字符串不变

    public String replace(char oldChar, char newChar)
    

    字符串替换,替换字符序列,返回新字符串,原字符串不变

     public String replace(CharSequence target, CharSequence replacement)
    

    删掉开头和结尾的空格,返回新字符串,原字符串不变

    public String trim()
    

    分隔字符串,返回分隔后的子字符串数组,原字符串不变

    public String[] split(String regex)
    

    例如,按逗号分隔"hello,world":

    String str = "hello,world"; String[] arr = str.split(",");
    

    arr[0]为"hello", arr[1]为"world"。

    走进String内部

    • 封装字符数组
      String类内部用一个字符数组表示字符串,实例变量定义为:
    private final char value[];
    

    String有两个构造方法,可以根据char数组创建String

     public String(char value[])
     public String(char value[], int offset, int count)
    

    返回指定索引位置的char

    public char charAt(int index)
    

    返回字符串对应的char数组

    public char[] toCharArray()
    

    注意,返回的是一个拷贝后的数组,而不是原数组。
    将char数组中指定范围的字符拷贝入目标数组指定位置

    public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)
    

    按Code Point处理字符
    与Character类似,String类也提供了一些方法,按Code Point对字符串进行处理。

    public int codePointAt(int index)
    public int codePointBefore(int index)public int codePointCount(int beginIndex, int endIndex)
    public int offsetByCodePoints(int index, int codePointOffset)
    
    • 编码转换
      Java使用Charset这个类表示各种编码,它有两个常用静态方法:
    public static Charset defaultCharset()
    public static Charset forName(String charsetName)
    

    第一个方法返回系统的默认编码,比如,在我的电脑上,执行如下语句:

    System.out.println(Charset.defaultCharset().name());
    

    输出为UTF-8
    第二方法返回给定编码名称的Charset对象,与我们在第六节介绍的编码相对应,其charset名称可以是:US-ASCII, ISO-8859-1, windows-1252, GB2312, GBK, GB18030, Big5, UTF-8,比如:

    Charset charset = Charset.forName("GB18030");
    

    String类提供了如下方法,返回字符串按给定编码的字节表示:

    public byte[] getBytes() public byte[] getBytes(String charsetName)
     public byte[] getBytes(Charset charset)
    

    第一个方法没有编码参数,使用系统默认编码,第二方法参数为编码名称,第三个为Charset。
    String类有如下构造方法,可以根据字节和编码创建字符串,也就是说,根据给定编码的字节表示,创建Java的内部表示。

    public String(byte bytes[])public String(byte bytes[], int offset, int length)
    public String(byte bytes[], int offset, int length, String charsetName)
    public String(byte bytes[], int offset, int length, Charset charset)
    public String(byte bytes[], String charsetName)
    public String(byte bytes[], Charset charset)
    

    不可变性

    与包装类类似,String类也是不可变类,即对象一旦创建,就没有办法修改了。String类也声明为了final,不能被继承,内部char数组value也是final的,初始化后就不能再变了。
    String类中提供了很多看似修改的方法,其实是通过创建新的String对象来实现的,原来的String对象不会被修改。比如说,我们来看concat()方法的代码:

    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
    

    通过Arrays.copyOf方法创建了一块新的字符数组,拷贝原内容,然后通过new创建了一个新的String。
    与包装类类似,定义为不可变类,程序可以更为简单、安全、容易理解。但如果频繁修改字符串,而每次修改都新建一个字符串,性能太低,这时,应该考虑Java中的另两个类StringBuilder和StringBuffer,我们在下节介绍它们。

    常量字符串

    它自己就像一个String类型的对象一样,可以直接调用String的各种方法
    当通过常量的形式使用一个字符串的时候,使用的就是常量池中的那个对应的String类型的对象
    通过常量直接赋值返回true,而是通过new创建的,==就不会返回true

    hashCode

    private int hash; // Default to 0
    

    第一次调用hashCode()的时候,会把结果保存在hash这个变量中,以后再调用就直接返回保存的值

    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;
    
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
    

    如果缓存的hash不为0,就直接返回了,否则根据字符数组中的内容计算hash,计算方法是: s[0]31^(n-1) + s[1]31^(n-2) + ... + s[n-1] s表示字符串,s[0]表示第一个字符,n表示字符串长度,s[0]*31^(n-1)表示31的n-1次方再乘以第一个字符的值

    正则表达式

    分隔字符串

     public String[] split(String regex) 
    

    检查是否匹配

    public boolean matches(String regex)
    

    字符串替换

    public String replaceFirst(String regex, String replacement)  public String replaceAll(String regex, String replacement)
    

    相关文章

      网友评论

          本文标题:《Java编程的逻辑》笔记29--剖析String

          本文链接:https://www.haomeiwen.com/subject/pybmkctx.html