JAVA基础10面向对象思考

本文深入探讨了JAVA中的面向对象编程,包括类的抽象和封装,强调了类的实现与使用分离以及封装的重要性。文章还讲解了类的关系,如关联、聚集和组合,以及在实际编程中如何体现这些概念。此外,介绍了基本数据类型值的包装类,如Integer和Double,以及基本类型与包装类之间的自动转换。最后,讨论了String类的不可变性及其常用方法,如构造、替换、分隔等,以及StringBuilder和StringBuffer在字符串操作中的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

10. 面向对象思考

10.1 类的抽象和封装

类的抽象是指将类的实现和类的使用分离开实现的细节被封装并且对用户隐藏,这被称为类的封装。

前面已经学习了方法的抽象以及如何在逐步求精中使用它。Java 提供了多层次的抽象。类抽象class abstraction) 是将类的实现和使用分离类的创建者描述类的功能让使用者明白如何才能使用类。从类外可以访问的方法和数据域的集合以及预期这些成员如何行为的描述,合称为类的合约classs contract)如下图所示类的使用者不需要知道类是如何实现的。实现的细节经过封装对用户隐藏起来这称为类的封装class encapsulation)例如:可以创建一个 Circle 对象并且可以在不知道面积是如何计算出来的情况下求出这个圆的面积。由于这个原因,类也称为抽象数据类型Abstract Data Type, ADT)

类的抽象和封装是一个问题的两个方面现实生活中的许多例子都可以说明类抽象的概念。例如考虑建立一个计算机系统个人计算机有很多组件~~CPU内存磁盘主板和风扇等。每个组件都可以看作是一个有属性和方法的对象要使各个组件一起工作,只需要知道每个组件是怎么用的以及是如何与其他组件进行交互的,而无须了解这些组件内部是如何工作的。内部功能的实现被封装起来对你是隐藏的所以你可以组装一台计算机,而不需要了解每个组件的功能是如何实现的。

对计算机系统的模拟准确地反映了面向对象方法每个组件可以看成组件类的对象例如,你可能已经建立了一个类模拟用在计算机上的各种类型的风扇它具有风扇尺寸和速度等属性,还有像开始和停止这样的方法一个具体的风扇就是该类具有特定属性值的实例

 

 

10.2 面向对象的思考

面向过程的范式重点在于设计方法面向对象的范式将数据和方法耦合在一起构成对象。使用面向对象范式的软件设计重点在对象以及对对象的操作上

一个程序的代码在 main 方法中就不能在其他程序中重用。为使之具备可重用性定义一个静态方法计算身体质量指数如下所示

public static double getBMI(double weight, double height)

这个方法对于计算给定体重和身高的身体质量指数是很有用的但是它是有局限性的。假设需要将体重和身髙同一个人的名字与出生日期相关联虽然可以分别声明几个变量来存储这些值,但是这些值不是紧密耦合在一起的将它们耦合在一起的理想方法就是创建一个包含它们的对象。因为这些值都被绑定到单独的对象上所以它们应该存储在实例数据域中。可以定义一个名为 BMI的类如下图所示:

假设 BMI 类是可用的。下列程序清单给出使用这个类的测试程序。显示

    UseBMICIass.java
public class UseBMICIass { 
    public static void main(String[] args){ 
        BMI bmil = new BMI("Kim Yang",18, 145, 70); 
        System.out.println("The BMI for " + bmil.getName() + " is ")+ bmi1.getBMI() + " " + bmil.getStatus());
        BMI bmi2 = new BMI("Susan King", 215, 70);
        System.out.println("The BMI for " + bmi2.getName()+ " is " + bmi2.getBMI() + " "bmi2.getStatus());
    }
}
        

显示

The BMI for Kim Yang is 20.81 Normal
The BMI for Susan King is 30.85 0bese

3 行为 Kim Yang 创建一个对象 bmi1, 而第 7行为 Susan King 创建一个对象 bmi2可以使用实例方法 getName( )、getBMI( )和 getStatus( )返回一个 BMI 对象中的 BMI 信息

 

 

