【JavaSE】Java基础语法(三十七):Java 中的 String 类(源码级别)(1)

简介: String 表示 字符串类型,属于 引用数据类型 。Java 中 String 是 不可变 的。在 Java 当中 双引号 括起来的字符串,是直接存储在“方法区”的“字符串常量池”当中的。1. 构造方法1.1 String()

String 表示 字符串类型,属于 引用数据类型 。Java 中 String 是 不可变 的。

在 Java 当中 双引号 括起来的字符串,是直接存储在“方法区”的“字符串常量池”当中的。


1. 构造方法

1.1 String()

源码:

/** 
    初始化新创建的字符串对象,使其表示空字符序列。
 请注意,由于字符串是不可变的,因此不需要使用此构造函数。
*/
public String() {
    this.value = "".value;
}

1.2 String(String original)

源码:

/**
    初始化新创建的字符串对象,使其表示与参数相同的字符序列;
    换句话说,新创建的字符串是参数字符串的副本。
    除非需要original的显式副本,否则不需要使用此构造函数,因为字符串是不可变的。
*/
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

1.3 String(char[] chars)

源码:

/**
分配一个新字符串,使其表示字符数组参数中当前包含的字符序列。
复制字符数组的内容;对字符数组的后续修改不会影响新创建的字符串。
参数:
value–字符串的初始值
*/
public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}

1.4 String(char数组,起始下标,长度)

源码:

/**
    分配一个新字符串,该字符串包含字符数组参数子数组中的字符。
    offset参数是子数组第一个字符的索引,count参数指定子数组的长度。
    复制子数组的内容;对字符数组的后续修改不会影响新创建的字符串。
    参数:
    value–作为字符源的数组
    偏移量–初始偏移量
    计数–长度
    抛出:
    IndexOutOfBoundsException–如果偏移量和计数参数索引字符超出值数组的边界
*/
public String(char value[], int offset, int count) {
    if (offset < 0) {
        throw new StringIndexOutOfBoundsException(offset);
    }
    if (count <= 0) {
        if (count < 0) {
            throw new StringIndexOutOfBoundsException(count);
        }
        if (offset <= value.length) {
            this.value = "".value;
            return;
        }
    }
    // Note: offset or count might be near -1>>>1.
    if (offset > value.length - count) {
        throw new StringIndexOutOfBoundsException(offset + count);
    }
    this.value = Arrays.copyOfRange(value, offset, offset+count);
}

1.5 String(byte数组)

源码:

/**
    通过使用平台的默认字符集对指定的字节数组进行解码来构造新字符串。
    新字符串的长度是字符集的函数,因此可能不等于字节数组的长度。
    当给定字节在默认字符集中无效时,此构造函数的行为未指定。
    当需要对解码过程进行更多控制时,应使用CharsetDecoder类。
参数:
字节–要解码为字符的字节
Since: JDK1.1
*/ 
public String(byte bytes[]) {
     this(bytes, 0, bytes.length);
 }

1.6 String(byte数组,起始下标,长度)

源码:

/**
    通过使用平台的默认字符集对指定的字节子数组进行解码,构造一个新字符串。
    新字符串的长度是字符集的函数,因此可能不等于子数组的长度。
    当给定字节在默认字符集中无效时,此构造函数的行为未指定。
    当需要对解码过程进行更多控制时,应使用CharsetDecoder类。
参数:
字节–要解码为字符的字节
偏移量–要解码的第一个字节的索引
长度–要解码的字节数
抛出:
IndexOutOfBoundsException–如果偏移量和长度参数索引字符超出字节数组的边界
Since: JDK1.1
*/ 
public String(byte bytes[], int offset, int length) {
    //  checkBounds(bytes, offset, length);
    if (length < 0)
        throw new StringIndexOutOfBoundsException(length);
    if (offset < 0)
        throw new StringIndexOutOfBoundsException(offset);
    if (offset > bytes.length - length)
        throw new StringIndexOutOfBoundsException(offset + length);
    this.value = StringCoding.decode(bytes, offset, length);
}

1.7 String(StringBuffer buffer)

源码:

