Java学习笔记(10)Object-Oriented Thinking

来源:互联网 发布:qq飞车淘宝怎么刷魅力 编辑:程序博客网 时间:2024/06/09 07:17

10.1 Class Abstraction and Encapsulation类抽象和封装

类抽象指的是将一个类的具体实现和类的使用做一个分离。

作为类的创建者,他只需要提供这个类的描述,以便让使用者知道如何使用这个类;

作为类的使用者,他不需要知道这个类的内部如何实现,也无从知道这个类如何实现。 

看一个例子来感受类封装

显然,即便你不知道如何Stage类是怎么做出来的,不妨碍你可以用它做一个有界面的程序。

import javafx.application.Application;

import javafx.stage.Stage;

 

public class MyJavaFXextends Application {

  public void start(StageprimaryStage) {

      primaryStage.show();

  }

}


10.2面向对象的思维方式

面向对象非常适合开发大型程序,因为它对代码重用的支持是非常好的。

当然如果是小型程序,或者你根本不考虑代码重用的问题,那么面向过程的思维方式就足够?了。

来看一个计算身体质量指数的例子。

计算身体质量指数Body Mass Index (BMI)是利用身高和体重计算是否健康的一个指数,公式为:BMI=体重(kg)÷(身高(m)^2)

利用上述公式计算某人的BMI指数并给出解释。

 

public class BMI {private String name;private int age;private double weight; // in poundsprivate double height; // in inchespublic static final double KILOGRAMS_PER_POUND = 0.45359237;public static final double METERS_PER_INCH = 0.0254;public BMI(String name, int age, double weight, double height) {this.name = name;this.age = age;this.weight = weight;this.height = height;}public BMI(String name, double weight, double height) {this(name, 20, weight, height);}public double getBMI() {double bmi = weight * KILOGRAMS_PER_POUND / ((height * METERS_PER_INCH) * (height * METERS_PER_INCH));return Math.round(bmi * 100) / 100.0;}public String getStatus() {double bmi = getBMI();if (bmi < 18.5) return "Underweight";else if (bmi < 25) return "Normal";else if (bmi < 30) return "Overweight";else return "Obese";}public String getName() {return name;}public int getAge() {return age;}public double getWeight() {return weight;}public double getHeight() {return height;}}public class UseBMIClass {public static void main(String[] args) {BMI bmi1 = new BMI("Kim Yang", 18, 145, 70);System.out.println("The BMI for " + bmi1.getName() + " is " + bmi1.getBMI() + " " + bmi1.getStatus());BMI bmi2 = new BMI("Susan King", 215, 70);System.out.println("The BMI for " + bmi2.getName() + " is " + bmi2.getBMI() + " " + bmi2.getStatus());}}

 

小结:

面向过程侧重于考虑方法的编写,面向对象则致力于将数据和方法先做一个封装,侧重于考虑对象和对象的操作。

面向过程的编程,数据和对数据的操作是分开的,造成了数据需要在不同方法中反复传递;面向对象很好地反映了真实的世界中,所有的对象都是相关的属性和活动。使用对象,提高了软件的可重用性并使得程序更容易开发和维护。一个Java程序可以看作是一堆合作的对象的集合。


10.3编程练习:课程类

属性设计:                     方法设计:

课程名                          构造方法

选课名单                       返回课程姓名

选课人数                       添加学生

                                    返回选课学生

