Java编程思想--13字符串

第十三章 字符串

  • 13.1 不可变的String
  • 13.2 重载“+”与StringBuilder
    • 13.2.1 javap反编译
  • 13.3 无意识的递归
  • 13.4 String常用方法
  • 13.5格式化输出
    • 13.5.1 printf()
    • 13.5.2 System,out.format()
    • 13.5.3 Formatter类
    • 13.5.4 格式化说明符
    • 13.5.5 Formatter转换
    • 13.5.6 String.format()
  • 13.6正则表达式
    • 13.6.1 基础
    • 13.6.2 创建正则表达式
      • (1)字符
      • (2)字符类
    • 13.6.3 量词
    • 13.6.4 Pattern与Matcher
    • 13.6.5 split()
    • 13.6.6 替换操作
    • 13.6.7 reset()
  • 13.7 扫描输入
  • 13.8 StringTokenizer

13.1 不可变的String

String对象是不可变的,每一次修改实际上都是创建了一个新的String对象。

13.2 重载“+”与StringBuilder

String的“+”与“+=”用于拼接字符串,但由于String是可变的,拼接多个字符串时会造成大量的垃圾。Java对此进行了优化,当拼接多个字符串时,编译器自动引用了StringBuilder变量。(新版本与书上例子不同)
使用StringBuilder可以很高效的进行字符串拼接。并且包含了丰富的方法:insert()、replace()、subString()、reverse()。其中append()与toString()比较常用。

public class Concatenation {
    public static void main(String[] args) {
        String mango = "mango";
        String s = "abs" + mango + "def" + 47;
        System.out.println(s);
    }
}
public class chapter13.Concatenation {
  public chapter13.Concatenation();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #7                  // String mango
       2: astore_1
       3: aload_1
       4: invokedynamic #9,  0              // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
       9: astore_2
      10: getstatic     #13                 // Field java/lang/System.out:Ljava/io/PrintStream;
      13: aload_2
      14: invokevirtual #19                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      17: return
}

13.2.1 javap反编译

对当前class字节码进行反编译生成汇编代码

javac chapter13\Concatenation.java
javap -c chapter13\Concatenation

13.3 无意识的递归

下面的程序,在覆盖的方法toString中,字符换拼接碰到了对象引用,会自动调用this对象的toString()方法,于是发生了递归调用。
为了消除递归,应该调用super.toString。

import java.util.*;

public class InfiniteRecursion {
  public String toString() {
    return " InfiniteRecursion address: " + this + "\n";
  }
  public static void main(String[] args) {
    List<InfiniteRecursion> v =
      new ArrayList<InfiniteRecursion>();
    for(int i = 0; i < 10; i++)
      v.add(new InfiniteRecursion());
    System.out.println(v);
  }
} ///:~

13.4 String常用方法

方法 参数返回值 描述
length() - 返回字符串长度
charAt() int索引 返回该索引上的char
toCharArray() - 生成char[], 里面包含String所有字符
equals(), equalsIgnoreCase() 与之相比的String 比较两个字符串内容是否相同 (忽略大小写)
compareTo, compareToIgnoreCase() 与之相比的String 按字典序比较两个字符串的内容
contains() 要搜索的CharSequence() 如果包含参数的内容,则返回True
contentEquals() 与之进行比较的CharSequence或者StringBuffer 如果包含参数的内容,则返回True
regionMatcher() 当前String索引的偏移量与另一个String索引的偏移量,要求比较的长度 boolean
startsWith 可能起始的String,重载增添了offset boolean
endsWith boolean endssWith​(String prefix) boolean
indexOf(), lastIndexOf char或char的索引 返回目标索引,如果不存在则返回-1
subString() 起始索引,起始+终止索引 返回新的String子串
concat() 要连接的String 返回已给您的String对象,包含两个字符串的拼接
replace() 要替换的字符串,用来替换的字符串 返回替换后的String对象,如果没有发生替换,则返回原始对象
toLowerCase(), toUpperCase() - 改变字符串大小写。若无需改变则返回原始String对象
trim() - 去掉两端空白字符,若无需改变则返回原始String对象
valueOf() 静态方法,重载版本为Object、boolean、char、int、long、short、float、double 返回
intern() - 详细解答

13.5格式化输出

13.5.1 printf()

13.5.2 System,out.format()

13.5.3 Formatter类

Formatter的构造器经过重载可以接受多种输出目的地。

13.5.4 格式化说明符

