数值:
主要讨论使用这些类的实例化而不是基本数据类型
在格式化或者科学计数中的运用
自动装箱和自动拆箱
基本数据类型对应的包装对象类型,所有的包装类型都是抽象类Number的子类
实际上Number子类有15个分别如下:
值得关注的是分了四种类型:
- 1、AtomicLong和AtomicInteger都是应用于多线程应用。
- 2、BigDecimal和BigInteger都是应用在高精度的运算。
- 3、Striped64,LongAccumulator,DoubleAccumulator,LongAdder,DoubleAdder可以参考之后的伪共享,缓存行内容。
- 4、基本数据类型的包装类。
为什么要使用Number对象而不是一个基本数据类型:
格式化数字打印输出:
之前你看到过print和println的方法打印字符串作为System.out的标准输出。
因为所有的数值都可以被转换成字符串,你可以使用这些方法输出一个任意混合的字符串和数值。不止如此, Java程序语言还有一些其他方法允许你执行更多的输出控制。
比如java.io包中的PrintStream类
你可以使用System.out.format(…);代替public PrintStream format(String format, Object… args)
当多个参数输出的时候可以这样使用:
System.out.format("The value of " + "the float variable is " +
"%f, while the value of the " + "integer variable is %d, " +
"and the string is %s", floatVar, intVar, stringVar);
对于符号的执行,不如%s或者%d等等可以参考java.util。Formatter
比如如下基本的例子:
int i = 461012;
System.out.format("The value of i is: %d%n", i);
输出结果:
The value of i is: 461012
不同地方语言系统的支持
public PrintStream format(Locale l, String format, Object... args)
比如法国系统
ystem.out.format(Locale.FRANCE,
"The value of the float " + "variable is %f, while the " +
"value of the integer variable " + "is %d, and the string is %s%n",
floatVar, intVar, stringVar);
举例格式输出:
import java.util.Calendar;
import java.util.Locale;
public class TestFormat {
public static void main(String[] args) {
long n = 461012;
System.out.format("%d%n", n); // --> "461012"
System.out.format("%08d%n", n); // --> "00461012"
System.out.format("%+8d%n", n); // --> " +461012"
System.out.format("%,8d%n", n); // --> " 461,012"
System.out.format("%+,8d%n%n", n); // --> "+461,012"
double pi = Math.PI;
System.out.format("%f%n", pi); // --> "3.141593"
System.out.format("%.3f%n", pi); // --> "3.142"
System.out.format("%10.3f%n", pi); // --> " 3.142"
System.out.format("%-10.3f%n", pi); // --> "3.142"
System.out.format(Locale.FRANCE,
"%-10.4f%n%n", pi); // --> "3,1416"
Calendar c = Calendar.getInstance();
System.out.format("%tB %te, %tY%n", c, c, c); // --> "May 29, 2006"
System.out.format("%tl:%tM %tp%n", c, c, c); // --> "2:34 am"
System.out.format("%tD%n", c); // --> "05/29/06"
}
}
精度格式的例子:
import java.text.*;
public class DecimalFormatDemo {
static public void customFormat(String pattern, double value ) {
DecimalFormat myFormatter = new DecimalFormat(pattern);
String output = myFormatter.format(value);
System.out.println(value + " " + pattern + " " + output);
}
static public void main(String[] args) {
customFormat("###,###.###", 123456.789);
customFormat("###.##", 123456.789);
customFormat("000000.000", 123.78);
customFormat("$###,###.###", 12345.67);
}
}
The output is:
123456.789 ###,###.### 123,456.789
123456.789 ###.## 123456.79
123.78 000000.000 000123.780
12345.67 $###,###.### $12,345.67
高难度的运算
如果涉及到高难度的运算的时候,不单单是加减乘除。则可以使用Math包。
比如
Math.cos(angle);
如果你感觉每次都需要写Math的话,可以将其以静态包导入:
import static java.lang.Math.*;
这样你的方法功能函数使用就可以简化为:
cos(angle);
常量和基本方法
这个Math类包括了2个常量:
Math.E是自然对数的底
Math.PI(圆周率),是圆周长与直径之比
public class BasicMathDemo {
public static void main(String[] args) {
double a = -191.635;
double b = 43.74;
int c = 16, d = 45;
System.out.printf("The absolute value " + "of %.3f is %.3f%n",
a, Math.abs(a));
System.out.printf("The ceiling of " + "%.2f is %.0f%n",
b, Math.ceil(b));
System.out.printf("The floor of " + "%.2f is %.0f%n",
b, Math.floor(b));
System.out.printf("The rint of %.2f " + "is %.0f%n",
b, Math.rint(b));
System.out.printf("The max of %d and " + "%d is %d%n",
c, d, Math.max(c, d));
System.out.printf("The min of of %d " + "and %d is %d%n",
c, d, Math.min(c, d));
}
}
Here's the output from this program:
The absolute value of -191.635 is 191.635
The ceiling of 43.74 is 44
The floor of 43.74 is 43
The rint of 43.74 is 44
The max of 16 and 45 is 45
The min of 16 and 45 is 16
public class ExponentialDemo {
public static void main(String[] args) {
double x = 9;
double y = 2;
System.out.printf("The value of " + "e is %.4f%n",
Math.E);
System.out.printf("exp(%.3f) " + "is %.3f%n",
x, Math.exp(x));
System.out.printf("log(%.3f) is " + "%.3f%n",
x, Math.log(x));
System.out.printf("pow(%.3f, %.3f) " + "is %.3f%n",
x, y, Math.pow(x, y));
System.out.printf("sqrt(%.3f) is " + "%.3f%n",
x, Math.sqrt(x));
}
}
输出内容:
The value of e is 2.7183
exp(9.000) is 8103.084
log(9.000) is 2.197
pow(9.000, 2.000) is 81.000
sqrt(9.000) is 3.000
public class TrigonometricDemo {
public static void main(String[] args) {
double degrees = 45.0;
double radians = Math.toRadians(degrees);
System.out.format("The value of pi " + "is %.4f%n",
Math.PI);
System.out.format("The sine of %.1f " + "degrees is %.4f%n",
degrees, Math.sin(radians));
System.out.format("The cosine of %.1f " + "degrees is %.4f%n",
degrees, Math.cos(radians));
System.out.format("The tangent of %.1f " + "degrees is %.4f%n",
degrees, Math.tan(radians));
System.out.format("The arcsine of %.4f " + "is %.4f degrees %n",
Math.sin(radians),
Math.toDegrees(Math.asin(Math.sin(radians))));
System.out.format("The arccosine of %.4f " + "is %.4f degrees %n",
Math.cos(radians),
Math.toDegrees(Math.acos(Math.cos(radians))));
System.out.format("The arctangent of %.4f " + "is %.4f degrees %n",
Math.tan(radians),
Math.toDegrees(Math.atan(Math.tan(radians))));
}
}
The output of this program is as follows:
The value of pi is 3.1416
The sine of 45.0 degrees is 0.7071
The cosine of 45.0 degrees is 0.7071
The tangent of 45.0 degrees is 1.0000
The arcsine of 0.7071 is 45.0000 degrees
The arccosine of 0.7071 is 45.0000 degrees
The arctangent of 1.0000 is 45.0000 degrees
随机数:
方法返回一个介于0.0和1.0之间的伪随机选择的数字。范围包括0.0,但不包括1.0。换句话说:0.0 <= Math.random() < 1.0。要获得不同范围内的数字,可以对random方法返回的值执行算术。例如,要生成0到9之间的整数,可以这样写:
int number = (int)(Math.random() * 10);
通过将该值乘以10,可能值的范围变为0.0 <= number < 10.0。
使用数学。当您需要生成一个随机数时,random可以很好地工作。如果需要生成一系列随机数,应该创建java.util.Random的实例。随机调用该对象上的方法来生成数字。如果并发场景下需要生成随机数的实例则需要使用ThreadLocalRandom,可参考这篇文章
数值的小结归纳:
- 装箱和拆箱:
您可以使用其中一个包装器类Byte、Double、Float、Integer、Long或Short来包装对象中的一些基本类型。Java编译器会在必要时自动为您包装(box)原语,并在必要时再次解压它们。- 常量类和String的转换方法的使用:
这些类包括常量和有用的类方法。MIN_VALUE和MAX_VALUE常量包含该类型对象可以包含的最小值和最大值。byteValue、shortValue和类似的方法将一种数字类型转换为另一种类型。方法valueOf将字符串转换为数字,toString方法将数字转换为字符串。- 数值的格式化:
要格式化包含输出数字的字符串,可以使用PrintStream类中的printf()或format()方法。或者,您可以使用NumberFormat类使用模式自定义数字格式。- 数学函数的使用:
Math包含各种执行数学函数的类方法,包括指数法、对数法和三角法。数学还包括基本的算术函数,如绝对值和舍入,以及用于生成随机数的方法random()。
问题1:您可以使用哪种整数方法将int转换为字符串,
以十六进制表示数字?
例如,什么方法将整数65转换为字符串“41”?
Integer.toHexString(65);
问题2;您将使用哪种整数方法将以5为基底的字符串转换为等效的int?例如,
如何将字符串“230”转换为整数值65?显示您将用于完成此任务的代码。
String base5String = "230";
int result = Integer.valueOf(base5String, 5);
问题3:您可以使用什么双重方法来检测浮点数是否具有特殊值而不是数字(NaN)?
isNaN
问题4: 下面这个表达式的值是多少,为什么?
Integer.valueOf(1).equals(Long.valueOf(1))
false,类型不一致
代码练习:
更改MaxVariablesDemo以显示最小值,而不是最大值。
您可以删除与aChar和aBoolean变量相关的所有代码。输出是什么?
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public class MaxVariablesDemo {
public static void main(String args[]) {
//integers
byte largestByte = Byte.MAX_VALUE;
short largestShort = Short.MAX_VALUE;
int largestInteger = Integer.MAX_VALUE;
long largestLong = Long.MAX_VALUE;
//real numbers
float largestFloat = Float.MAX_VALUE;
double largestDouble = Double.MAX_VALUE;
//other primitive types
char aChar = 'S';
boolean aBoolean = true;
//Display them all.
System.out.println("The largest byte value is "
+ largestByte + ".");
System.out.println("The largest short value is "
+ largestShort + ".");
System.out.println("The largest integer value is "
+ largestInteger + ".");
System.out.println("The largest long value is "
+ largestLong + ".");
System.out.println("The largest float value is "
+ largestFloat + ".");
System.out.println("The largest double value is "
+ largestDouble + ".");
if (Character.isUpperCase(aChar)) {
System.out.println("The character " + aChar
+ " is uppercase.");
} else {
System.out.println("The character " + aChar
+ " is lowercase.");
}
System.out.println("The value of aBoolean is "
+ aBoolean + ".");
}
}
将上面的MAX_VALUE改为MIN_VALUE即可。
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public class MinVariablesDemo {
public static void main(String args[]) {
// integers
byte smallestByte = Byte.MIN_VALUE;
short smallestShort = Short.MIN_VALUE;
int smallestInteger = Integer.MIN_VALUE;
long smallestLong = Long.MIN_VALUE;
// real numbers
float smallestFloat = Float.MIN_VALUE;
double smallestDouble = Double.MIN_VALUE;
// display them all
System.out.println("The smallest byte value is " + smallestByte);
System.out.println("The smallest short value is " + smallestShort);
System.out.println("The smallest integer value is " + smallestInteger);
System.out.println("The smallest long value is " + smallestLong);
System.out.println("The smallest float value is " + smallestFloat);
System.out.println("The smallest double value is " + smallestDouble);
}
}
代码练习:创建一个程序,该程序从命令行读取未指定数目的整数参数并将它们相加。
例如,假设您输入以下内容:
java Adder 1 3 2 10
程序应该显示16,然后退出。如果用户只输入一个参数,程序应该显示一个错误消息。
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public class ValueOfDemo {
public static void main(String[] args) {
// this program requires two
// arguments on the command line
if (args.length == 2) {
// convert strings to numbers
float a = (Float.valueOf(args[0])).floatValue();
float b = (Float.valueOf(args[1])).floatValue();
// do some arithmetic
System.out.println("a + b = " +
(a + b));
System.out.println("a - b = " +
(a - b));
System.out.println("a * b = " +
(a * b));
System.out.println("a / b = " +
(a / b));
System.out.println("a % b = " +
(a % b));
} else {
System.out.println("This program " +
"requires two command-line arguments.");
}
}
}
正确答案:
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public class Adder {
public static void main(String[] args) {
int numArgs = args.length;
//this program requires at least two arguments on the command line
if (numArgs < 2) {
System.out.println("This program requires two command-line arguments.");
} else {
int sum = 0;
for (int i = 0; i < numArgs; i++) {
sum += Integer.valueOf(args[i]).intValue();
}
//print the sum
System.out.println(sum);
}
}
}
创建一个程序,类似于前一个,但有以下差异:
它不是读取整数参数,而是读取浮点参数。
它显示参数的和,使用小数点右边的两位数字。
例如,假设您输入以下内容
java FPAdder 1 1e2 3.0 4.754
程序将显示108.75。根据地区的不同,小数点可能是逗号(,)而不是句号(.)。
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//1.1 and later
import java.text.DecimalFormat;
public class FPAdder {
public static void main(String[] args) {
int numArgs = args.length;
//this program requires at least two arguments on the command line
if (numArgs < 2) {
System.out.println("This program requires two command-line arguments.");
} else {
double sum = 0.0;
for (int i = 0; i < numArgs; i++) {
sum += Double.valueOf(args[i]).doubleValue();
}
//format the sum
DecimalFormat myFormatter = new DecimalFormat("###,###.##");
String output = myFormatter.format(sum);
//print the sum
System.out.println(output);
}
}
}
字符
日常使用字符的例子:
char ch = 'a';
// Unicode for uppercase Greek omega character
char uniChar = '\u03A9';
// an array of chars
char[] charArray = { 'a', 'b', 'c', 'd', 'e' };
但是,有时您需要使用char作为对象—例如,作为期望对象的方法参数。Java编程语言提供了一个包装器类,它将字符“包装”到字符对象中。类型为Character的对象包含一个字段,其类型为char。这个字符类还提供了一些有用的类(例如。(静态)操作字符的方法。
Character ch = new Character(‘a’);
在某些情况下,Java编译器还会为您创建一个字符对象。例如,如果将原始字符传递给期望对象的方法,编译器会自动将该字符转换为字符。这个特性称为自动装箱或拆箱
字符类是不可变的,因此一旦创建了它,就不能更改字符对象。
下表列出了字符类中一些最有用的方法,但不是全部。要获得该类中所有方法的完整清单(有50多个方法),请参考java.lang。字符API规范。
转义字符
举个例子你想输出如下语句
She said "Hello!" to me.
那么代码编写的时候应该如下编码
System.out.println("She said \"Hello!\" to me.");
字符串
在Java编程中广泛使用的字符串是字符序列。在Java编程语言中,字符串是对象
比如你编码的时候经常如下编码:
String greeting = "Hello world!";
那么在本例中,“Hello world!”是一个字符串文本—代码中的一系列字符,用双引号括起来。每当在代码中遇到字符串文字时,编译器就创建一个字符串对象及其值——在本例中是Hello world!
String类有13个构造函数,允许您使用不同的源提供字符串的初始值,
String类是不可变的,因此一旦创建了String对象,就不能更改它。String类有许多方法,其中一些方法将在下面讨论,它们似乎可以修改字符串。因为字符串是不可变的,所以这些方法真正做的是创建并返回一个包含操作结果的新字符串。
比如可以演示下字符和字符串的关系
char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
String helloString = new String(helloArray);
System.out.println(helloString);
这段代码的最后一行显示hello。
字符串的length()方法:
String palindrome = "Dot saw I was Tod";
int len = palindrome.length();
len =17;
palindrome (回文)是一个对称的单词或句子,它的前后拼写相同,忽略了大小写和标点符号。下面是一个简短而低效的程序来反转回文字符串。它调用字符串方法charAt(i),该方法返回字符串中的第i个字符,从0开始计数。
public class StringDemo {
public static void main(String[] args) {
String palindrome = "Dot saw I was Tod";
int len = palindrome.length();
char[] tempCharArray = new char[len];
char[] charArray = new char[len];
// put original string in an
// array of chars
for (int i = 0; i < len; i++) {
tempCharArray[i] =
palindrome.charAt(i);
}
// reverse array of chars
for (int j = 0; j < len; j++) {
charArray[j] =
tempCharArray[len - 1 - j];
}
String reversePalindrome =
new String(charArray);
System.out.println(reversePalindrome);
}
}
输出结果
doT saw I was toD
要完成字符串反转,程序必须将字符串转换为一个字符数组(第一个for循环),
将数组转换为第二个数组(第二个for循环),然后再转换回字符串。
String类包含一个方法getChars(),用于将字符串或字符串的一部分转换为字符数组,
这样我们就可以用上面程序中的第一个for循环替换
palindrome.getChars(0, len, tempCharArray, 0);
字符串连接
String类包含用于连接两个字符串的方法:
string1.concat (string2相等);
这将返回一个新的字符串,它是string1,末尾添加了string2。
字符串通常与+运算符连接,如in
“Hello”+“world”+“!
需要注意的是:当使用字符串的时候,如果超过行大小,则需要+连接比如如下:
String quote =
"Now is the time for all good " +
"men to come to the aid of their country.";
创建格式字符串
原来输出格式:
System.out.printf("The value of the float " +
"variable is %f, while " +
"the value of the " +
"integer variable is %d, " +
"and the string is %s",
floatVar, intVar, stringVar);
优化后的输出格式:
String fs;
fs = String.format("The value of the float " +
"variable is %f, while " +
"the value of the " +
"integer variable is %d, " +
" and the string is %s",
floatVar, intVar, stringVar);
System.out.println(fs);
数值和字符串之间的转换
比如如下例子:
public class ValueOfDemo {
public static void main(String[] args) {
// this program requires two
// arguments on the command line
if (args.length == 2) {
// convert strings to numbers
float a = (Float.valueOf(args[0])).floatValue();
float b = (Float.valueOf(args[1])).floatValue();
// do some arithmetic
System.out.println("a + b = " +
(a + b));
System.out.println("a - b = " +
(a - b));
System.out.println("a * b = " +
(a * b));
System.out.println("a / b = " +
(a / b));
System.out.println("a % b = " +
(a % b));
} else {
System.out.println("This program " +
"requires two command-line arguments.");
}
}
}
下面是命令行参数使用4.5和87.2时程序的输出:
a + b = 91.7
a - b = -82.7
a * b = 392.4
a / b = 0.0516055
a % b = 4.5
封装基本数值类型的每个Number子类还提供一个parseXXXX()方法(例如parseFloat()),
该方法可用于将字符串转换为基本数值。由于返回的是原始类型而不是对象,
所以parseFloat()方法比valueOf()方法更直接
float a = Float.parseFloat(args[0]);
float b = Float.parseFloat(args[1]);
将数字转换为字符串
常用的方法:
int i;
// Concatenate "i" with an empty string; conversion is handled for you.
String s1 = "" + i;
或者
// The valueOf class method.
String s2 = String.valueOf(i);
每个Number子类都包含一个类方法toString(),该方法将其基本类型转换为字符串。
int i;
double d;
String s3 = Integer.toString(i);
String s4 = Double.toString(d);
如下是个在数值转字符串的例子:
public class ToStringDemo {
public static void main(String[] args) {
double d = 858.48;
String s = Double.toString(d);
int dot = s.indexOf('.');
System.out.println(dot + " digits " +
"before decimal point.");
System.out.println( (s.length() - dot - 1) +
" digits after decimal point.");
}
}
The output of this program is:
3 digits before decimal point.
2 digits after decimal point.
从字符串获取字符
按索引获取字符和子字符串
通过调用charAt()访问器方法,可以在字符串中的特定索引处获取字符。第一个字符的索引是0,而最后一个字符的索引是length()-1。例如,下面的代码获取字符串中索引9处的字符:
String anotherPalindrome = "Niagara. O roar again!";
char aChar = anotherPalindrome.charAt(9);
索引从0开始,因此索引9处的字符是“O”,如下图所示
String anotherPalindrome = "Niagara. O roar again!";
String roar = anotherPalindrome.substring(11, 15);
在字符串中搜索字符和子字符串
CharSequence是一个由String类实现的接口。因此,可以使用字符串作为contains()方法的参数。
将字符和子字符串替换为字符串
举个例子:
public class Filename {
private String fullPath;
private char pathSeparator,
extensionSeparator;
public Filename(String str, char sep, char ext) {
fullPath = str;
pathSeparator = sep;
extensionSeparator = ext;
}
public String extension() {
int dot = fullPath.lastIndexOf(extensionSeparator);
return fullPath.substring(dot + 1);
}
// gets filename without extension
public String filename() {
int dot = fullPath.lastIndexOf(extensionSeparator);
int sep = fullPath.lastIndexOf(pathSeparator);
return fullPath.substring(sep + 1, dot);
}
public String path() {
int sep = fullPath.lastIndexOf(pathSeparator);
return fullPath.substring(0, sep);
}
}
public class FilenameDemo {
public static void main(String[] args) {
final String FPATH = "/home/user/index.html";
Filename myHomePage = new Filename(FPATH, '/', '.');
System.out.println("Extension = " + myHomePage.extension());
System.out.println("Filename = " + myHomePage.filename());
System.out.println("Path = " + myHomePage.path());
}
}
And here's the output from the program:
Extension = html
Filename = index
Path = /home/user
举个例子
public class RegionMatchesDemo {
public static void main(String[] args) {
String searchMe = "Green Eggs and Ham";
String findMe = "Eggs";
int searchMeLength = searchMe.length();
int findMeLength = findMe.length();
boolean foundIt = false;
for (int i = 0;
i <= (searchMeLength - findMeLength);
i++) {
if (searchMe.regionMatches(i, findMe, 0, findMeLength)) {
foundIt = true;
System.out.println(searchMe.substring(i, i + findMeLength));
break;
}
}
if (!foundIt)
System.out.println("No match found.");
}
}
输出结果Eggs
StringBuilder类
StringBuilder对象类似于String对象,只是可以修改它们。在内部,这些对象被视为包含字符序列的变长数组。在任何时候,序列的长度和内容都可以通过方法调用进行更改
值得注意的是:在使用编码的时候应该推荐使用的是String,除非是大量字符串拼接的时候使用对象StringBuilder会更加高效。
与String类一样,StringBuilder类也有一个length()方法,该方法返回生成器中字符序列的长度。与字符串不同,每个字符串构建器都有一个容量,即分配的字符空间的数量。容量(由capacity()方法返回)总是大于或等于长度(通常大于),并且会根据需要自动扩展,以适应字符串生成器的添加。
举个例子:
// creates empty builder, capacity 16
StringBuilder sb = new StringBuilder();
// adds 9 character string at beginning
sb.append("Greetings");
是否会生成长度为9、容量为16的字符串生成器
许多操作(例如,append()、insert()或setLength()可以增加字符串构造器中字符序列的长度,这样得到的长度()将大于当前容量()。当这种情况发生时,容量会自动增加
您可以在StringBuilder对象上使用任何String方法,方法是首先使用StringBuilder类的toString()方法将String builder转换为String。然后使用StringBuilder(string str)构造函数将字符串转换回字符串生成器。
在标题为“String”的部分中列出的StringDemo程序就是一个例子,如果使用StringBuilder而不是字符串,程序的效率会更高。
public class StringDemo {
public static void main(String[] args) {
String palindrome = "Dot saw I was Tod";
int len = palindrome.length();
char[] tempCharArray = new char[len];
char[] charArray = new char[len];
// put original string in an
// array of chars
for (int i = 0; i < len; i++) {
tempCharArray[i] =
palindrome.charAt(i);
}
// reverse array of chars
for (int j = 0; j < len; j++) {
charArray[j] =
tempCharArray[len - 1 - j];
}
String reversePalindrome =
new String(charArray);
System.out.println(reversePalindrome);
}
}
输出结果:
doT saw I was toD
可优化为:
public class StringBuilderDemo {
public static void main(String[] args) {
String palindrome = "Dot saw I was Tod";
StringBuilder sb = new StringBuilder(palindrome);
sb.reverse(); // reverse it
System.out.println(sb);
}
}
输出结果:
doT saw I was toD
还有一个与StringBuilder类完全相同的StringBuffer类,只是它的方法是同步的,因此是线程安全的。
字符和字符串的小结
大多数情况下,如果您使用单个字符值,您将使用基本字符类型。但是,有时您需要使用char作为对象,例如,在需要对象的地方作为方法参数。Java编程语言提供了一个包装器类,它将字符“包装”到字符对象中。类型为Character的对象包含一个类型为char的字段。这个字符类还提供了一些有用的类(例如。(静态)操作字符的方法。
字符串是字符序列,在Java编程中广泛使用。在Java编程语言中,字符串是对象。String类有60多个方法和13个构造函数。最常见的情况是,创建一个字符串时使用string s = "Hello world!"这样的语句;而不是使用一个字符串构造函数。String类有许多方法来查找和检索子字符串;然后可以使用+ 操作符轻松地将它们重新组装成新的字符串。
String类还包括许多实用程序方法,其中包括split()、toLowerCase()、toUpperCase()和valueOf()。在将用户输入字符串转换为数字时,后一种方法是必不可少的。
Number子类还具有将字符串转换为数字的方法,反之亦然。
除了String类之外,还有一个StringBuilder类。使用StringBuilder对象有时比使用字符串更有效。StringBuilder类提供了一些对字符串有用的方法,其中reverse()就是其中之一。然而,一般来说,String类有更广泛的方法。可以使用StringBuilder构造函数将字符串转换为字符串生成器。可以使用toString()方法将字符串生成器转换为字符串。
自动拆箱和装箱
自动装箱是Java编译器在基本类型及其对应的对象包装器类之间进行的自动转换。例如,将int转换为整数,将double转换为double,等等。如果转换以另一种方式进行,则称为自动拆箱
小结测试:
问题1:以下字符串生成器的初始容量是多少?
StringBuilder sb = new StringBuilder("Able was I ere I saw Elba.");
答案:初始字符串的长度+16,26 + 16 = 42
问题2:String hannah = "Did Hannah see bees? Hannah did.";
hannah.length()值输出多少?
答案: 32
hannah.charAt(12)值是多少?
答案: e
编写一个表达式,该表达式引用hannah引用的字符串中的字母b?
答案:hannah.charAt(15).
问题3:"Was it a car or a cat I saw?".substring(9, 12) 返回值是多长
长度为3个字符:car。不包括车后的空间。
问题4:在下面的程序中,称为ComputeResult,在执行每个编号行之后,result的值是多少
public class ComputeResult {
public static void main(String[] args) {
String original = "software";
StringBuilder result = new StringBuilder("hi");
int index = original.indexOf('a');
/*1*/ result.setCharAt(0, original.charAt(0));
/*2*/ result.setCharAt(1, original.charAt(original.length()-1));
/*3*/ result.insert(1, original.charAt(4));
/*4*/ result.append(original.substring(1,4));
/*5*/ result.insert(3, (original.substring(index, index+2) + " "));
System.out.println(result);
}
}
输出结果:
si
se
swe
sweoft
swear oft
代码练习:
展示两种将以下两个字符串连接在一起的方法,以获得字符串“Hi, mom”
String hi = "Hi, ";
String mom = "mom.";
答案:+或者concat
编写一个程序,从你的全名计算出你名字的首字母并显示出来
public class ComputeInitials {
public static void main(String[] args) {
String myName = "Fred F. Flintstone";
StringBuffer myInitials = new StringBuffer();
int length = myName.length();
for (int i = 0; i < length; i++) {
if (Character.isUpperCase(myName.charAt(i))) {
myInitials.append(myName.charAt(i));
}
}
System.out.println("My initials are: " + myInitials);
}
}
字谜是将另一个单词或短语的字母调换而成的单词或短语;
例如,“议会”是“部分男性”的字谜,而“软件”是“swear oft”的字谜。编写一个程序,
找出一个字符串是否是另一个字符串的变位符。程序应该忽略空白和标点符号
public class Anagram {
public static boolean areAnagrams(String string1,
String string2) {
String workingCopy1 = removeJunk(string1);
String workingCopy2 = removeJunk(string2);
workingCopy1 = workingCopy1.toLowerCase();
workingCopy2 = workingCopy2.toLowerCase();
workingCopy1 = sort(workingCopy1);
workingCopy2 = sort(workingCopy2);
return workingCopy1.equals(workingCopy2);
}
protected static String removeJunk(String string) {
int i, len = string.length();
StringBuilder dest = new StringBuilder(len);
char c;
for (i = (len - 1); i >= 0; i--) {
c = string.charAt(i);
if (Character.isLetter(c)) {
dest.append(c);
}
}
return dest.toString();
}
protected static String sort(String string) {
char[] charArray = string.toCharArray();
java.util.Arrays.sort(charArray);
return new String(charArray);
}
public static void main(String[] args) {
String string1 = "Cosmo and Laine:";
String string2 = "Maid, clean soon!";
System.out.println();
System.out.println("Testing whether the following "
+ "strings are anagrams:");
System.out.println(" String 1: " + string1);
System.out.println(" String 2: " + string2);
System.out.println();
if (areAnagrams(string1, string2)) {
System.out.println("They ARE anagrams!");
} else {
System.out.println("They are NOT anagrams!");
}
System.out.println();
}
}