                                    返回选课人数

public class Course {private String courseName;private String[] students = new String[100];private int numberOfStudents;public Course(String courseName) {this.courseName = courseName;}public void addStudent(String student) {students[numberOfStudents] = student;numberOfStudents++;}public String[] getStudents() {return students;}public int getNumberOfStudents() {return numberOfStudents;}public String getCourseName() {return courseName;}}public class TestCourse {public static void main(String[] args) {Course course1 = new Course("Data Structures");Course course2 = new Course("Database Systems");course1.addStudent("Peter Jones");course1.addStudent("Kim Smith");course1.addStudent("Anne Kennedy");course2.addStudent("Peter Jones");course2.addStudent("Steve Smith");System.out.println("Number of students in course1: "+ course1.getNumberOfStudents());String[] students = course1.getStudents();for (int i = 0; i < course1.getNumberOfStudents(); i++)System.out.print(students[i] + ", ");System.out.print("Number of students in course2: "+ course2.getNumberOfStudents());}}

小结:

为了简单,课程类的学生数上限是100。

创建一个Course对象之后,学生数组同时被创建,Course其实仅仅记录了这个数组的引用,严格来说,数组并不在Course的存储空间内,不过你可以简单这么认为。

对类的使用者而言,他只需要借助addStudent, getNumberOfStudents等方法即可使用这个类,完全不用关心这个类的内部如何实现。例如他根本不必知道学生姓名如何被存储,是数组、链表或是其它数据结构。


10.4设计GuessDate类

       还记得猜生日的程序吧?前后我们写过2个版本,都用到了同样的5张表。假如我们要再写一个更漂亮的界面来猜生日,毫无疑问又要把5张表的数据再贴到现在的代码中。

有没有办法可以做到,5个表的数据单独做好,任何程序都可以借用?这样就不用反复贴一堆数字了。答案是,面向对象,我们把5个表的数字单独做一个类。

       由于5个表的数据是常量,无论在哪个程序中,这些数据都是一样的,所以没有必要把这个类设计成实例相关,因此把所有数据设置成final static是最好的。

       用户无需知道这些数据的存储细节,因此只需要提供一个getValue的方法就行。

 

public class GuessDate {private final static int[][][] dates = {{ { 1, 3, 5, 7 }, { 9, 11, 13, 15 }, { 17, 19, 21, 23 },{ 25, 27, 29, 31 } },{ { 2, 3, 6, 7 }, { 10, 11, 14, 15 }, { 18, 19, 22, 23 },{ 26, 27, 30, 31 } },{ { 4, 5, 6, 7 }, { 12, 13, 14, 15 }, { 20, 21, 22, 23 },{ 28, 29, 30, 31 } },{ { 8, 9, 10, 11 }, { 12, 13, 14, 15 }, { 24, 25, 26, 27 },{ 28, 29, 30, 31 } },{ { 16, 17, 18, 19 }, { 20, 21, 22, 23 }, { 24, 25, 26, 27 },{ 28, 29, 30, 31 } } };/** 不让用户使用类似 GuessDate g = new GuessDate(); 这样的语法 */private GuessDate() {}/** 返回指定位置的数字,参数是:表序号,行,列 */public static int getValue(int setNo, int i, int j) {return dates[setNo][i][j];}}

 

小结

1、这个GuessDate类使用了三维数组存储5张表,如果哪天你心血来潮想用5个二维数组来存储并修改了GuessDate类,只要保持getValue方法不变,重编译GuessDate即可。UseGuessDateClass这个程序完全不用修改,这就是封装性的好处。

2、把GuessDate方法设置为private,是因为它的成员都是static的,把这种类new出来并没有多大意义,干脆禁止用户这么使用。


10.5用对象的方式处理基本类型

OOP号称“Everything is an Object”,所以Java中唯一美中不足的,就是那些基本类型(char, int, float, double...)了。为了弥补这个缺憾,Java为每一种基本类型设计了对应的包装类。功能上它们能够完全取代基本类型,当然,用起来要麻烦一点。


10.5.1数值型包装类

数值型包装类Integer和Double的成员如图,注意有下划线的是静态成员。

 


10.5.2数值型包装类的构造方法

可以直接从基本数值类型(或形如数值的字符串),作为参数去构造出一个对应的包装类。

例如:

Double doubleObject = new Double(5.0);

Double doubleObject = new Double("5.0");

Integer integerObject = new Integer(5);

Integer integerObject = new Integer("5");

JDK1.5以上版本,你还可以这样偷懒:

Double doubleObject = 5.0;

Integer integerObject = 5;


10.5.3数值型包装类的常量

数值型包装类提供了本类型的最大值和最小值的静态常量 MAX_VALUEMIN_VALUE,你可以从两个数得知该类型的取值范围。

例如:

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);