格式:%[argument_inde$][flags][width][.presion]conversion

“-”可以调整对齐方式,默认是右对齐。

import java.util.*;

public class Receipt {
  private double total = 0;
  private Formatter f = new Formatter(System.out);
  public void printTitle(inr) {
    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
*///:~

13.5.5 Formatter转换

类型转换符
d 整数型(十进制)
c Unicode字符
b Boolean值
s String
f 浮点数(十进制)
e 浮点数(科学计数)
x 整数(十六进制)
h 散列码(十六进制)
% 字符串%

13.5.6 String.format()

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

13.6正则表达式

13.6.1 基础

\表示要插入一个正则表达式的反斜线其后面的字符有特殊的意义,例如,表示一位数字\d,表示\,应该使用\\。

  1. “Hello”.matches(regular_string):检查字符串是否匹配某种模式
  2. “Hello”.split(regular_string):根据正则表达式进行字符串分割,其重载版本限制了修改的次数。

13.6.2 创建正则表达式

(1)字符

字符 含义
B 指定字符B
\xhh 十六进制为xhh的字符
\uhhhh 十六进制为oxhhhh的Unicode字符
\t 制表符Tab
\n 换行符
\r 回车
\f 换页
\e 转义Escape

(2)字符类

字符类 含义
. 任意字符
[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 非空白符[^s]
\d 数字[0-9]
\D 非数字[^0-9]
\w 词字符[a-zA-Z0-9]
\W 非词字符[^\w]
逻辑操作符 含义
XY Y在X后面
X|Y X或Y
(X) 捕获组。可以在表达式中用\i引用第i个捕获组
边界匹配符 含义
^ 一行的起始
$ 一行的结束
\b 词的边界
\B 非词的边界
\G 前一个匹配的结束

13.6.3 量词

  • 贪婪型:贪婪型表达式会为所有可能的模式发现尽可能多的匹配。
  • 勉强型:用问号来指定,这个量词满足模式所需的最少的字符。
  • 占有型:用+号来指定。此方式看可以防止回溯。
贪婪型 勉强型 占有型 含义
X? X?? X?+ 至多一个X
X* X*? X*+ 任意个X
X+ X+? X++ 至少一个X
X{n} X{n}? X{n}+ 恰好n次X
X{n,} X{n,}? X{n}+ 至少n次X
X{n,m} X{n,m}? X{n, m}+ X至少n次且不超过m次

表达式通常用圆括号包围起来,以便按照我们期望的效果去执行。

13.6.4 Pattern与Matcher

Pattern与Matcher组合是比String强大的正则表达式工具。

用法

  1. 先创建Pattern对象,位于java.util.regex包,然后调用Pattern.compile()方法来编译正则表达式,来产生Pattern对象。
  2. 调用Pattern.matcher()方法,该方法将会产生一个Matcher对象,该对象会有很多功能。
  • boolean matches()
  • lookingAt():判断该字符串的始部分(不必是整个字符串)是否能够匹配模式。
  • find():进行查找,查找成功,会跳到下一个
  • find(int start):从第start个位置开始查找
  • start(), end():当前匹配项的起始位置
  • group():当前匹配的字符串
  • groupCount:返回匹配到的个数
import java.util.regex.*;
// import static net.mindview.util.Print.*;

public class Finding {
  public static void main(String[] args) {
    Matcher m = Pattern.compile("\\w+")
      .matcher("Evening is full of the linnet's wings");
    while(m.find())
      System.out.print(m.group() + " ");
    System.out.println();
    int i = 0;
    while(m.find(i)) {
      System.out.print(m.group() + " ");
      i++;
    }
  }
} /* Output:
Evening is full of the linnet s wings
Evening vening ening ning ing ng g is is s full full ull ll l of of f the the he e linnet linnet innet nnet net et t s s wings wings ings ngs gs s
*///:~

13.6.5 split()

split()方法可以很便捷的将输入字符串断开形成对象数组。

13.6.6 替换操作

  • replaceFirst(String replacement):替换第一个
  • replaceAll(String replacement):替换所有
  • appendReplacement(String sbuf, String replacement):允许渐进式替换。

13.6.7 reset()

通过reset()方法,可以将现有的Matcher对象应用到新的字符序列。如果使用不带参的reset(),可以将Matcher对象重新设置到当前字符序列的起始位置。

13.7 扫描输入

13.8 StringTokenizer

可以用更加强大的split和正则表达式代替。

你可能感兴趣的:(Java基础复习)