10.3 类的关系

为了设计类需要探究类之间的关系类中间的关系通常是关联聚合组合以及继承

10.3.1 关联

关联是一种常见的二元关系描述两个类之间的活例如学生选取课程是 Student类和 Course 类之间的一种关联而教师教授课程是 Faculty 类和 Course 类之间的关联这些关联可以使用 UML 图形标识来表达如下图所示:

关联由两个类之间的实线表示可以有一个可选的标签描述关系。上图标签是Take 和 Teach每个关系可以有一个可选的小的黑色三角形表明关系的方向在该图中方向表明学生选取课程(而不是相反方向的课程选取学生

关系中涉及的每个类可以有一个角色名称描述在该关系中担当的角色。上图,Teacher 是 Faculty 的角色名关联中涉及的每个类可以给定一个多重性(multiplicity), 放置在类的边上用于给定 UML 图中关系所涉及的类的对象数。多重性可以是一个数字或者一个区间决定在关系中涉及类的多少个对象。字符 * 意味着无数多个对象m ..n 表示对象数处于 m 和 n 之间并且包括 m 和 n。上图每个学生可以选取任意数量的课程数每门课程可以有至少 5 个最多 6 个学生。每门课程只由一位教师教授并且每位教师每学期可以教授 0 3门课程

Java 代码中可以通过使用数据域以及方法来实现关联例如,上图中的关系可以使用下图中的类来实现关系 一个学生选取一门课程使用 Student类中的 addCourse 方法和 Course 类中的 addStudent 方法实现关系 一位教师教授一门课程使用 Faculty 类中的 addCourse 方法和 Course 类中的 setFaculty 方法实现Student 类可以使用一个列表来存储学生选取的课程,Faculty 类可以使用一个列表来存储教师教授的课程,Course 类可以使用一个列表来存储课程中登记的学生以及一个数据域来存储教授该课程的教师。

注意实现类之间的关系可以有很多种可能的方法例如Course 类中的学生和教师信息可以省略,因为它们已经在 Student Faculty 类中了同样的如果不需要知道一个学生选取的课程或者教师教授的课程,Student 或者 Faculty 类中的数据域 courseList 和 addCourse 方法也可以省略。

 

10.3.2 聚集和组合

聚集是关联的一种特殊形式代表了两个对象之间的归属关系聚集建模 has -a 关系。所有者对象称为聚集对象,它的类称为聚集类而从属对象称为被聚集对象它的类称为被聚集类。

个对象可以被多个其他的聚集对象所拥有如果一个对象只归属于一个聚集对象那么它和聚集对象之间的关系就称为组合(composition)例如一个学生有一个名字就是学生类 Student 与名字类 Name 之间的一个组合关系一个学生有一个地址是学生类 Student 与地址类 Address 之间的一个聚集关系因为一个地址可以被几个学生所共享。在 UML 附加在聚集类例如Student ) 上的实心菱形表示它和被聚集类例如Name ) 之间具有组合关系;而附加在聚集类例如Student)上的空心菱形表示它与被聚集类例如:Address)之间具有聚集关系如下图所示:

在上图每个学生只能有一个地址而每个地址最多可以被 3 个学生共享每个学生都有一个名字,而每个学生的名字都是唯一的

聚集关系通常被表示为聚集类中的一个数据域例如:上图中的关系可以使用下图中的类来实现。关系 一个学生拥有一个名字以及 一个学生有一个地址在 Student 类中的数据域 name address 中实现

聚集可以存在于同一类的多个对象之间例如一个人可能有一个管理者,如下图所示:

 

在关系 一个人有一个管理者管理者可以如下表示为 Person 类的一个数据域

public class Person { 
    // The type for the data is the class itself
    private Person supervisor;
    ...
}

如果一个人可以有几个管理者如下图 所示可以用一个数组存储管理者如下图所示。

注意:由于聚集和组合关系都以同样的方式用类来表示,我们不区分它们将两者都称为组合。

 

 

10.4 将基本数据类型值作为对象处理