10.5.4数值型包装类 => 基本类型

可以使用包装类的doubleValue, floatValue, intValue, longValue, shortValue函数,从包装类取出对应的基本类型的值。

例如:

long l = doubleObject.longValue(); //有截断

int i = integerObject.intValue();


10.5.5数值包装类和字符串的转换

数值包装类 => 字符串

double d = 5.9;

Double doubleObject = new Double(d);

String s = doubleObject.toString();

字符串 => 数值包装类

Double doubleObject = Double.valueOf("1.4");

Integer integerObject = Integer.valueOf("12");

字符串 => 基本类型

// These two methods are in the Byte class

public static byte parseByte(String s)

public static byte parseByte(String s, int radix)

 

// These two methods are in the Short class

public static short parseShort(String s)

public static short parseShort(String s, int radix)

 

// These two methods are in the Integer class

public static int parseInt(String s)

public static int parseInt(String s, int radix)

例如:

Integer.parseInt("11", 2) returns 3;

Integer.parseInt("1A", 16) returns 26;

// These two methods are in the Long class

public static long parseLong(String s)

public static long parseLong(String s, int radix)

 

// These two methods are in the Float class

public static float parseFloat(String s)

public static float parseFloat(String s, int radix)

 

// These two methods are in the Double class

public static double parseDouble(String s)

public static double parseDouble(String s, int radix)


10.5.6 BigInteger和BigDecimal

这两个类用于处理任意精度的整数和浮点数运算,不会有计算溢出问题。

不过这两个类不能使用普通的运算符(例如:+-*/%),只能用add, subtract, multiply, divideremainder等成员方法,和另一个类对象做运算。

看两个例子。

例题一

BigInteger a = new BigInteger("9223372036854775807");

BigInteger b = new BigInteger("2");

BigInteger c = a.multiply(b); // 9223372036854775807 * 2

System.out.println(c); // 18446744073709551614

 

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

例题二

LISTING 10.9 LargeFactorial.java

 import java.math.*; public class LargeFactorial { public static void main(String[] args) { System.out.println("50! is \n" + factorial(50)); } public static BigInteger factorial(long n) { BigInteger result = BigInteger.ONE; for (int i = 1; i <= n; i++) result = result.multiply(new BigInteger(i + "")); return result; } }


10.6 The String Class

标准的字符串构造方法:

String newString = new String(stringLiteral);

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

由于字符串用的太频繁了,所以Java提供了一个简写形式的构造方式:

String message = "Welcome to Java";

注意:其实,上述两种方法并不完全等价,它们构造出来的字符串,其存储原理还是有细微差别的。不过构造出来之后,用法是一样的。


10.6.1字符串内容是不可变的

字符串一旦创建完毕,其内容是不可变的。换句话说,字符串的内容是常量。不过下面这个例子可能有些误导,"Java"字符串的内容究竟被改变了没有?

String s = "Java";

s = "HTML";

结论是显然的:内容未变。那么被改变的是什么?答案是s的指向,或者说s所引用的字符串变成另外一个串了。


10.6.2驻留字符串(Interned Strings)

由于字符串内容不可更改,因此JVM为了节约内存和提高效率,对于相同内容的字符串,JVM在内存中只留一份,然后大家共享。

这种只留一份大家共享的字符串,称为驻留字符串(Interned Strings)。你可以理解为,在没有使用new,采用类似(String s = "Java"; )这种方式创建字符串的情况下,Java不会让相同内容的字符串在内存中出现2次。例如:


输出结果:

   s1 == s2 is false    

   s1 == s3 is true

注意==运算符比较的不是字符串内容,而是是否引用同一对象。

结论:

1、new运算符能确保String新建一个字符串;

2、如果采用简写方式创建字符串,JVM会采用驻留字符串机制,尽可能共享内容相同的字符串。


10.6.3字符串内容相等比较equals

