美文网首页
String你了解多少

String你了解多少

作者: 二旬一月 | 来源:发表于2020-05-30 17:06 被阅读0次

常用方法
这些用法应该烂熟于心

        String string = "Hello World!";
        String string2 = new String("abc");

        //1.获取字符串长度
        string.length();
        //2.截取一个字符
        string.charAt(0);
        //3.替代getChars()的一种方法是将字符存储在字节数组中,该方法即getBytes()
        byte[] bytes = string.getBytes();
        //4.转换成字符数组
        char[] chars = string.toCharArray();
        //5.判断字符串开始和结束
        boolean h = string.startsWith("H");
        boolean b = string.endsWith("World!");
        //6.indexOf() 查找字符或者子串第一次出现的地方。
        int e = string.indexOf('e');
        //7.lastIndexOf() 查找字符或者子串是后一次出现的地方
        int o = string.lastIndexOf('o');
        //8.截取字符串
        String substring = string.substring(1);//指定位置到结束
        String substring1 = string.substring(1, 3);//指定位置到指定位置,结果"el"
        //9.替换(这个替换是全部的)。
        String replace = string.replace('o', 'z');
        //10.连接两个字符串
        String concat = string.concat(string2);
        //11.去掉起始和结尾的空格
        String trim = string.trim();
        //12.将基础数据类型转换为字符串类型
        String s = String.valueOf(333);
        //13.大小写转换
        string.toLowerCase();
        string.toUpperCase();

从源码去理解

定义

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
          /** The value is used for character storage. */
          private final char value[];
          /** Cache the hash code for the string */
          private int hash; // Default to 0
          /** use serialVersionUID from JDK 1.0.2 for interoperability */
          private static final long serialVersionUID = -6849794470754667710L;

从上面的定义我们可以看出

  • Final 标识不允许集成重载. jdk中还多重要类都是final 标识, 防止应用程序继承重载以影响jdk的安全
  • 继承Serializable 接口, 可以放心的序列化
  • Comparable 接口, 可以根据自然序排序.
  • CharSequence 字符串的重要接口
  • char数组 value . Final 修饰.
  • hash字段 int, 表示当前的hashCode值, 避免每次重复计算hash值

字符串构造方法3+1

  • String string = "abcd";
  • public String()创建的是一个空字符
  • public String(char[])穿进去一个字符数组
  • public String(byte[])传递进去一个字节数组
    注意 直接使用双引号的形式,创建色字符串是保存在字符串常量池当中的
    new 关键字创建的方法,则是创建一条引用,然后指向了一个字符数组。
    空白构造方法其实是生成 "" 字符串传入其他字符串的构造方式其实只是把其他字符串的value 和hash 值的引用复制一份, 不用担心两个字符串的value和hash 互相干扰. 因为String类中没有修改这两个值的方法, 并且这两个值是private final修饰的, 已经无法修改了。
    空白构造方法中没有设置hash的值, 则使用 hash的默认值 // Default to 0

hashCode方法

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;
    }
  • 重写了hashcode 方法,可以看出hashcode 和每个字符都有关

字符串的拼接concat方法和join静态方法

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

直接在内存中复制一份新的数组, 在new 一个String对象. 线程安全. 性能较低.
也可以直接是用 + 拼接.

  • join静态方法
    内部发现还是使用StringBuilder来实现, join 完全就是一个为了使用方便的一个工具方法。

trim 方法

从前后遍历空白字符, 判断空白字符是使用的 char <=' ' 来判断的, 后面在使用substring来截取非空白字符

substring方法

内部使用public String(char value[], int offset, int count) 构造方法来生成新的字符串, 在这个构造方法内部会有数组的赋值

valueOf方法
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}
// 内部使用传入对象的自己的toString方法, 传入对象如果没有重载toString方法, 就使用默认的toString方法. 
public static String valueOf(char data[]) {
    return new String(data);
}
// 根据传入的数组来选择合适的构造方法来生成String对象
public static String valueOf(boolean b) {
    return b ? "true" : "false";
}
// 根据传入布尔值