基本数据类型值不是一个对象,但是可以使用 JavaAPl 中的包装类来包装成一个对象。

出于对性能的考虑Java 中基本数据类型不作为对象使用因为处理对象需要额外的系统开销,所以如果将基本数据类型当作对象就会给语言性能带来负面影响然而,Java 中的许多方法需要将对象作为参数Java 提供了一个方便的办法即将基本数据类型并入对象或包装成对象(例如int 包装成 Integer double 包装成 Double 将 char 包装成 Character 通过使用包装类可以将基本数据类型值作为对象处理Java 为基本数据类型提供了 BooleanCharacterDoubleFloatByteShortInteger 和 Long 等包装类这些包装类都打包在 java.lang 包里Boolean 类包装了布尔值 true 或者 false。本节使用 Integer Double 类为例介绍数值包装类

注意大多数基本类型的包装类的名称与对应的基本数据类型名称一样第一个字母要大写。Integer Character 例外数值包装类相互之间都非常相似。每个都包含了doubleValue( ) 、floatValue( ) 、intValue( )longValue( )、shortValue( ) 和 byteValue( )方法这些方法将对象 转换” 为基本类型值。Integer 类和 Double 类的主要特征如下图所示:

既可以用基本数据类型值也可以用表示数值的字符串来构造包装类例如new Double(5.0)new Double("5 .0")new Integer5)new Integer("5")

包装类没有无参构造方法所有包装类的实例都是不可变的这意味着一旦创建对象后,它们的内部值就不能再改变

每一个数值包装类都有常量 MAX_VALUE MIN_VALUEMAX_VALUE 表示对应的基本数据类型的最大值对于 Byte ShortInteger Long 而言MIN_VALUE 表示对应的基本类型 byteshortint long 的最小值Float Double 类而言MIN_VALUE 表示 float 型和 double 型的最小正值下面的语句显示最大整数( 2 147 483 647 )最小正浮点数1.4E - 45 ),以及双精度浮点数的最大值1.79769313486231570e+308d ): 

System.out.println("The maximum integer is " + Integer.MAX_VALUE);
System.out.println("The minimum positive float is " + Float.MIN_VALUE);
System.out.println("The maximum double-precision floating-point number is " + Double.MAX.VALUE);

每个数值包装类都会包含方法 doubleValue( ) floatValue( )intValue( )longValue( ) shortValue( )这些方法返回包装对象的 doublefloatintlong short 例如:

new Doub1e(12.4).intValue() returns 12;
new Integer(12).doubleValue() returns 12.0;

回顾下 String 类中包含 compareTo 方法用于比较两个字符串数值包装类中包含 compareTo 方法用于比较两个数值并且如果该数值大于等于或者小于另外一个数值时, 分别返回 10-1例如:

new Doub1e(12.4).compareTo(new Doub1e(12.3)) returns 1;
new Double(12.3).compareTo(new Doub1e(12.3)) returns 0;
new Doub1e(12.3).compareTo(new Double(12.51)) returns -1;

数值包装类有一个有用的静态方法 valueOfString s)该方法创建一个新对象并将它初始化为指定字符串表示的值。例如:

Double doubleObject = Double.valueOf("12.4");
Integer integerObject = Integer.valueOf("12");