/**
    分配一个新字符串,该字符串包含字符串缓冲区参数中当前包含的字符序列。
    复制字符串缓冲区的内容;
    字符串缓冲区的后续修改不会影响新创建的字符串。
*/
synchronized(buffer) {
    this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}

1.8 String(StringBuilder builder)

源码:

/**
    分配一个新字符串,该字符串包含字符串生成器参数中当前包含的字符序列。
    复制字符串生成器的内容;
    字符串生成器的后续修改不会影响新创建的字符串。
    提供此构造函数是为了方便迁移到StringBuilder。
    通过toString方法从字符串生成器获取字符串可能运行得更快,通常是首选方法。
    Since:JDK1.5
*/  
public String(StringBuilder builder) {
    this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

2. 普通方法

https://blog.csdn.net/qq_44715943/article/details/116308837

2.1 char charAt(int index)

源码:

/**
    返回指定索引处的字符值。索引的范围从0到length()-1。
    序列的第一个字符值在索引0处,下一个字符值在索引1处,依此类推,就像数组索引一样。
    如果索引指定的char值是代理项,则返回代理项值。
参数:index–字符值的索引。
返回:此字符串指定索引处的char值。第一个char值位于索引0处。
抛出:IndexOutOfBoundsException–如果索引参数为负或不小于此字符串的长度。
*/
public char charAt(int index) {
    if ((index < 0) || (index >= value.length)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index];
}

2.2 int compareTo(String anotherString)

源码:

public int compareTo(String anotherString) {
    int len1 = value.length;
    int len2 = anotherString.value.length;
    int lim = Math.min(len1, len2);
    char v1[] = value;
    char v2[] = anotherString.value;
    int k = 0;
    while (k < lim) {
        char c1 = v1[k];
        char c2 = v2[k];
        if (c1 != c2) {
            return c1 - c2;
        }
        k++;
    }
    return len1 - len2;
}

2.3 int indexOf(String str, int fromIndex)

源码:

 /**
    返回指定子字符串第一次出现的字符串内的索引,从指定的索引开始。
    返回的索引是最小的值k,其中:
    k>=fromIndex&amp;&amp;this。startsWith(str,k)
    如果不存在这样的k值,则返回-1。
    参数:
    str–要搜索的子字符串。
    fromIndex–开始搜索的索引。
    返回:指定子字符串第一次出现的索引,从指定的索引开始,如果没有出现,则为-1。
*/
public int indexOf(String str, int fromIndex) {
    return indexOf(value, 0, value.length,
                   str.value, 0, str.value.length, fromIndex);
}

2.4 int indexOf(String str)

源码:

/**
    返回指定子字符串第一次出现时该字符串内的索引。
    返回的索引是最小的值k,其中:
    这startsWith(str,k)
    如果不存在这样的k值,则返回-1。
    参数:str–要搜索的子字符串。
    返回:指定子字符串第一次出现的索引,如果没有出现,则为-1。
*/
public int indexOf(String str) {
    return indexOf(str, 0);
}

2.5 boolean contains(CharSequence s)

源码:

/**
    当且仅当此字符串包含指定的字符值序列时,返回true。
    参数:s–要搜索的序列
    返回:如果此字符串包含s,则为true,否则为false
    Since:1.5
*/
public boolean contains(CharSequence s) {
    return indexOf(s.toString()) > -1;
}

2.6 boolean startsWith(String prefix, int toffset)

源码:

/**
    测试此字符串中从指定索引开始的子字符串是否以指定前缀开始。
参数:
    prefix–前缀。
    toffset–从何处开始查看此字符串。
返回:
如果参数所表示的字符序列是从索引toffset开始的该对象的子字符串的前缀,则为true;否则就错了。
如果toffset为负值或大于该字符串对象的长度,则结果为false;否则,结果与表达式的结果相同
这子串(toffset)。startsWith(前缀)
*/
public boolean startsWith(String prefix, int toffset) {
    char ta[] = value;
    int to = toffset;
    char pa[] = prefix.value;
    int po = 0;
    int pc = prefix.value.length;
    // Note: toffset might be near -1>>>1.
    if ((toffset < 0) || (toffset > value.length - pc)) {
        return false;
    }
    while (--pc >= 0) {
        if (ta[to++] != pa[po++]) {
            return false;
        }
    }
    return true;
}

2.7 boolean startsWith(String prefix)

源码:

public boolean startsWith(String prefix) {
    return startsWith(prefix, 0);
}

2.8 boolean endsWith(String suffix)

源码:

public boolean endsWith(String suffix) {
    return startsWith(suffix, value.length - suffix.value.length);
}

2.9 boolean equals(Object anObject)

源码:

/**
*/
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

2.10 boolean equalsIgnoreCase(String anotherString)

源码:

public boolean equalsIgnoreCase(String anotherString) {
    return (this == anotherString) ? true
        : (anotherString != null)
    && (anotherString.value.length == value.length)
        && regionMatches(true, 0, anotherString, 0, value.length);
}

相关文章
|
10天前
|
存储 JavaScript Java
Java 中的 String Pool 简介
本文介绍了 Java 中 String 对象及其存储机制 String Pool 的基本概念,包括字符串引用、构造方法中的内存分配、字符串文字与对象的区别、手工引用、垃圾清理、性能优化,以及 Java 9 中的压缩字符串特性。文章详细解析了 String 对象的初始化、内存使用及优化方法,帮助开发者更好地理解和使用 Java 中的字符串。
Java 中的 String Pool 简介
|
16天前
|
缓存 安全 Java
java 为什么 String 在 java 中是不可变的?
本文探讨了Java中String为何设计为不可变类型,从字符串池的高效利用、哈希码缓存、支持其他对象的安全使用、增强安全性以及线程安全等方面阐述了不可变性的优势。文中还通过具体代码示例解释了这些优点的实际应用。
java 为什么 String 在 java 中是不可变的?
|
10天前
|
存储 Java
Java 11 的String是如何优化存储的?
本文介绍了Java中字符串存储优化的原理和实现。通过判断字符串是否全为拉丁字符,使用`byte`代替`char`存储,以节省空间。具体实现涉及`compress`和`toBytes`方法,前者用于尝试压缩字符串,后者则按常规方式存储。代码示例展示了如何根据配置决定使用哪种存储方式。
|
26天前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
44 8
|
26天前
|
Java
在Java中如何将基本数据类型转换为String
在Java中,可使用多种方法将基本数据类型(如int、char等)转换为String:1. 使用String.valueOf()方法;2. 利用+运算符与空字符串连接;3. 对于数字类型,也可使用Integer.toString()等特定类型的方法。这些方法简单高效,适用于不同场景。
54 7
|
7月前
|
安全 Java
Java StringBuffer 和 StringBuilder 类
Java StringBuffer 和 StringBuilder 类
49 0
|
4月前
|
安全 Java
【Java基础面试二十七】、说一说StringBuffer和StringBuilder有什么区别
这篇文章介绍了Java中StringBuffer和StringBuilder的区别:StringBuffer是线程安全的,而StringBuilder是非线程安全的,因此在单线程环境下优先推荐使用StringBuilder以获得更好的性能。
|
4月前
|
安全 Java API
Java系类 之 String、StringBuffer和StringBuilder类的区别
这篇文章讨论了Java中`String`、`StringBuffer`和`StringBuilder`三个类的区别,其中`String`是不可变的,而`StringBuffer`是线程安全的可变字符串类,`StringBuilder`是非线程安全的可变字符串类,通常在单线程环境下性能更优。
Java系类 之 String、StringBuffer和StringBuilder类的区别
|
4月前
|
API C# 开发者
WPF图形绘制大师指南:GDI+与Direct2D完美融合,带你玩转高性能图形处理秘籍!
【8月更文挑战第31天】GDI+与Direct2D的结合为WPF图形绘制提供了强大的工具集。通过合理地使用这两种技术,开发者可以创造出性能优异且视觉效果丰富的WPF应用程序。在实际应用中,开发者应根据项目需求和技术背景,权衡利弊,选择最合适的技术方案。
200 0
|
7月前
|
存储 Java
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
下一篇
DataWorks