java中String类

java的Math和Random类

java中String类

String类的本质

在这里插入图片描述
String类是在java.lang下,经过前面的学习可以知道在这个包中的所有类可以直接调用,不需要导包。

//自动装箱
String str = "abc";

"abc"就是String类下的一个具体的对象,由于String类被final修饰着,这个String类不可以被继承,不能有子类。
接下来看一下String字符串的本质:
在这里插入图片描述
其实String字符串的底层就是一个char类型的数组

String类的常用方法

public class Test10 {
    public static void main(String[] args) {
        //声明变量,类型为String类型
        String str = "abc";
        System.out.println(str);
        String str2 = "";
        //通过构造器来创建对象
        //空构造器
        String s1 = new String();
        String s2 = new String("abc");
        String s3 = new String(new char[]{'a', 'b', 'c'});
        String s4 = "abc";
        System.out.println("字符串的长度为:" + s4.length());
        String s5 = new String("abc");
        System.out.println("字符串是否为空:" + s5.isEmpty());
        System.out.println("获取字符串的下标对应的字符为:" + s5.charAt(1));
        String s6 = new String("abc");
        String s7 = new String("abc");
        System.out.println(s6.equals(s7));
        String s8 = new String("abc");
        String s9 = new String("abc");
        System.out.println(s8.compareTo(s9));
        //字符串的截取
        String s10 = "agbvasdfgas";
        System.out.println(s10.substring(3));
        System.out.println(s10.substring(3, 6));
        //字符串的合并和拼接操作
        System.out.println(s10.concat("pppp"));
        //字符串中的字符进行替换
        String s11= "asdfasdfasdfasdf";
        System.out.println(s11.replace('a','u'));
        //按照指定的字符串进行分割为数组的形式
        String s12 = "a-b-c-e-fg";
        String[] strs = s12.split("-");
        System.out.println(Arrays.toString(strs));
        //将字符串转换大小写
        String s13 = "abc";
        System.out.println(s13.toUpperCase());
        System.out.println(s13.toUpperCase().toLowerCase());
        //去除首尾空格
        String s14 = " a b c ";
        System.out.println(s14.trim());
        //toString()
        String s15 = "abc";
        System.out.println(s15.toString());
        //转换为String类型
        System.out.println(String.valueOf(false));
    }
}
  • 调用String类的空构造器
        String s1 = new String();

可以查看String底层的源码:
在这里插入图片描述

方法说明返回值
length()返回此字符串的长度。返回int类型的数据
isEmpty()判断字符串是否为空,如果为空则返回true返回boolean类型的数据
charAt()获取字符串的下标对应的字符返回char类型的数据
equals()将此字符串与指定对象进行比较。返回boolean类型的数据
compareTo()如果这个字符串是等参数字符串那么​返回值0,如果这个字符串是按字典顺序小于字符串参数那么返回小于0的值,如果此字符串是按字典顺序大于字符串参数那么返回一个大于0的值返回int类型的数据
substring()截取字符串,beginIndex - 起始索引(包括),endIndex - 结束索引(不包括)。返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符。
concat(String str)将指定字符串连接到此字符串的结尾,需要创建对象才能够调用该方法返回字符串类型
replace​(char oldChar, char newChar)将字符串中的旧字符进行替换成新的字符返回String类型
split​(String regex, int limit)根据匹配给定的正则表达式来拆分字符串,其中参数str为正则表达式分隔符,参数limit:分割份数返回String[]类型
toString()String类重写了Object的toString方法,用于返回String的字符串值返回String类型
toUpperCase()将字符串全部大写返回String类型
toLowerCase()将字符串全部小写返回String类型
trim()去掉字符串中的首尾空格,保留字符之间的空格返回String类型
valueOf()是静态方法,可以通过类名点出来,将其他任意类型的数据转换成字符串类型返回String类型

接下来就详细的分析一下经常用到的String类下的方法的底层源码:

  • String类下的length()方法
    点到length()方法中,看一下length方法的定义
    private final byte[] value;

    /**
     * Returns the length of this string.
     * The length is equal to the number of <a href="Character.html#unicode">Unicode
     * code units</a> in the string.
     *
     * @return  the length of the sequence of characters represented by this
     *          object.
     */
    public int length() {
        return value.length >> coder();
    }

value.length返回的是value中存储的字符(char)的数量,也就是返回了unicode数量。
上面我们提到过String类其本质就是一个char类型的数组,在这里length方法返回的就是String字符串的长度

  • String类下的isEmpty()方法
	private final byte[] value;

    /**
     * Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
     *
     * @return {@code true} if {@link #length()} is {@code 0}, otherwise
     * {@code false}
     *
     * @since 1.6
     */
    @Override
    public boolean isEmpty() {
        return value.length == 0;
    }