我们已经使用过 Integer 类中的 parselnt 方法将一个数值字符串转换为一个 int ,而且使用过 Double 类中的 parseDouble 方法将一个数值字符串转变为一个 double 每个数值包装类都有两个重载的方法,将数值字符串转换为正确的以 10(十进制或指定值为基数(例如2 为二进制8为八进制,16 为十六进制的数值

 

 

10.5 基本类型和包装类类型之间的自动转换

根据上下文环境基本数据类型值可以使用包装类自动转换成一个对象反过来的自动转换也可以。

将基本类型值转换为包装类对象的过程称为装箱boxing), 相反的转换过程称为开箱 ( unboxing)Java 允许基本类型和包装类类型之间进行自动转换如果一个基本类型值出现在需要对象的环境中,编译器会将基本类型值进行自动装箱如果一个对象出现在需要基本类型值的环境中,编译器会将对象进行自动开箱这称为自动装箱和自动开箱。例如,可以用自动装箱将图 a 中的语句简化为图 b 中的语句

考虑下面的例子

Integer[] intArray = {1, 2, 3}; 
System,out.println(intArray[0]+ intArray[1]+ intArray[2]);

在第一行中基本类型值 12 被自动装箱成对象 new Integer(1)new Integer(2)new Integer(3)第二行中对象 intArray[0]intArray[1]intArray[2] 被自动转换为 int 然后进行相加

 

 

10.6 Biglnteger BigDecimal

Biglnteger 类和 BigDecimal 类可以用于表示任意大小和精度的整数或者十进制数。

如果要进行非常大的数的计算或者高精度浮点值的计算可以使用 java.math 包中的 Biglnteger 类和 BigDecimal 它们都是不可变的long 类型的最大整数值为 long.MAX_ VALUE (9223372036854775807)Biglnteger 的实例可以表示任意大小的整数可以使用 new Biglnteger(String)new BigDecimal(String)来 创 建 Biglnteger BigDecimal 的实例,使用 addsubtractmultipledivide remainder 方法完成算术运算使用 compareTo 方法比较两个大数字例如下面的代码创建两个 Biglnteger 对象并且将它们进行相乘:

Biglnteger a = new BigInteger("9223372036854775807");
Biglnteger b = new BigInteger("2");
Biglnteger c = a.multiply(b); // 9223372036854775807 * 2
System.out.println(c);

它的输出为 18446744073709551614

BigDecimal 对象的精度没有限制如果结果不能终止那么divide 方法会抛出 ArithmeticException 异常但是可以使用重载的 divide(BigDecimal d.int scale, int roundingMode)方法来指定尺度和舍入方式来避免这个异常这里的 scale 是指小数点后最小的整数位数。例如下面的代码创建两个尺度为 20舍入方式为 BigDecimal .R0UND_UP的 BigDecimal 对象

BigDecimal a = new BigDecimal(1.0);
BigDecimal b = new BigDecimal(3):
BigDecimal c = a.divide(b, 20, BigDecimal .ROUND_UP);
System.out.println(c);

输出为 0.33333333333333333334

注意一个整数的阶乘可能会非常大

 

 

10.7 String

String 对象是不可改变的字符串一旦创建内容不能再改变

10.7.1 构造字符串

可以用字符串直接量或字符数组创建一个字符串对象使用如下语法用字符串直接量创建—个字符串

String newString = new String(stringLiteral);

参数 StringLiteral 是一个括在双引号内的字符序列下面的语句为字符串直接量 "Welcome to Java"创建一个 String 对象 message:

String message = new String("Welcome to Java");

Java 将字符串直接量看作 String 对象所以下面的语句是合法的

String message = "Welcome to Java";

还可以用字符数组创建一个字符串例如下述语句构造一个字符串 "Good Day"

char[] charArray = {'G','o', 'o' , 'd' , ' ' , 'o' , 'a' ,'y'};
String message = new String(charArray);

注意String 变量存储的是对 String 对象的引用String 对象里存储的才是字符串的值。严格地讲术语 String 变量String 对象和字符串值是不同的但在大多教情况下,它们之间的区别是可以忽略的。为简单起见术语字符串将经常被用于指 String 变量、String 对象和字符串的值

 

10.7.2 不可变字符串与限定字符串

String 对象是不可变的它的内容是不能改变的下列代码会改变字符串的内容吗

String s = "Java";
s = "HTML":

答案是不能第一条语句创建了一个内容为"JavaString 对象并将其引用赋值给So 第二条语句创建了一个内容为"HTML"的新 String 对象并将其引用赋值给 s陚值后第一个 String 对象仍然存在但是不能再访问它因为变量 s 现在指向了新的对象如下图所示:

因为字符串在程序设计中是不可变的但同时又会频繁地使用所以 Java 虚拟机为了提高效率并节约内存,对具有相同字符序列的字符串直接量使用同一个实例这样的实例称为限定的(interned)字符串例如,下面的语句:

String s1 = "Welcome to ]ava";
String s2 = new String("Weicome to ]ava");
String s3 = "Welcome to ]ava";
System.out.println("sl==s2 is " + (sl==s2));
System.out.println("sl==s3 is " + (sl==s3));

程序结果显示:

s1 = s2 is false
s1 = s3 is true

在上述语句中,由于 s1 s3 指向相同的限定字符串 "Welcome to Java", 因此s1 -s3 true但是s1 - s2 false, 这是因为尽管 s1s2 的内容相同但它们是不同的字符串对象。

 

10.7.3 字符串的替换和分隔

String 类提供替换和分隔字符串的方法如下图所示:

一旦创建了字符串它的内容就不能改变但是方法 repalcereplaceFirst replaceAll 会返回一个源自原始字符串的新字符串并未改变原始字符串方法 replace 有好几个版本,它们实现用新的字符或子串替换字符串中的某个字符或子串

例如

"Welcome".replace('e', 'A') 返回一个新的字符串,WAlcomA. 
"Welcome".replaceFirst("e","AB") 返回一个新的字符串,WABlcome. 
"Welcome".replace("e","AB")返回一个新的字符串,WABlcomAB.
"Welcome”.replace("el", "AB") 返回一个新的字符串,WABcome.

split 方法可以从一个指定分隔符的字符串中提取标识例如下面的代码

String[] tokens = "Java#HTML#Perl".split("#");
for (int i = 0; i < tokens.length; i++)
System.out.print(tokens[i] + " ");

显示

Java HTML Perl

 

10.7.4 依照模式匹配替换和分隔

正则表达式regular expression)(缩写 regex) 是一个字符串用于描述匹配一个字符串集的模式。可以通过指定某个模式来匹配替换或分隔一个字符串这是一种非常有用且功能强大的特性。

