Java编程思想--13字符串

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."<init>":()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,重载增添了offsetboolean
endsWithboolean endssWith​(String prefix)boolean
indexOf(), lastIndexOfchar或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整数型(十进制)
cUnicode字符
bBoolean值
sString
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]
逻辑操作符含义
XYY在X后面
X|YX或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和正则表达式代替。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值