isEmpty方法中定义了当且仅当字符串的长度为0的时候返回的是true,否则返回的是false这两个布尔类型的值

  • String类下的charAt()方法
    看jdk中的charAt方法的定义
    private final byte[] value;
    /**
     * Returns the {@code char} value at the
     * specified index. An index ranges from {@code 0} to
     * {@code length() - 1}. The first {@code char} value of the sequence
     * is at index {@code 0}, the next at index {@code 1},
     * and so on, as for array indexing.
     *
     * <p>If the {@code char} value specified by the index is a
     * <a href="Character.html#unicode">surrogate</a>, the surrogate
     * value is returned.
     *
     * @param      index   the index of the {@code char} value.
     * @return     the {@code char} value at the specified index of this string.
     *             The first {@code char} value is at index {@code 0}.
     * @throws     IndexOutOfBoundsException  if the {@code index}
     *             argument is negative or not less than the length of this
     *             string.
     */
    public char charAt(int index) {
        if (isLatin1()) {
            return StringLatin1.charAt(value, index);
        } else {
            return StringUTF16.charAt(value, index);
        }
    }

charAt方法中的index代表了索引值,点到StringLatin1中,有这样的一段代码:

    public static char charAt(byte[] value, int index) {
        if (index < 0 || index >= value.length) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return (char)(value[index] & 0xff);
    }

如果索引值小于0或者是大于字符串的长度时,系统会抛出异常StringIndexOutOfBoundsException(index)(越界异常),其他情况下返回索引值对应的char类型的字符

  • String类下的equals()方法
    private final byte[] value;
    /**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * <p>For finer-grained String comparison, refer to
     * {@link java.text.Collator}.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String aString = (String)anObject;
            if (!COMPACT_STRINGS || this.coder == aString.coder) {
                return StringLatin1.equals(value, aString.value);
            }
        }
        return false;
    }
    public static boolean equals(byte[] value, byte[] other) {
        if (value.length == other.length) {
            for (int i = 0; i < value.length; i++) {
                if (value[i] != other[i]) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

对equals()方法的源码进行注释,这个源码需要掌握
在这里插入图片描述

  • String类下的substring()方法:
    点到substring中看一下方法的定义:
    public String substring(int beginIndex, int endIndex) {
        int length = length();
        checkBoundsBeginEnd(beginIndex, endIndex, length);
        if (beginIndex == 0 && endIndex == length) {
            return this;
        }
        int subLen = endIndex - beginIndex;
        return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
                          : StringUTF16.newString(value, beginIndex, subLen);
    }
    static void checkBoundsBeginEnd(int begin, int end, int length) {
        if (begin < 0 || begin > end || end > length) {
            throw new StringIndexOutOfBoundsException(
                "begin " + begin + ", end " + end + ", length " + length);
        }
    }

返回的是一个字符。
返回一个新字符串,它是此字符串的一个子字符串。
该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符。
因此,该子字符串的长度为 endIndex-beginIndex。
抛出异常
IndexOutOfBoundsException
- beginIndex 为负,
- endIndex 大于此 String 对象的长度,
- beginIndex 大于 endIndex。

String类加号编译器优化问题

  • 字符串与字符串用加号+ 拼接
    刚开始接触java的时候就知道这个加号+可以连接字符串,接下来我们看一下在底层是怎样的
package Test;

public class Test11 {
    public static void main(String[] args) {
        String s1 = "a"+"b"+"c";
        String s2 = "ab"+"c";
        String s3 = "a"+"bc";
        String s4 = "abc";
        String s5 = "abc"+ "";
        System.out.println(s1 == s4);
        System.out.println(s2 == s5);
        String s6 = new String("abc");
    }
}

可以在IDEA中查看对应的class文件:
在这里插入图片描述
可见这几种用加号拼接的形式在底层中都是相当于"abc" 可见他们是一样的。

  • 变量与字符串用加号+进行拼接
package Test;

public class Test12 {
    //有变量参与的字符串拼接
    public static void main(String[] args) {
        String a = "abc";
        String b = a + "def";
        System.out.println(b);
        //a变量在编译的时候不知道a是"abc"字符串,所以不会进行编译优化,并不会直接合并为"abcdef"
    }
}

虽然a = "abc" 但是编辑器不知道a="abc",不会进行编译优化,不会直接合并,这个就是与字符串和字符串用加号+ 拼接的区别,也可以通过对应的class文件查看:
在这里插入图片描述
java的StringBuilder类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_45671732

你们鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值