String 类中的 matches 方法开始乍一看matches 方法和 equals 方法非常相似。例如,下面两条语句的值均为 true:

"Java".matches("Java");
"Java".equals("Java");

但是matches 方法的功能更强大它不仅可以匹配定长的字符串还能匹配一套遵从某种模式的字符串。例如下面语句的结果均为 true:

"Java is fun".matches("Java.*") 
"Java is cool".matches("Java.*") 
"Java is powerful".matches("Java.*")

在前面语句中的 "Java.*" 是一个正则表达式它描述的字符串模式是以字符串 Java 开始的,后面紧跟任意 0 个或多个字符这里子串 .* 0个或多个字符相匹配

下面语句结果为 true.

'440-02-4534".matches("\\d{3}-\\d{2}-\\d{4}")

这里 \\d 表示单个数字位,\\d{3}表示三个数字位

方法 replaceAllreplaceFirst split 也可以和正则表达式结合在一起使用例如,下面的语句用字符串 NNN 替换 "a+b$#c" 中的 $+ 或者 #然后返回一个新字符串

String s = "a+b$#c".replaceAll("[$+#]", "NNN"):
System.out.println(s);

这里的正则表达式 [$+#]表示能够匹配 $+ 或者 * 的模式所以输出是 aNNNbNNNNNNc

下面的语句将字符串分隔为由标点符号分隔开的字符串数组。

String[] tokens = "Java.C?C#.C++".split("[.,: ?]");
for (int i = 0; i < tokens.length; i++)
System.out.println(tokens[i]);

这里的正则表达式指定的模式是指匹配 .、 ;或者这里的每个字符都是分隔字符串的分隔符。因此这个字符串就被分割成JavaCC# C++, 它们都存储在数组 tokens

 

10.7.5 字符串与数组之间的转换

字符串不是数组但是字符串可以转换成数组反之亦然为了将字符串转换成一个字符数组,可以使用 toCharArray 方法例如下述语句将字符串"Java"转换成一个数组

char[] chars = "Java".toCharArray();

因此chars[0]是 'J, chars[1]a', chars[2]vchars[3]'a’。

还可以使用方法 getChars(int srcBegin.int srcEnd,char]dst,int dstBegin)将下标从 srcBegin srcEnd -1的子串复制到字符数组 dst 中下标从 dstBegin 开始的位置例如,下面的代码将字符串"CS3720"中下标从 2 6-1的子串"3720"复制到字符数组 dst 中下标从 4 开始的位置