String s1 = new String("Welcome“);

String s2 = "welcome";

   if (s1.equals(s2)){  

     //比较s1s2的内容是否相等

   }

   if (s1 == s2) {

     //比较s1s2是否相同引用(即指向同一个对象)

   }


10.6.4字符串比较大小compareTo(Object object)

String s1 = new String("Welcome);

String s2 = "welcome";

   if (s1.compareTo(s2) > 0) {  

     // s1大于s2

   }

   else if (s1.compareTo(s2) == 0) {

     // s1等于s2

   }

   else

      // s1小于s2


10.6.5字符串长度

可以通过长度函数得到字符串长度(注意Java的字符是双字节的,所以单个汉字或英文字母长度都算1):

message = "Welcome";

message.length() (返回7)

注意:字符串长度有小括号(),这点和数组不同。数组的长度是属性:

int[] myList=new int[5];  

myList.length才是长度


10.6.6访问字符串的单个字符

不要使用下标方式,如:message[0],必须使用:message.charAt(index)

老习惯,下标从0开始


10.6.7字符串拼接

String s3 = s1.concat(s2);

String s3 = s1 + s2;

s1 + s2 + s3 + s4 + s5 等价于(((s1.concat(s2)).concat(s3)).concat(s4)).concat(s5);


10.6.8子串抽取

使用 substring 方法可以从字符串中抽取子串,该方法的有两个重载版本:

一是substring(beginIndex: int),表示从起始下标抽取到串尾;

二是substring(beginIndex: int, endIndex: int),表示从起始下标抽取到终止下标,但不含终止下标那个字符(即抽取到endIndex-1)。

String s1 = "Welcome to Java";

String s2 = s1.substring(0, 11) + "HTML";



10.7 Matching, Replacing and Splitting by Patterns

Often you will need to write code that validates user input, such as to check whether the input is a number, a string with all lowercase letters, or a Social Security number. How do you write this type of code? A simple and effective way to accomplish this task is to use the regular expression.

A regular expression(abbreviatedregex) is a string that describes a pattern for matching a set of strings. You can match, replace, or split a string by specifying a pattern. This is an extremely useful and powerful feature.

Let us begin with the matchesmethod in theStringclass. At first glance, thematches method is very similar to theequalsmethod. For example, the following two statements both evaluate totrue. 

"Java".matches("Java"); 

"Java".equals("Java");

However, the matchesmethod is more powerful. It can match not only a fixed string, but also a set of strings that follow a pattern. For example, the following statements all evaluate totrue:

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

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

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

Java.* in the preceding statements is a regular expression. It describes a string pattern that begins with Java followed by any zero or more characters. Here, the substring matches any zero or more characters.

The following statement evaluates to true.

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

Here \\drepresents a single digit, and\\d{3} represents three digits.

 

The replaceAll,replaceFirst, andsplitmethods can be used with a regular

expression. For example, the following statement returns a new string that replaces$,+, or# ina+b$#cwith the stringNNN.

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

System.out.println(s);

Here the regular expression [$+#]specifies a pattern that matches$,+, or#. So, the output isaNNNbNNNNNNc.

The following statement splits the string into an array of strings delimited by punctuation marks.

String[] tokens = "Java,C?C#,C++".split("[.,:;?]");

for (inti =0; i < tokens.length; i++)

        System.out.println(tokens[i]);

In this example, the regular expression [.,:;?]specifies a pattern that matches.,,,:,;, or ?. Each of these characters is a delimiter for splitting the string. Thus, the string is split into Java,C,C#, andC++, which are stored in arraytokens.

Regular expression patterns are complex for beginning students to understand. For this reason, simple patterns are introduced in this section. Please refer to Appendix H, Regular Expressions, to learn more about these patterns.


10.8字符串替换函数举例

"Welcome". toLowerCase() 返回新串 welcome.

"Welcome".toUpperCase()返回新串 WELCOME.

"  Welcome  ".trim()返回新串 Welcome.

"Welcome".replace('e', 'A')返回新串 WAlcomA.

"Welcome".replaceFirst("e", "AB")返回新串WABlcome.

"Welcome".replace("e", "AB")返回新串 WABlcomAB.

"Welcome".replace("el", "AB")返回新串WABlcome.

注意:因为字符串内容不可变,上述操作都是通过另外新建一个字符串的方式实现。


10.9字符串拆分split

String[] tokens = "Java#HTML#Perl".split("#");

for (int i = 0; i < tokens.length; i++)

System.out.println("No." + (i + 1) +" " + tokens[i]);


运行结果是:

No.1 Java

No.2 HTML

No.3 Perl


10.10使用正则表达式拆分字符串

上述例子如果单词之间的#数是不定的,普通拆分就搞不定了,例如下面这个例子:

String[] tokens = "Java##HTML###Perl".split("#");

for (int i = 0; i < tokens.length; i++)

System.out.println("No." + (i + 1) +" " + tokens[i]);


运行结果是:

No.1 Java

No.2

No.3 HTML

No.4

No.5

No.6 Perl


采用正则表达式做参数可以解决上面那个问题:

String[] tokens = "Java##HTML###Perl".split("[#]+");

for (int i = 0; i < tokens.length; i++)

System.out.println("No." + (i + 1) +" " + tokens[i]);


运行结果是:

No.1 Java

No.2 HTML

No.3 Perl

P.S. 关于正则表达式,这是个很大的话题了。有兴趣可以自行学习。这里我们只需要记住String支持使用正则表达式进行拆分就可以了。


10.11字符或子串查找

"Welcome to Java".indexOf('W') 返回0.

"Welcome to Java".indexOf('x')返回 -1.

"Welcome to Java".indexOf('o', 5)返回9.

"Welcome to Java".indexOf("come")返回3.

"Welcome to Java".indexOf("Java", 5)返回11.

"Welcome to Java".indexOf("java", 5)返回-1.

"Welcome to Java".lastIndexOf('a')返回14.


10.12字符串转成字符数组

String和字符数组本质上是不同的对象,不过它们之间可以互相转换。例如字符串可以这样转成字符数组:

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

转完之后, chars[0]J, chars[1]a, chars[2]v, chars[3]a


10.13字符数组转成字符串

字符数组转成字符串可以这样做:

char[] arr = {'J', 'A', 'V', 'A'};

String str = String.valueOf(arr);

其实valueOf还能用于将char, double, long, int, float, boolean等类型转成字符串,例如:

String s = String.valueOf(5.44); //s变为"5.44"

当然你也可以这样转: String s = ""+5.44;


10.14 Formatting Strings

The Stringclass contains the staticformatmethod to return a formatted string. The syntax

to invoke this method is:String.format(format, item1, item2, ..., itemk)

This method is similar to the printfmethod except that theformatmethod returns a formatted string, whereas theprintfmethod displays a formatted string. For example,

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

System.out.println(s);

Displays : ██45.56████14AB██

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

is equivalent to

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

where the square box () denotes a blank space.


10.15之前:编程判断字符串是否回文

解题思路:分别从字符串的一头一尾开始,比较所在字符是否相等,然后各自前进一步继续判断,直到相遇或者所在字符不等为止。

 


10.16 StringBuilder 和StringBuffer

这两个类是String的替代类,你可以在任何使用String类的地方改用这两个类。

这两个类的功能显然比String更强大,因为它们可以就地添加、插入和修改字符串的内容。

二者的区别是,StringBuilder是同步的,每次只能被一个线程修改;StringBuffer则允许多个线程同时修改同一个字符串。如果你的程序是单线程的,不需要同时修改字符串,使用StringBuilder的效率会更高。

StringBuilder stringBuilder = new StringBuilder();

stringBuilder.append("Welcome");

stringBuilder.append(' ');

stringBuilder.append("to");

stringBuilder.append(' ');

stringBuilder.append(“Java”);

//现在字符串是Welcome to Java

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

//现在字符串是Welcome to HTML and Java.

假设stringBuilder内容是Welcome to Java,以下操作的效果分别是:

stringBuilder.delete(8, 11); //变为Welcome Java.

stringBuilder.deleteCharAt(8); //变为Welcome o Java.

stringBuilder.reverse(); //变为avaJ ot emocleW.

stringBuilder.replace(11, 15, "HTML"); //变为Welcome to HTML.

stringBuilder.setCharAt(0, 'w'); //变为welcome to Java.

The StringBuilderandStringBufferclasses are similar to theString class except that theStringclass is immutable.

In general, the StringBuilderandStringBufferclasses can be used wherever a string is used.StringBuilderandStringBufferare more flexible thanString. You can add, insert, or append new contents intoStringBuilder andStringBufferobjects, whereas the value of aStringobject is fixed once the string is created.

The StringBuilderclass is similar toStringBufferexcept that the methods for modifying the buffer inStringBufferaresynchronized, which means that only one task is allowed to execute the methods. UseStringBuffer if the class might be accessed by multiple tasks concurrently, because synchronization is needed in this case to prevent corruptions to StringBuffer. Concurrent programming will be introduced in Chapter 30. UsingString- Builderis more efficient if it is accessed by just a single task, because no synchronization is needed in this case. The constructors and methods inStringBufferandStringBuilder are almost the same. This section coversStringBuilder. You can replaceStringBuilderin all occurrences in this section byStringBuffer. The program can compile and run without any other changes.

The StringBuilderclass has three constructors and more than 30 methods for managing the builder and modifying strings in the builder. You can create an empty string builder or a string builder from a string using the constructors, as shown in Figure 10.18.

 


10.17编程练习:检查字符串是否回文,非数字或者非字母的字符忽略不计

/** Return true if a string is a palindrome 回文判断函数*/public static boolean isPalindrome(String s) {// Create a new string by eliminating nonalphanumeric charsString s1 = filter(s);// Create a new string that is the reversal of s1String s2 = reverse(s1);// Check if the reversal is the same as the original stringreturn s2.equals(s1);}/** Create a new string by eliminating nonalphanumeric chars 过滤非数字、非字母的字符*/public static String filter(String s) {// Create a string builderStringBuilder stringBuilder = new StringBuilder();// Examine each char in the string to skip alphanumeric charfor (int i = 0; i < s.length(); i++) {if( Character.isLetterOrDigit(s.charAt(i))) {stringBuilder.append(s.charAt(i));}}// Return a new filtered stringreturn stringBuilder.toString();}/** Create a new string by reversing a specified string字符串反转函数 */public static String reverse(String s) {StringBuilder stringBuilder = new StringBuilder(s);// Invoke reverse in StringBuilderstringBuilder.reverse();return stringBuilder.toString();}


10.18.1 Modifying Strings in the StringBuilder

You can append new contents at the end of a string builder, insert new contents at a specified position in a string builder, and delete or replace characters in a string builder, using the methods listed in Figure 10.19.

The StringBuilderclass provides several overloaded methods to appendboolean, char,char[],double,float,int,long, andString into a string builder. For example, the following code appends strings and characters intostringBuilderto form a new string, Welcome to Java.

StringBuilder stringBuilder = newStringBuilder();

stringBuilder.append("Welcome");

stringBuilder.append(' ');

stringBuilder.append("to");

stringBuilder.append(' ');

stringBuilder.append("Java");

The StringBuilderclass also contains overloaded methods to insertboolean,char,char array,double,float,int,long, andString into a string builder. Consider the following code:

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

Suppose stringBuildercontainsWelcome to Javabefore theinsertmethod is applied. This code inserts"HTML and "at position 11 instringBuilder(just before theJ). The newstringBuilderisWelcome to HTML and Java. You can also delete characters from a string in the builder using the twodeletemethods, reverse the string using thereversemethod, replace characters using thereplacemethod, or set a new character in a string using thesetCharAtmethod.

For example, suppose stringBuildercontainsWelcome to Javabefore each of the following methods is applied:

stringBuilder.delete(8, 11) changes the builder toWelcome Java.

stringBuilder.deleteCharAt(8) changes the builder toWelcome o Java.

stringBuilder.reverse() changes the builder toavaJ ot emocleW.

stringBuilder.replace(11, 15, "HTML") changes the builder to Welcome to HTML.

stringBuilder.setCharAt(0, 'w') sets the builder towelcome to Java.

All these modification methods except setCharAtdo two things:

Change the contents of the string builder

Return the reference of the string builder

For example, the following statement

StringBuilder stringBuilder1 = stringBuilder.reverse();

reverses the string in the builder and assigns the builder’s reference tostringBuilder1. Thus,stringBuilderandstringBuilder1both point to the sameStringBuilder object. Recall that a value-returning method can be invoked as a statement, if you are not interested in the return value of the method. In this case, the return value is simply ignored.

For example, in the following statement

stringBuilder.reverse();

the return value is ignored.

Tip

If a string does not require any change, use String rather thanStringBuilder. Java can perform some optimizations forString, such as sharing interned strings.

 


10.18.2 The toString, capacity, length, setLength,and charAt Methods

The StringBuilderclass provides the additional methods for manipulating a string builder and obtaining its properties, as shown in Figure 10.20.

 


The capacity()method returns the current capacity of the string builder. The capacity is the number of characters the string builder is able to store without having to increase its size.

The length()method returns the number of characters actually stored in the string builder. ThesetLength(newLength)method sets the length of the string builder. If the newLengthargument is less than the current length of the string builder, the string builder is truncated to contain exactly the number of characters given by thenewLength argument. If thenewLengthargument is greater than or equal to the current length, sufficient null characters (\u0000) are appended to the string builder so that lengthbecomes thenewLength argument. ThenewLengthargument must be greater than or equal to0. 

The charAt(index)method returns the character at a specificindexin the string builder. The index is 0based. The first character of a string builder is at index0, the next at index1, and so on. Theindex argument must be greater than or equal to0, and less than the length of the string builder.


Note

The length of the string is always less than or equal to the capacity of the builder. The length is the actual size of the string stored in the builder, and the capacity is the current size of the builder. The builder’s capacity is automatically increased if more characters are added to exceed its capacity. Internally, a string builder is an array of characters, so the builder’s capacity is the size of the array. If the builder’s capacity is exceeded, the array is replaced by a new array. The new array size is 2 * (the previous array size + 1).


Tip

You can use new StringBuilder(initialCapacity)to create aString- Builderwith a specified initial capacity. By carefully choosing the initial capacity, you can make your program more efficient. If the capacity is always larger than the actual length of the builder, the JVM will never need to reallocate memory for the builder. On the other hand, if the capacity is too large, you will waste memory space. You can use thetrimToSize()method to reduce the capacity to the actual size.


CHAPTER10SUMMARY

1. The procedural paradigm focuses on designing methods. The object-oriented paradigm couples data and methods together into objects. Software design using the objectoriented paradigm focuses on objects and operations on objects. The object-oriented approach combines the power of the procedural paradigm with an added dimension that integrates data with operations into objects.

2. Many Java methods require the use of objects as arguments. Java offers a convenient way to incorporate, or wrap, a primitive data type into an object (e.g., wrapping intinto theIntegerclass, and wrappingdoubleinto theDoubleclass).

3. Java can automatically convert a primitive type value to its corresponding wrapper object in the context and vice versa.

4. TheBigIntegerclass is useful for computing and processing integers of any size. The BigDecimalclass can be used to compute and process floating-point numbers with any arbitrary precision.

5. AStringobject is immutable; its contents cannot be changed. To improve efficiency and save memory, the JVM stores two literal strings that have the same character sequence in a unique object. This unique object is called aninterned string object.

6. Aregular expression(abbreviatedregex) is a string that describes a pattern for matching a set of strings. You can match, replace, or split a string by specifying a pattern.

7. TheStringBuilderandStringBufferclasses can be used to replace theString class. TheStringobject is immutable, but you can add, insert, or append new contents intoStringBuilderandStringBufferobjects. UseStringif the string contents do not require any change, and useStringBuilderorStringBufferif they might change.


0 0
原创粉丝点击