Java字符串

1 不可变Strng

1.1 概述

String对象是不可变的
修改String值,实际上是创建了一个全新的String对象

1.2 源码分析

(1)成员变量

String底层是用char[]字符数组实现的
成员变量是final类型,因此是不能改变的,每次修改都会创建一个新的String

/** String的属性值 */  
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    /**数组被使用的开始位置**/
    private final int offset;

    /** The count is the number of characters in the String. */
    /**String中元素的个数**/
    private final int count;

    /** Cache the hash code for the string */
   /**String类型的hash值**/
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;
    /**
     * Class String is special cased within the Serialization Stream         Protocol.
     *
     * A String instance is written into an ObjectOutputStream according to
     * <a href="{@docRoot}/../platform/serialization/spec/output.html">
     * Object Serialization Specification, Section 6.2, "Stream Elements"</a>
     */

  private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

String的成员变量
(2)构造方法
String() 
          初始化一个新创建的 String 对象,使其表示一个空字符序列。 
String(byte[] bytes) 
          通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。 
String(byte[] bytes, Charset charset) 
          通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。  
String(byte[] bytes, int offset, int length) 
          通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。 
String(byte[] bytes, int offset, int length, Charset charset) 
          通过使用指定的 charset 解码指定的 byte 子数组,构造一个新的 String。 
String(byte[] bytes, int offset, int length, String charsetName) 
          通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String。 
String(byte[] bytes, String charsetName) 
          通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。 
String(char[] value) 
          分配一个新的 String,使其表示字符数组参数中当前包含的字符序列。 
String(char[] value, int offset, int count) 
          分配一个新的 String,它包含取自字符数组参数一个子数组的字符。 
String(int[] codePoints, int offset, int count) 
          分配一个新的 String,它包含 Unicode 代码点数组参数一个子数组的字符。 
String(String original) 
          初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。 
String(StringBuffer buffer) 
          分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。 
String(StringBuilder builder) 
          分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。

2 重载“+”StringBuilder

StringBuilder时Java SE5引入的,之前用的都是StringBuffer,后者是前程安全的,但开销会比较大

public class WhitherStringBuilder {
  //前者在构造字符串时,虽然没有使用StringBuilder,但编译器会自动调用,并且在每个循环中创建一个新的StringBuilder
  public String implicit(String[] fields) {
    String result = "";
    for(int i = 0; i < fields.length; i++)
      result += fields[i];
    return result;
  }
  //后者因为显示的使用StringBuilder,所以整个过程中只会产生一个StringBuilder,可以避免多次重新分配缓冲
  public String explicit(String[] fields) {
    StringBuilder result = new StringBuilder();
    for(int i = 0; i < fields.length; i++)
      result.append(fields[i]);
    return result.toString();
  }
}

3 创建String对象的两种方式

(1) 直接赋值

创建的对象在方法区的常量池

String str=“hello”;//直接赋值的方式

(2)通过构造方法

创建的对象在堆内存

String str=new String(“hello”);//实例化的方式

(3)比较

public class TestString {
    public static void main(String[] args) {
        String str1 = "Lance";
        String str2 = new String("Lance");
        String str3 = str2; //引用传递,str3直接指向st2的堆内存地址
        String str4 = "Lance";
        /**
         *  ==:
         * 基本数据类型:比较的是基本数据类型的值是否相同
         * 引用数据类型:比较的是引用数据类型的地址值是否相同
         * 所以在这里的话:String类对象==比较,比较的是地址,而不是内容
         */
         System.out.println(str1==str2);//false
         System.out.println(str1==str3);//false
         System.out.println(str3==str2);//true
         System.out.println(str1==str4);//true
         /*如果采用直接赋值的方式(String str="Lance")进行对象的实例化,则会将匿名对象“Lance”放入对象池,每当下一次对不同的对象进行直接赋值的时候会直接利用池中原有的匿名对象,这样,所有直接赋值的String对象,如果利用相同的“Lance”,则String对象==返回true;*/
    }

}

4 String常用方法

4.1 String的判断功能

boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String str): 比较字符串的内容是否相同,忽略大小写
boolean startsWith(String str): 判断字符串对象是否以指定的str开头
boolean endsWith(String str): 判断字符串对象是否以指定的str结尾

4.2 String类的获取功能

int length():获取字符串的长度,其实也就是字符个数
char charAt(int index):获取指定索引处的字符
int indexOf(String str):获取str在字符串对象中第一次出现的索引
String substring(int start):从start开始截取字符串
String substring(int start,int end):从start开始,到end结束截取字符串。包括start,不包括end

4.3 String的转换功能

char[] toCharArray():把字符串转换为字符数组
String toLowerCase():把字符串转换为小写字符串
String toUpperCase():把字符串转换为大写字符串

4.4 其他常用方法

String trim() 去除字符串两端空格
String[] split(String str) 按照指定符号分割字符串

5 格式化输出

5.1 System.out.format()

format方法类似于c语言的printf()
适用于PrintStream和PrintWriter以及System.out对象