char[] dst = {'J' ,'A' , 'V' , 'A' , '1' , '3' ,'0' , '1' }; 
"CS3720".getChars(2, 6, dst, 4);

这样dst 就变成了{'J' ,'A' , 'V' , 'A' , '3' , '7' ,'2' , '0' }; 

为了将一个字符数组转换成一个字符串应该使用构造方法 String(Char[ ]) 或者方法 value0f(char])例如下面的语句使用 String 构造方法由一个数组构造一个字符串

String str = new String(new char[]{'J' , 'a' , 'v' , 'a'});

下面的语句使用 valueOf方法由一个数组构造一个字符串

String str = String.valueOf(new char[]{'J' , 'a' , 'v' , 'a'});

 

10.7.6 将字符和数值转换成字符串

回顾下可以使用 Double.parseDouble(str)或者 Integer_ parselnt(str)将一个字符串转换为一个 double 值或者一个 int 也可以使用字符串的连接操作符来将字符或者数字转换为字符串。另外一种将数字转换为字符串的方法是使用重载的静态 valueOf 方法该方法可以用于将字符和数值转换成字符串,如下图所示:

例如为了将 double 5 .44 转换成字符串可以使用 String.value0f(5 .44)返回值是由字符'5' 、'.' 、 '4'  和  '4'  构成的字符串

 

10.7.7 格式化字符串

String 类包含静态 format 方法它可以创建一个格式化的字符串调用该方法的语法是:

String.format(format, item1, item2,..., itemk)

这个方法很像 Printf 方法只是 format 方法返回一个格式化的字符串printf 方法显示一个格式化的字符串。例如

String s = String.format("%7.2f%6d%- 4s", 45.556, 14, "AB");
System.out.println(s);

显示

□□45.56□□□□14AB□□

注意

System.out.printf(format, item1, item2,...,itemk);

等价于

System.out.print(String,format(format, item1, item2,...,itemk));

这里小方形框表示一个空格

 

 

10.8 StringBuilder StringBuffer

StringBuilder StringBuffer 类似于 String 区别在于 String 类是不可改变的。

般来说只要使用字符串的地方都可以使用StringBuilder/StringBuffer。 StringBuilder/StringBuffer类比 String类更灵活可以给一个 StringBuilder String - Buffer 中添加插入或追加新的内容但是 String 对象一旦创建它的值就确定了

除了 StringBuffer 中修改缓冲区的方法是同步的,这意味着只有一个任务被允许执行方法之外,StringBuilder 类与 StringBuffer 类是很相似的如果是多任务并发访问,就使用 StringBuffer, 因为这种情况下需要同步以防止 StringBuffer 崩溃而如果是单任务访问使用 StringBuilder 会更有效StringBuffer 和 StringBuilder 中的构造方法和其他方法几乎是完全一样的本节介绍 StringBuilder在本节的所有地方 StringBuilder 都可以替换为 StringBuffer程序可以不经任何修改进行编译和运行。

StringBuilder 类有 3 个构造方法和 30多个用于管理构建器或修改构建器内字符串的方法。可以使用构造方法创建一个空的构建器或从一个字符串创建一个构建器如下图所示:

10.8.1 修改 StringBuilder 中的字符串

可以使用下图中列出的方法在字符串构建器的末尾追加新内容在字符串构建器的特定位置插人新的内容,还可以删除或替换字符串构建器中的字符

StringBuilder 类提供了几个重载方法可以将 booleancharchar 数组doublefloatintlong String 类型值追加到字符串构建器例如下面的代码将字符串和字符追加到 StringBuilder, 构成新的字符串 "Welcome to Java"

