java编程思想第四版读书笔记——第十三章字符串

severusyue severusyue     2022-07-31     406

关键词:

 Java编程思想第四版读书笔记——第十三章 字符串

字符串的操作是计算机程序设计中最常见的行为。

关键词: StringBuilder ,StringBuffer,toString(),format转换,正则表达式,


1、不可变String

String对象时不可变的。每当把String对象作为方法的参数时,都会复制一份引用。(其实就是对函数中参数列表中参数的操作不会影响外面的原参数)

如下:

import static net.mindview.util.Print.*;
public class Immutable {
public static String upcase(String s) {
return s.toUpperCase();
}
public static void main(String[] args) {
String q = "howdy";
print(q); // howdy
String qq = upcase(q);
print(qq); // HOWDY
print(q); // howdy q还是q
}
} /* Output:
howdy
HOWDY
howdy


2、重载“+”与StringBuilder

用于String的“+”与“+=”是Java中仅有的两个重载过的操作符,而Java并不允许程序员重载任何操作符。

在使用"+"操作符时,编译器自动引入了java.lang.StringBuilder类,避免了连加情况下产生大量需要回收的垃圾(每+一次就会产生一个新的字符串)。

因此,当为一个类编写toString()方法时,如果字符串操作简单,可以信赖编译器,它会为你合理的构造最终字符串结果。但是如果要在toString()中使用循环,那么最好自己创建一个StringBuilder对象,结合append()用它来构造最终结果

StringBuilder提供了丰富而全面的方法,包括insert()、replace()、subString()甚至reverse(),但最常用的还是append()和toString(),delete()方法。

StringBuilder是Java SE5引入的,在这之前还有Java的StringBuffer。StringBuffer是线程安全的,因此开销会大一些。StringBuilder字符串操作会更快一些。


3、无意识的递归

如果希望toString()方法打印出对象的内存地址,不可以使用this关键字。如果这样写:

public String toString() {
return " InfiniteRecursion address: " + this + " ";
}


编译器会试图将"+"后面的this转换为String,此时调用toString()函数,导致无穷递归。因此如果想要打印出内存地址,应该调用Object.toString()方法,所以调用super.toString()就可以了。

public String toString() {
return " InfiniteRecursion address: " + super.toString() + " ";
}

结果是:

[ E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]
, E02_RepairInfinite address: [email protected]

]

4、String上的操作

String的一些基本方法:

一、构造函数
     String(byte[ ] bytes):通过byte数组构造字符串对象
     String(char[ ] value):通过char数组构造字符串对象
     String(Sting original):构造一个original副本。即:拷贝一个original
     String(StringBuffer buffer):通过StringBuffer数组构造字符串对象。

二、方法

1. char charAt(int index) :取字符串中的某一个字符,其中的参数index指的是字符串中序数。字符串的序数从0开始到length()-1 。
    例如:String s = new String("abcdefghijklmnopqrstuvwxyz");
          System.out.println("s.charAt(5): " + s.charAt(5) );
          结果为: s.charAt(5): f
2. int compareTo(String anotherString) :当前String对象与anotherString比较相等关系返回0不相等时,从两个字符串第0个字符开始比较,返回第一个不相等的字符差,另一种情况,较长字符串的前面部分恰巧是较短的字符串,返回它们的长度差。
3. int compareTo(Object o) :如果o是String对象,和2的功能一样;否则抛出ClassCastException异常。
    例如:String s1 = new String("abcdefghijklmn");
            String s2 = new String("abcdefghij");
           String s3 = new String("abcdefghijalmn");
           System.out.println("s1.compareTo(s2): " + s1.compareTo(s2) ); //返回长度差
           System.out.println("s1.compareTo(s3): " + s1.compareTo(s3) ); //返回‘k‘-‘a‘的差
           结果为:s1.compareTo(s2): 4
                       s1.compareTo(s3): 10
4. String concat(String str) :将该String对象与str连接在一起。
5. boolean contentEquals(StringBuffer sb) 将该String对象与StringBuffer对象sb进行比较。
6. static String copyValueOf(char[] data) 
7. static String copyValueOf(char[] data, int offset, int count) :这两个方法将char数组转换成String,与其中一个构造函数类似。
8. boolean endsWith(String suffix) :该String对象是否以suffix结尾
    例如:String s1 = new String("abcdefghij");
           String s2 = new String("ghij");
           System.out.println("s1.endsWith(s2): " + s1.endsWith(s2) );
           结果为:s1.endsWith(s2): true
9. boolean equals(Object anObject) :当anObject不为空并且与当前String对象一样,返回true;否则,返回false
10. byte[] getBytes() :将该String对象转换成byte数组
11. void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) :该方法将字符串拷贝到字符数组中。其中,srcBegin为拷贝的起始位置、srcEnd为拷贝的结束位置、字符串数值dst为目标字符数组、dstBegin为目标字符数组的拷贝起始位置。
     例如:char[] s1 = {‘I‘,‘ ‘,‘l‘,‘o‘,‘v‘,‘e‘,‘ ‘,‘h‘,‘e‘,‘r‘,‘!‘};//s1=I love her!
           String s2 = new String("you!"); s2.getChars(0,3,s1,7); //s1=I love you!
           System.out.println( s1 );
           结果为:I love you!
12. int hashCode() :返回当前字符的哈希表码
13. int indexOf(int ch) :只找第一个匹配字符位置
14. int indexOf(int ch, int fromIndex) :fromIndex开始找第一个匹配字符位置
15. int indexOf(String str) :只找第一个匹配字符串位置
16. int indexOf(String str, int fromIndex) :从fromIndex开始找第一个匹配字符串位置
      例如:String s = new String("write once, run anywhere!");
              String ss = new String("run");
              System.out.println("s.indexOf(‘r‘): " + s.indexOf(‘r‘) );
              System.out.println("s.indexOf(‘r‘,2): " + s.indexOf(‘r‘,2) );
              System.out.println("s.indexOf(ss): " + s.indexOf(ss) );
              结果为:s.indexOf(‘r‘): 1
                      s.indexOf(‘r‘,2): 12
                      s.indexOf(ss): 12
17. int lastIndexOf(int ch)
18. int lastIndexOf(int ch, int fromIndex)
19. int lastIndexOf(String str)
20. int lastIndexOf(String str, int fromIndex) 以上四个方法与13、14、15、16类似,不同的是:找后一个匹配的内容
public class CompareToDemo {
      public static void main (String[] args) {
           String s1 = new String("acbdebfg");
      
           System.out.println(s1.lastIndexOf((int)‘b‘,7));
     }
}
运行结果5
       (其中fromIndex的参数为 7,是从字符串acbdebfg的最后一个字符g开始往前数的位数。既是从字符c开始匹配,寻找最后一个匹配b的位置。所以结果为 5


21. int length() :返回当前字符串长度
22. String replace(char oldChar, char newChar) :将字符号串中第一个oldChar替换成newChar
23. boolean startsWith(String prefix) :该String对象是否以prefix开始
24. boolean startsWith(String prefix, int toffset) :该String对象从toffset位置算起,是否以prefix开始
     例如:String s = new String("write once, run anywhere!");
             String ss = new String("write");
             String sss = new String("once");
             System.out.println("s.startsWith(ss): " + s.startsWith(ss) );
             System.out.println("s.startsWith(sss,6): " + s.startsWith(sss,6) );
             结果为:s.startsWith(ss): true
                     s.startsWith(sss,6): true
25. String substring(int beginIndex) 取从beginIndex位置开始到结束的子字符串
26.String substring(int beginIndex, int endIndex) :取从beginIndex位置开始到endIndex位置的子字符串
27. char[ ] toCharArray() :将该String对象转换成char数组
28. String toLowerCase() :将字符串转换成小写
29. String toUpperCase() :将字符串转换成大写。
     例如:String s = new String("java.lang.Class String");
             System.out.println("s.toUpperCase(): " + s.toUpperCase() );
             System.out.println("s.toLowerCase(): " + s.toLowerCase() );
             结果为:s.toUpperCase(): JAVA.LANG.CLASS STRING
                  s.toLowerCase(): java.lang.class string
30. static String valueOf(boolean b)
31. static String valueOf(char c)
32. static String valueOf(char[] data)
33. static String valueOf(char[] data, int offset, int count)
34. static String valueOf(double d)
35. static String valueOf(float f)
36. static String valueOf(int i)
37. static String valueOf(long l)
38. static String valueOf(Object obj)

     以上方法用于将各种不同类型转换成Java字符型。这些都是类方法。下面挑选一些上面常用的方法:

Java中String类的常用方法:

public char charAt(int index)

返回字符串中第index个字符;
public int length()
返回字符串的长度;
public int indexOf(String str)
返回字符串中第一次出现str的位置;
public int indexOf(String str,int fromIndex)
返回字符串从fromIndex开始第一次出现str的位置;
public boolean equalsIgnoreCase(String another)
比较字符串与another是否一样(忽略大小写);
public String replace(char oldchar,char newChar)
在字符串中用newChar字符替换oldChar字符
public boolean startsWith(String prefix)
判断字符串是否以prefix字符串开头;
public boolean endsWith(String suffix)
判断一个字符串是否以suffix字符串结尾;
public String toUpperCase()
返回一个字符串为该字符串的大写形式;
public String toLowerCase()
返回一个字符串为该字符串的小写形式
public String substring(int beginIndex)
返回该字符串从beginIndex开始到结尾的子字符串;
public String substring(int beginIndex,int endIndex)
返回该字符串从beginIndex开始到endsIndex结尾的子字符串
public String trim()
返回该字符串去掉开头和结尾空格后的字符串
public String[] split(String regex)
将一个字符串按照指定的分隔符分隔,返回分隔后的字符串数组


5、格式化的输出

Java SE5推出了格式化输出这一功能。如下:

printf()

printf()并不是用重载的“+”操作符来连接引号内的字符串,而是使用特殊的占位符来表示数据将来的位置。而且它还将插入格式化字符串的参数,以逗号分隔,排成一行。

printf("Row 1: [%d %f] ", x, y);

这些占位符称作格式修饰符,它不但说明了插入位置,还说明了插入说明类型的变量,%d表示整数,%f表示浮点数,%s表示字符串。


System.out.format()

Java SE5引入的format方法可用于PrintStream或者PrintWriter对象。其中也包括System.out对象。

format()方法模仿自C的printf(),两者是等价的,以下展示三种方法输出坐标点:

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] ", x, y);
// or
System.out.printf("Row 1: [%d %f] ", x, y);
}
} /* Output:
Row 1: [5 5.332542]
Row 1: [5 5.332542]
Row 1: [5 5.332542]


Formatter类

在Java中,所有新的格式化功能都有java.util.Formatter处理。Formatter构造器经过重载可以接受多种输出目的地,最常用的还是PrintStream()OutputStream和File。

如下所示:

import java.io.*;
import java.util.*;
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) ", 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)


tommy输出到System.out中,terry输出到System.out的一个别名中。


格式化说明符

为了在插入数据是控制空格和对齐,需要更加精细的格式修饰符。格式如下:

[argument_index$][flags][width][.precision]conversion

flags表示左右对齐,默认是右对齐,如果想左对齐就使用“-”标志

with控制最小尺寸(宽度)至少该这么长,不够用空格替代。

在with后面加上"."后面表示精度precision。

用于String(%s)时,表示最多可写的字符数

用于浮点数(%f)表示小数点后面的位数,多了舍入,少了补0,默认是6位

用于整数(%d)时,不可用于整数,会触发异常


下面是例子:

import java.util.*;
public class Receipt {
private double total = 0;
private Formatter f = new Formatter(System.out);
public void printTitle() {
f.format("%-15s %5s %10s ", "Item", "Qty", "Price");  //Item项都有“-”,表示左对齐,其余项都是右对齐
f.format("%-15s %5s %10s ", "----", "---", "-----");
}
public void print(String name, int qty, double price) {
f.format("%-15.15s %5d %10.2f ", name, qty, price);    //name是左对齐并且最多15个字符,包括空格。price最多小数点后两位。
total += price;
品悟性能优化读书笔记-第十三章

1.Oracle的自动化工具,直接截图了,不过我好想就用过AWRAWR相关的命令:快照默认时间的更改:EXECDBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(interval=>30);修改默认时间从一小时改到30分钟(还未做实验)创建快照EXECDBMS_WORKLOAD_REPOSITOR... 查看详情

算法导论读书笔记-第十三章-红黑树

算法导论第13章红黑树红黑树(red-blacktree)是许多平衡搜索树中的一种,可以保证在最坏情况下基本动态集合操作的时间复杂度为O(lgn).13.1红黑树的性质红黑树(red-blacktree):满足下面性质的二叉搜索树:每个结点是红色的或者黑色的.根... 查看详情

《java编程思想》读书笔记<一>

第二章一切皆对象java是面向对象的语言。1.我们怎么操作对象?每种语言都有自己的操纵内存中元素的方式,java使用引用操作内存中元素(对象)。引用可以独立存在,例如:Strings;表示创建一个引用。但是对象一旦创建,需... 查看详情

java学习笔记第十三章css

JAVA学习笔记第十三章13.CSS13.1CSS书写方式【1】内联样式【2】内部样式【3】外部样式有多个html页面需要用到该样式,可以在css文件夹下新建css文件mystyle.css在html文件中通过link导入css【4】实际开发中常用第三种方式,这种方式真... 查看详情

onjava8第十三章函数式编程

...作为闭包的内部类7函数组合8柯里化和部分求值9纯函数式编程10本章小结函数式编程的中心思想:是把函数作为参数传递给另一个函数,或把函数作为一个返回值。只是为了使程序适合有限的内存,程序员通过修改内存中的代 查看详情

《代码大全》阅读笔记-目录

...:可以工作的类第七章:高质量的子程序第八章:防御式编程第九章:伪代码编程过程第三部分:变量第十章:使用变量的一般事项第十一章:变量名的力量第十二章:基本数据类型第十三章:不常见的数据类型第四部分:语句... 查看详情

『java编程思想-第四版』第二章:一切都是对象

Java编程思想-第四版学习总结,此为第二章:一切都是对象.packagecom.w3cjava.second;@SuppressWarnings("all")publicclassSecond{/***Java编程思想(第四版)*第2章一切都是对象*@paramargs*/publicstaticvoidmain(String[]args){/***2.1用引用操作对象*遥控器(引用)操... 查看详情

java编程思想第四版(完整中文高清版)pdf

...问权限控制、复用类、多态、接口、通过异常处理错误、字符串、泛型、数组、容器深入研究、JavaI/O系统、枚举类型、并发以及图形化用户界面等内容。这些丰富的内容,包含了Java语言基础语法以及高级特性,适合各个层次的J... 查看详情

《programminginc》读书笔记

...第七章、函数使用  第八章、结构体使用  第九章、字符串使用  第十章、指针  第十一章、位运算  第十 查看详情

一起读《java编程思想》(第四版)

实习期间利用空余时间看《Java编程思想》(第四版)这本书,遇到不懂的知识点就记录在本博客内。 1.5复用具体实现Java代码复用的三种常见方式:继承、组合、代理。1、继承:使用extends关键字在基类的基础上创建新类,... 查看详情

《csapp》读书笔记

第一章第二章第三章第四章第五章第六章第七章链接可重定位目标文件符号和符号表符号解析第八章第九章第十章第十一章第十二章逐步添加。。 查看详情

java编程思想第四版*第五章个人练习

练习3:(1)创建一个带默认构造器(即无參构造器)的类。在构造器中打印一条消息。为这个类创建一个对象。P116publicclassTest{ publicTest(){ System.out.println("HelloWord"); } publicstaticvoidmain(String[]args){ newTest(); } /** *执行结果 ... 查看详情

深入理解计算机系统第十三章-并发编程

CopyfromOneNote乍一看还以为本科时候没上过……感觉大二学的真是云里雾里(其实现在也没好到哪里去)。看看有啥练手的做一做,或者看看源码吧……  查看详情

第十三章元表与元方法lua程序设计笔记

--第十三章元表与元方法Lua中每个值都有一个表。table和userdata可以有各自独立的元表,其他类型的值共享一个元表。Lua中只能设置table的元表。若要设置其他类型的值的元表,则必须通过C代码来完成。--13.1算数类型的元方法Set={}... 查看详情

读书笔记-js高级程序设计-第十五章使用canvas绘图

读书笔记-js高级程序设计-第十三章事件 canvas具备绘图能力的2D上下文及文本API很多浏览器对WebGL的3D上下文支持还不够好 有时候即使浏览器支持,操作系统如果缺缺乏必要的绘图驱动程序,则浏览器即使支持了也没用 ... 查看详情

“全栈2019”java第四十三章:封装

...开发环境JDKv11IntelliJIDEAv2018.3文章原文链接“全栈2019”Java第四十三章:封装下一章“全栈2019”Java第四十四章:继承学习小组加入同步学习小组,共同交流与进步。方式一:关注头条号Gorhaf,私信“Java学习小组”。方式二:关注... 查看详情

[读书笔记]java编程思想(代码片段)

...10章内部类第11章持有对象第12章通过异常处理错误第13章字符串第14章类型信息第15章泛型第16章数组第17章容器深入研究第18章JavaI/O系统第19章枚举类型第20章注解第21章并发第22章图形化用户界面第1章对象导论第2章一切都是对象... 查看详情

第十三章磁盘文件管理

第十三章、磁盘管理本章内容磁盘结构1、分区类型管理分区2、管理文件系统3、挂载设备管理虚拟内存设备文件?I/OPorts:I/O设备地址?一切皆文件:open(),read(),write(),close()? 设备类型:块设备:block,存取单位“块”,磁盘字符... 查看详情