Java:String类再回顾(上)

简介: Java:String类再回顾(上)

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

类是不可改变的,所以一旦创建了 String 对象,那它的值就无法改变了。 如果需要对字符串做很多修改,那么应该选择使用

StringBuffer & StringBuilder 类


为什么String类是不可改变的?

String s = "AAAA";
System.out.println("s = " + s);
s = "BBBB";
System.out.println("s = " + s);

输出结果:


AAAA
BBBB


从结果上看是改变了,但为什么说String对象是不可变的呢?


原因在于实例中的 s 只是一个 String 对象的引用,并不是对象本身,当执行 s = “BBBB”; 创建了一个新的对象 “BBBB”,而原来的 “AAAA” 还存在于内存中。

如图:

20191115110911655.png

或者根据 jdk 的源码来分析。

字符串实际上就是一个 char 数组,并且内部就是封装了一个 char 数组。

并且这里 char 数组是被 final 修饰的:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

并且 String 中的所有的方法,都是对于 char 数组的改变,只要是对它的改变,方法内部都是返回一个新的 String 实例。


Java:String、StringBuffer 和 StringBuilder 的区别


String:字符串常量,字符串长度不可变。Java中String 是immutable(不可变)的。用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。


StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。Java.lang.StringBuffer 线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。


StringBuilder:字符串变量(非线程安全)。在内部 StringBuilder 对象被当作是一个包含字符序列的变长数组。


基本原则:


如果要操作少量的数据用 String ;

单线程操作大量数据用StringBuilder ;

多线程操作大量数据,用StringBuffer。

String类支持的方法:


获取字符串长度 用于获取有关对象的信息的方法称为访问器方法。


String 类的一个访问器方法是 length() 方法

1、length() 方法是针对字符串来说的,要求一个字符串的长度就要用到它的length()方法;

2、length 属性是针对 Java 中的数组来说的,要求数组的长度可以用其 length 属性;

3、Java 中的 size() 方法是针对泛型集合说的, 如果想看这个泛型有多少个元素, 就调用此方法来查看!

连接字符串


concat() 方法


'+'操作符

String a = "a";
String b = "b";
String c = a + b

相当于:

String c = new StringBuffer().append(a).append(b).toString();


对于字符串的加运算,当编译成 class 文件时,会自动编译为 StringBuffer 来进行字符串的连接操作。

同时对于字符串常量池:

当一个字符串是一个字面量时,它会被放到一个常量池中,等待复用。

String a = "saff";
String b = "saff";
String c = new String("saff");
System.out.println(a.equal(b));  // true
System.out.println(a.equal(c));  // true

这个就是字符串的常量池。


创建格式化字符串


String 类的静态方法 format() 能用来创建可复用的格式化字符串,而不仅仅是用于一次打印输出。

返回指定索引处的 char 值


charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。

字符串与对象进行比较、按字典顺序比较两个字符串


int compareTo(Object o)


compareTo(String anotherString)


关于这个方法,不管参数是对象还是字符串,最终要比较的都是两个字符串的不同,以下称调用方法那边的为原字符串,方法参数里的为参数字符串。


这个方法分为两种比较方式:


1、不同的字符在较短字符串长度之内时


2、不同的字符在较短字符串长度之外时


看下 compareTo 的源码:

/*
*如果参数字符串等于此字符串,则返回值 0;
*如果此字符串按字典顺序小于字符串参数,则*返回一个小于 0 的值;
*如果此字符串按字典顺序大于字符串参数,则返回一个大于 0 的值。
*/
public int compareTo(String anotherString) {
    int len1 = value.length;
    int len2 = anotherString.value.length;
    //取数组长度里面最小的
    int lim = Math.min(len1, len2);
    // 获得两个数组,这两个数组就是string的属性
    char v1[] = value;
    char v2[] = anotherString.value;
    int k = 0;
    while (k < lim) {
    //获取第K的字符,进行比较
        char c1 = v1[k];
        char c2 = v2[k];
        if (c1 != c2) {
        //Java使用的是Unicode编码,因此返回这两个字符的Unicode差值。
            return c1 - c2;
        }
        k++;
    }
    //如果前lim个字符都相同,那么就返回长度差。
    return len1 - len2;
}


  • 1、取得string的value数组
  • 2、取得value数组里面的元素
  • 3、按照unicode值进行比较
  • 4、返回比较的值

String a = "a";
String b = "b";
System.out.println(a.compareTo(b));

输出值 -1

String a = "b";
String b = "a";
System.out.println(a.compareTo(b));

输出值 1

String a = "a";
String b = "a";
System.out.println(a.compareTo(b));

输出 0

两个字符串首字母不同,则该方法返回首字母的 asc 码的差值。

String a = "abc";
String b = "bcdfg";
System.out.println(a.compareTo(b));

输出 -1。

参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的 ascii 码差值。

String a = "abc";
String b = "abedfg";
System.out.println(a.compareTo(b));


输出 -2。

两个字符串不一样长,可以参与比较的字符又完全一样,则返回两个字符串的长度差值。

String a = "abc";
String b = "abcdefg";
System.out.println(a.compareTo(b));


输出 -4。

string a = "abcde";
String b = "abcd";
System.out.println(a.compareTo(b));


输出 1

目前 compareTo 项目中的用途是比较版本号的高低。

String a = "1.0.0";
String b = "1.0.1";
System.out.println(a.compareTo(b));


输出 -1。


目录
相关文章
|
2月前
|
安全 Java 数据建模
Java记录类:简化数据载体的新选择
Java记录类:简化数据载体的新选择
184 101
|
2月前
|
安全 Java 开发者
Java记录类:简化数据载体的新方式
Java记录类:简化数据载体的新方式
242 100
|
3月前
|
安全 IDE Java
Java记录类型(Record):简化数据载体类
Java记录类型(Record):简化数据载体类
337 120
|
16天前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
69 4
|
21天前
|
IDE JavaScript Java
在Java 11中,如何处理被弃用的类或接口?
在Java 11中,如何处理被弃用的类或接口?
118 5
|
24天前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
88 1
|
24天前
|
Java Go 开发工具
【Java】(8)正则表达式的使用与常用类分享
正则表达式定义了字符串的模式。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
149 2
|
24天前
|
存储 Java 程序员
【Java】(6)全方面带你了解Java里的日期与时间内容,介绍 Calendar、GregorianCalendar、Date类
java.util 包提供了 Date 类来封装当前的日期和时间。Date 类提供两个构造函数来实例化 Date 对象。第一个构造函数使用当前日期和时间来初始化对象。Date( )第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
102 1
|
24天前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
93 1
|
30天前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
187 5