StringBuilder StringBuilder = new StringBuilder();
stringBuilder = append("Welcome");
stringBui1der.append(' ');
stringBuilder.append("to");
stringBui1der.append(' ');
stringBui1der.append("]ava");

StringBuilder 类也包括几个重载的方法可以将 booleanchar char 数组double、 float、int,long String 类型值插人到字符串构建器考虑下面的代码

StringBuilder.insert(11, "HTML and ");

假设在应用 insert 方 法 之 前StringBuilder 包含的字符串是 "Welcome to Java"。上面的代码就在 stringBuilder 的第 11个位置就在 J 之前插人 "HTML and"新的 stringBuilder 就变成 "Welcome to HTML and Java"

也可以使用两个 delete 方法将字符从构建器中的字符串中删除使用 reverse 方法倒置字符串,使用 replace 方法替换字符串中的字符或者使用 setCharAt 方法在字符串中设置一个新字符。

例如假设在应用下面的每个方法之前stringBuilder 包含的是 "Welcome to Java"

stringBui1der.delete(8,11)将构建器变为 Welcome ]ava
stringBuilder.deleteCharAt(8)将构建器变为 Welcome o ]ava
stringBuilder.reverse() 将构建器变为 avaJ ot emocleW
stringBuilder.replace(11,15,"HTML")将构建器变为 Welcome to HTML
stringBuilder.setCharAt(0, 'w')将构建器变为 welcome to Java

除了 setCharAt 方法之外所有这些进行修改的方法都做两件事

  • 改变字符串构建器的内容
  • 返回字符串构建器的引用

例如下面的语句

StringBuilder strlngBuilderl = stringBui1der.reverse();

将构建器中的字符倒置并把构建器的引用陚值给 stringBuilderl这样stringBuilder 和 stringBuilderl都指向同一个 StringBuffer 对象回顾一下如果对方法的返回值不感兴趣,所有带返回值类的方法都可以被当作语句调用在这种情况下Java 就简单地忽略掉返回值。例如下面的语句

stringBuilder.reverse();

它的返回值就被忽略了

提示如果一个字符串不需要任何改变则使用 String 类而不使用 StringBuffer 。 Java 可以完成对 String 类的优化例如共享限定字符串等

 

10.8.2 toStringcapacitylengthsetLength charAt 方法

StringBuilder 类提供了许多其他处理字符串构建器和获取它的属性的方法如下图所示:

capacity( )方法返回字符串构建器当前的容量。容量是指在不增加构建器大小的情况下能够存储的字符数量

lengthC)方法返回字符串构建器中实际存储的字符数量setLength(newLength)方法设置字符串构建器的长度。如果参数 newLength 小于字符串构建器的当前长度则字符串构建器会被截短到恰好能包含由参数 newLength 给定的字符个数如果参数 newLength 大于或等于当前长度,则给字符串构建器追加足够多的空字符\u0000'), 使其长度 length 变成新参数 newLength参数 newLength 必须大于等于 0

charAt(index)方法返回字符串构建器中某个特定下标 index 的字符下标是基于 0,字符串构建器中的第一个字符的下标为 0, 第二个字符的下标为1依此类推参数 index 必须大于或等于 0, 并且小于字符串构建器的长度

注意字符串的长度总是小于或等于构建器的容量长度是存储在构建器中的字符串的实际大小,而容量是构建器的当前大小如果有更多的字符添加到字符串构建器超出它的容量,则构建器的容量就会自动增加在计算机内部字符串构建器是一个字符數组因此,构建器的容量就是数组的大小如果超出构建器的容量就用新的数组替換现有數组。新数组的大小为 2x( 之前数组的长度 +1)

提示可以使用 new StringBuilderCinitialCapacity)创建指定初始容量的 StringBuilder。通过仔细选择初始容量能够使程序更有效。如果容量总是超过构建器的实际使用长度,JVM 将永远不需要为构建器重新分配内存另一方面如果容量过大将会浪费内存空间。可以使用 trimToSizeQ 方法将容量降到实际的大小

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值