public class SimpleFormat {
  public static void main(String[] args) {
    int x = 5;
    double y = 5.332542;
    // The old way:
    System.out.println("Row 1: [" + x + " " + y + "]");
    // The new way:
    System.out.format("Row 1: [%d %f]\n", x, y);
    // or
    System.out.printf("Row 1: [%d %f]\n", x, y);
  }
} /* Output:
Row 1: [5 5.332542]
Row 1: [5 5.332542]
Row 1: [5 5.332542]
*///:~

5.2 Formatter类

所有新的格式化功能都由java.util.Formatter类处理

public class Turtle {
  private String name;
  private Formatter f;
  public Turtle(String name, Formatter f) {
    this.name = name;
    this.f = f;
  }
  public void move(int x, int y) {
    f.format("%s The Turtle is at (%d,%d)\n", name, x, y);
  }
  public static void main(String[] args) {
    PrintStream outAlias = System.out;
    Turtle tommy = new Turtle("Tommy",new Formatter(System.out));
    Turtle terry = new Turtle("Terry",new Formatter(outAlias));
    tommy.move(0,0);
    terry.move(4,8);
    tommy.move(3,4);
    terry.move(2,5);
    tommy.move(3,3);
    terry.move(3,3);
  }
} /* Output:
Tommy The Turtle is at (0,0)
Terry The Turtle is at (4,8)
Tommy The Turtle is at (3,4)
Terry The Turtle is at (2,5)
Tommy The Turtle is at (3,3)
Terry The Turtle is at (3,3)
*///:~

5.3 格式化说明符

%[argument_index$][flags][width][.precision]conversion
argument_index是一个十进制整数,顾名思义,表示后面参数的位置
flags是用于控制输出格式,但具体怎么控制还要看末尾的转换符(conversion)
width用来指定最大尺寸
precision 应用于String时,表示打印String时输出字符的最大数量
应用于浮点数时,表示小数部分显示的位数,过多则舍去,少则补0

public class Receipt {
    private double total = 0;
    private Formatter f = new Formatter(System.out);
    public void printTitle() {
        f.format("%-15s %5s %10s\n", "Item", "Qty", "Price"); //"-"表示左对齐
        f.format("%-15s %5s %10s\n", "----", "---", "-----");
    }
    public void print(String name, int qty, double price) {
        f.format("%-15.15s %5d %10.2f\n", name, qty, price);
        total += price;
    }
    public void printTotal() {
        f.format("%-15s %5s %10.2f\n", "Tax", "", total*0.06);
        f.format("%-15s %5s %10s\n", "", "", "-----");
        f.format("%-15s %5s %10.2f\n", "Total", "",
                total * 1.06);
    }
    public static void main(String[] args) {
        Receipt receipt = new Receipt();
        receipt.printTitle();
        receipt.print("Jack's Magic Beans", 4, 4.25);
        receipt.print("Princess Peas", 3, 5.1);
        receipt.print("Three Bears Porridge", 1, 14.29);
        receipt.printTotal();
    }
} /* Output:
Item              Qty      Price
----              ---      -----
Jack's Magic Be     4       4.25
Princess Peas       3       5.10
Three Bears Por     1      14.29
Tax                         1.42
                           -----
Total                      25.06
*///:~

5.4 String.format()

是一个static方法,接受与Formatter.format()方法一样的参数,但返回一个String对象

//String.format()内部也是创建一个Formatter对象
public class DatabaseException extends Exception {
  public DatabaseException(int transactionID, int queryID,
    String message) {
    super(String.format("(t%d, q%d) %s", transactionID,
        queryID, message));
  }
  public static void main(String[] args) {
    try {
      throw new DatabaseException(3, 7, "Write failed");
    } catch(Exception e) {
      System.out.println(e);
    }
  }
} /* Output:
DatabaseException: (t3, q7) Write failed
*///:~

6 正则表达式

6.1 基础

正则表达式就是以某种方式来描述字符串

6.2 创建正则表达式

字符类表示
.匹配单个任意字符(除\n)
[abc]包含a、b、c的任何字符
[^abc]除了a、b、c之外的任何字符
[a-zA-Z]从a到z或从A到Z的任何字符
[abc[hij]]任意a、b、c、h、i、j字符(合并)
[a-z&&[hij]]任意h、i或j(交)
\s空白格(空格、tab、换行、换页和回车)
\S非空白格
\d数字[0-9]
\D非数字[^0-9]
\w词字符[a-zA-Z0-9]
\W非词字符[^\w]
边界匹配符说明
^开始的标志
$结束的标志
\b词的边界
\B非词的边界
\G前一个匹配的结果
特殊字符说明
+匹配某元素一次或多次
匹配某元素0次或1次
*匹配某元素0次或多次
{n}n 是一个非负整数,匹配确定的n 次
{n,}n 是一个非负整数,至少匹配n 次
{n,m}最少匹配 n 次且最多匹配 m 次,在逗号和两个数之间不能有空格
xIy匹配 x 或 y

阅读《JAVA编程思想》以及大佬的博客所写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值