static copyValueOf方法

public static String copyValueOf(char data[], int offset, int count) {
        return new String(data, offset, count);
    }
// 静态工具方法, 默认使用合适构造方法来截取和生成新新的字符串

了解了这些应该再去看看密切相关的两个东西StringBuffer、StringBuilder

  1. 如果要操作少量的数据用 String
  2. 单线程操作字符串缓冲区 下操作大量数据 StringBuilder
  3. 多线程操作字符串缓冲区 下操作大量数据 StringBuffer

注意
每次执行“+”操作时jvm都要new一个StringBuffer对象来处理字符串的连接,这在涉及很多的字符串连接操作时开销会很大。
这一小节原文链接:https://blog.csdn.net/longfulong/article/details/78700239
1.StringBuffer()的初始容量可以容纳16个字符,当该对象的实体存放的字符的长度大于16时,实体容量就自动增加。StringBuffer对象可以通过length()方法获取实体中存放的字符序列长度,通过capacity()方法来获取当前实体的实际容量。

2.StringBuffer(int size)可以指定分配给该对象的实体的初始容量参数为参数size指定的字符个数。当该对象的实体存放的字符序列的长度大于size个字符时,实体的容量就自动的增加。以便存放所增加的字符。

3.StringBuffer(String s)可以指定给对象的实体的初始容量为参数字符串s的长度额外再加16个字符。当该对象的实体存放的字符序列长度大于size个字符时,实体的容量自动的增加,以便存放所增加的字符。

扩容算法:
使用append()方法在字符串后面追加东西的时候,如果长度超过了该字符串存储空间大小了就需要进行扩容:构建新的存储空间更大的字符串,将久的复制过去;

再进行字符串append添加的时候,会先计算添加后字符串大小,传入一个方法:ensureCapacityInternal 这个方法进行是否扩容的判断,需要扩容就调用expandCapacity方法进行扩容
尝试将新容量扩为大小变成2倍+2 if 判断一下 容量如果不够,直接扩充到需要的容量大小。

相关文章

  • String你了解多少

    常用方法这些用法应该烂熟于心 从源码去理解 定义 从上面的定义我们可以看出 Final 标识不允许集成重载. jd...

  • 关于String,你了解多少?

    字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作...

  • 关于String 你了解多少

    1. JDK1.8 和 JDK1.9的String 其实不一样 来源:https://openjdk.java.n...

  • 第3篇:C++的string内部原理

    本文假定你对C/C++的string语法已经有基本的了解。 如果你对C++的string的内部实现原理不了解的话,...

  • 你了解多少?

    男人不能为女人穿上嫁衣,请不要解开她的内衣! 世界上本没有长城,每当一个男人放弃一个女人的时候,女人就在地上摆一块...

  • Java中的String、StringBuilder和Strin

    一.你了解String类吗? 想要了解一个类,最好的办法就是看这个类的实现源代码,String类的实现在 \jdk...

  • JavaSE知识点11java深探String、StringBu

    你了解String类吗? 1 想要了解一个类,最好的办法就是看这个类的实现源代码String类的定义如下: 1 S...

  • 精油你了解多少?

    精油,英文叫Essential oil,是从植物的花、叶、茎、根或者果实中,通过水蒸气蒸馏法,挤压法,冷浸法或溶剂...

  • 碧玉你了解多少?

    碧玉是和田玉的一个品种,在我国以准噶尔盆地南缘的玛纳斯县出产量最大,所以玛纳斯产的碧玉又称“玛钠斯玉”。碧玉是一种...

  • 蜂蜜,你了解多少?

    蜂蜜是一种营养丰富的天然美容及保养食品,这,已经成为了大多数人心里的共识。 但是,面对市场上各种各样的蜂蜜,你会选...

网友评论

      本文标题:String你了解多少

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