JAVA的整形范围和运行的机器无关,这就导致JAVA可移植性较好。
长整型后加上L/l;十六进制有前缀0x或0X;八进制前缀为0;
从JAVA7开始,可在数值前面加上0b/0B表示二进制数;还可以为数字添加下划线,便于阅读,编译器会自动去掉这些下划线。
由上面展示的整型可以看出,JAVA没有无符号类型。
默认情况下浮点数值被认为是double类型,可在后面加上后缀f/F注明他是float,也可以加上D/d注明他是double。
用Double.POSITIVE_INFINITY表示正无穷;
用Double.NEGATIVE_INFINITY表示负无穷;
用Double.NaN表示NaN;
一般不直接使用这些值来比较,因为非数值的值都被认为是不相同的,如果需要判断,可以调用相应的方法:
码点:某个字符对应的代码值
Unicode标准的码点为16进制,并加上前缀U+。
Unicode的码点分为17个代码级别(一个代码级别就是一个码点范围),第一个代码级别(又称为基本的多语言级别)为U+0000到U+FFFF,包括经典的Unicode代码。其余的16个级别从U+10000到U+10FFFF,包括一些辅助字符。
UTF-16编码采用不同长度表示Unicode的所有码点,每16位就是一个代码单元,也就是多语言级别的范围宽度。
可以看到,辅助字符需要用两个代码单元表示。UTF-16通过编码算法,将它的两个代码单元中每一个的值都约束到基本多语言级别的某一个大小位2048字节的子集内,这个子集又称替代区域。第一个代码单元的替代区域范围为U+D800 ~ U+DBFF
,第二个代码单元的替代区域范围为U+DC00 ~ U+DFFF
JAVA里面的char表示的是UTF-16编码的第一个代码单元。
除非需要处理UTF-16的代码单元,否则不要在JAVA里使用char。
JAVA的boolean和整形之间不能相互转换。
JAVA不区分变量的声明与定义。
JAVA用final表示常量。
static final表示类常量。
整数除以0会得到一个异常,浮点数除以0会得到无穷大或者NaN.
浮点运算要保持可移植性是很困难的:
JAVA的double是64位的,假设某处理器使用80位的浮点寄存器。
如果把xy结果存放在80位寄存器内,把xy/z的结果截断至64位,虽然可以得到更精确的结果,但该结果和64位机器上是不同的。也就是说这种方法的阶段导致运算是不可移植的。
为了保证可以执行,JAVA早期规范要求对所有中间结果都阶段到64位,但这样开销太高。
最终,JAVA给出改进方案位:默认情况下,java会对所有中间计算结果进行截断,但是对strictfp标记的方法必须使用严格的浮点计算生成结果。如:
Math.sqrt(),开平方根
JAVA没有幂运算,使用Math.pow(x,a)计算x的a次幂。
在 Math 类中, 为了达到最快的性能,所有的方法都使用计算机浮点单元中的例程.。如果得到一个完全可预测的结果比运行速度更重要的话, 那么就应该使用 StrictMath类。
>>
用符号位填充高位
>>>
用0填充高位
C++的>>有不确定性,不知道是算术移位(填充符号位)还是逻辑移位(填充0)。JAVA消除了该不确定性。
JAVA有枚举类型。
String,注意大小写,JAVA是大小写敏感的。
String类没有提供修改字符串的方法(所以JAVA将String对象称为不可变字符串),你要想改,只能先截取不改的部分,再拼接。
之所以不提供修改是因为JAVA字符串常量是共享的,可以理解为每个字符串对应一个公共存储池的位置,字符串变量只是指向这个位置,如果复制一个字符串,原始字符串变量和复制的字符串变量共享相同的字符。
JAVA设计者认为共享字符串带来的高效率要高于拼接、提取字符串带来的低效率。
实际上只有字符串常量是共享的,而 + 或 substring 等操作产生的结果并不是共享的。因此,千万不
要使甩== 运算符测试字符串的相等性, 以免在程序中出现糟糕的 bug。如下:
s.substring(a,b)方法,第一个参数位起始下标,第二个参数位所要截取的子串的尾后下标。
JAVA可以使用+
拼接。
s.equals(t),s和t可以是字符串变量,也可以是字符串字面量。
可使用equalsIgnoreCase
忽略大小写进行比较。
不可以使用==检测两个字符串是否相等。
空串是"",长度为0的字符串。空串是一个string类对象。
string变量还可以存放一个特殊值null,表明目前没有任何对象和当前变量相关联。
码点和代码单元并不是一对一的关系,每个字符有一个码点,可能有多个代码单元表示。
s.length() 方法返回采用 UTF-16 编码表示的给定字符串所需要的代码单元数量。
s.codePointCount(0, s.lengthQ)得到的是码点数量。
char s.charAt(n) 将返回位置 n 的代码单元。
int index = greeting.offsetByCodePoints(0, i);
int cp = greeting.codePointAt(index); 返回位置为i的码点。
字符串转化为码点数组:int[] codePoints = str.codePoints().toArray();
码点数组转化为字符串:String str = new String(codePoints, 0, codePoints.length);
StringBuilder builder = new StringBuilder();
builder.append(ch); // 添加字符
bui1der.append(str); // 添加字符串
String completedString = builder.toString(); //生成string
不要把boolean转为数值类型。
使用(target_type)a,把a强制转为target_type类型。
先构造Scanna对象:
Scanner in = new Scanner(System.in);
Scanner 类定义在java.util 包内,所以需要导入包:
import java.util.*;
就可以用scanna对象完成输入操作了:
String name = in.nextLine();
相关API:
System.out.print
()
可以使用 s 转换符格式化任意的对象, 对于任意实现了 Formattable 接口的对象都将调用 formatTo 方法;否则将调用 toString 方法, 它可以将对象转换为字符串。
格式化浮点时,用.
设置精度。
日期与时间的格式化选项,以 t 开始, 以下表中的任意字母结束:
可以采用一个格式化的字符串指出要被格式化的参数索引。索引必须紧跟在 % 后面, 并以 $ 终止:
System.out.printfC’ lSs %2StB %2$te, %2StY",“Due date:”, new Date());
可以选择使用 < 标志它指示前而格式说明中的参数将被再次使川也就是说, 下列语句将产生与前面语句同样的输出结果:
System.out .printf(“%s %tB %
要一个用 File 对象构造一个 Scanner 对象,如下所示:
Scanner in = new Scanner(Paths.get(“myflle.txt”),“UTF-8”);//如果不指定编码,则使用运行该程序的机器的默认编码。
可以构造一个带有字符串参数的 Scanner, 但 这 个 Scanner 将字符串解释为数据,而不是文件名。
如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加一个额外的反斜杠:“ c:\mydirectory\myfile.txt ”
接下来就用scanner对象的方法完成读取,和读取标准输入一样。
需要构造一个 PrintWriter 对象。
PrintWriter out = new PrintWriter('myfile.txt",“UTF-8”);
JAVA中指定一个相对文件名时,文件位于 Java 虚拟机启动路径的相对位置。启动路径就是命令解释器的当前路径。如果使用集成开发环境, 那么启动路径将由 IDE 控制。 可以使用下面的调用方式找到路径的位置:
String dir = System.getProperty(“user.dir”);
如果用一个不存在的文件构造一个 Scanner, 或者用一个不能被创建的文件名构造一个 PrintWriter,那么就会发生异常。
在 C++ 中, 可以在嵌套的块中重定义一个变量。在内层定义的变量会覆盖在外层定义的变量。这样,有可能会导致程序设计错误, 因此在 Java 中不允许这样做。
如果在 case 分支语句的末尾没有 break 语句, 那么就会接着执行下一个 case 分支语句。
当在 switch 语句中使用枚举常量时,不必在每个标签中指明枚举名,可以由 switch 的表达式值确定。
Java 还提供了一种带标签的 break语句,用于跳出多重嵌套的循环语句。标签必须放在希望跳出的最外层循环之前, 并且必须紧跟一个冒号.
break 跳转到带标签的循环末尾。只能跳出语句块,而不能跳入语句块。
种带标签的 continue 语句,将跳到与标签匹配的循环首部。
基本的整数和浮点数精度不能够满足需求, 那么可以使用java.math 包中的两个很有用的类:Biglnteger 和 BigDecimal。Biglnteger 类实现了任意精度的整数运算, BigDecimal 实现了任意精度的浮点数运算。
普通数->大数值:Biglnteger a = Biglnteger.valueOf(100);
大数值不能用常规方法处理,需要调用相应的方法:
Biglnteger c = a.add(b); // c = a + b
Biglnteger d = c.multiply(b.add(Biglnteger.valueof(2))); // d = c * (b + 2)
//注意大数值的运算结果还是大数值,所以可以穿起来完成运算。
与 C++ 不同, Java 没有提供运算符重载功能。 程序员无法重定义 + 和 * 运算符, 使其应用于 Biginteger 类的 add 和 multiply 运算
上述两种方法只声明了变量 a, 并没有将 a 初始化为一个真正的数组。应该使用 new 运算符创建数组。
int[] a = new int[100];
可使用a.length 获取数组长度。//无括号
可用增强for循环处理元素:
可创建匿名数组:可以初始化一个匿名的数组:new int[] { 17, 19, 23, 29, 31, 37 }
这种表示法将创建一个新数组并利用括号中提供的值进行初始化,数组的大小就是初始值的个数。 使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组。
允许将一个数组变量拷贝给另一个数组变量。这时, 两个变量将引用同一个数组:
可以看到对一个数组的修改影响到了另一个数组。
也可以使用使用 Arrays 类的 copyOf方法完成拷贝:
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers , luckyNumbers .length);
第二个参数是生成的新数组的长度。
如果数组元素是数值型,那么多余的元素将被赋值为 0 ; 如果数组元素是布尔型,则将赋值为 false。相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素。
Arrays.sort(result);对result数组进行排序。sort使用的是优化的快排算法。
声明一个二维数组相当简单。例如:
double[][] balances;
与一维数组一样, 在调用 new 对多维数组进行初始化之前不能使用它。 在这里可以这样初始化:
balances = new double[N] [M]:
或者:
int[][] magicSquare =
{
{16, 3, 2, 13},
{5, 10, 11, 8},
(9, 6, 7, 12},
{4, 15, 14, 1}
};
Java二维数组事实上是数组的数组,也就是说,可以单独地存取数组的某一行,所以:
可以让两行交换。 double[] temp = balances[i]: balances[i] = balances[i + 1]; balances[i + 1] = temp;
也就是说,二维数组相当于一个存储数组指针(不是数组)的一维数组。