Java语法掌握:打好编程基础的关键(一)https://developer.aliyun.com/article/1480871
字符串
从概念上讲,Java 字符串就是 Unicode字符序列。 例如, 串 Java\u2122
由 5 个Unicode 字符 J
、a
、v
、a
和™
。
Java 没有内置的字符串类型, 而是在标准 Java 类库中提供了一个预定义类,很自然地叫做 String。
每个用双引号括起来的字符串都是 String 类的一个实例:
String e = ""; // an empty string String greeting = "Hello";
代码单元和码点
每一个字符通常被称为代码单元(code unit),char 类型描述了 UTF-16 编码中的一个代码单元。
码点(code point)是指与一个编码表中的某个字符对应的代码值。在 Unicode 标准中,码点采用十六进制书写,并加上前缀 U+,例如 U+0041 就是拉丁字母 A 的码点。
字符串的拼接和截取
字符串可以直接使用 + 进行拼接,但是这种方式效率较低,后面会介绍 StringBuilder。
当将一个字符串与一个非字符串的值进行拼接时,后者被转换成字符串。
如果需要把多个字符串放在一起,用一个定界符分隔,可以使用静态join方法:String s = String.join("*", "1", "2", "3");
字符串的截取操作可以调用substring方法。
不可变字符串
底层使用的是 final char[] 用来存储每个字符,并且 String 类没有提供用于修改字符串的方法。
private final char value[];
String 类被 final 修饰,表示这个类不可以被继承,意味着创建一个 String 的时候,创建完成后字符串本身的长度和内容就固定了,不能二次修改。此时在内存中指向了一块内存地址,当二次赋值的时候,并不是在原有基础上修改,而是重新指定一块新的内存地址,原始地址的数据将会被 JVM 的自动垃圾回收机制回收。
比较相等使用 equals 方法
s.equal(t)
如果字符串 s 与字符串 t 相等,则返回 true;否则,返回 false。
检测两个字符串是否相等,而不区分大小写,可以使用 equalsIgnoreCase 方法。
一定不要使用 == 运算符检测两个字符串是否相等!这个运算符只能够确定两个字串是否放置在同一个内存位置上。
常量池
String str1="abc"; String str2="abc"; String str3=new String("abc"); String str4=new String("abc"); String str5=str4.intern(); str1==str2 //第一行,true str1==str3 //第二行,false str1==str5 //第三行,true str3==str4 //第四行,false str3==str5 //第五行,false str1.equals(str2) //第六行,true str1.equals(str3) //第七行,true str1.equals(str5) //第八行,true str3.equals(str4) //第九行,true str3.equals(str5) //第十行,true
第一行:str1 和 str2 在赋值时,使用的是字符串常量。**Java 虚拟机有一个常量池机制,它会直接把字符串常量放入常量池中,从而实现复用。**因此 str1 和 str2 指向的是常量池中的同一个内存地址,所以返回值是 true。
第二行:str3 是用 new 关键字创建的,在 Java 中,new 关键字代表创建一个新对象。因此 str3 指向的是一个全新的内存地址。而 str1 指向的是一个常量池中的旧地址,因此 str1 和 str3 肯定是不同的,所以返回值是 false。
第三行:str5 是用 String 类的 intern() 方法创建的。JDK 文档中对 intern 方法是这样描述的:“返回一个常量池中的固定对象。当 intern 方法被调用时,如果常量池中已经包含了这个 String 对象(用 equals 方法判断包含与否),那么直接返回这个对象。否则,就向常量中添加这个对象,并返回对它的引用”。
第四行:str3 和 str4 使用 new 关键字分别创建了新的对象,所以返回值是 false。
第五行:str3 是指向新创建的内存地址,而 str5 指向常量池中的对象地址,两者是不可能相等的,因此返回值是 false。
对于第六、七、八、九、十行,它们全部使用 eqauls() 方法进行比较。关于 String 类的equals方法,JDK文档是这样说的:“equals 方法返回 true 当且仅当它的入参不为空并且它们代表相同的字符串内容”。
空串和Null串
空串"" 是长度为 0 的字符串。空串是一个 Java 对象,有自己的串长度( 0 ) 和内容(空)。
if (str.length() = 0) 或 if (str.equals (""))
String 变量还可以存放一个特殊的值,名为 null,这表示目前没有任何对象与该变量关联。
if (str = = null )
String 类常用基础API
StringBuilder
使用 + 进行字符串拼接的时候效率很低,每次连接字符串都会创建一个新的 String 对象,即耗时又浪费空间。使用 StringBuilder 类就可以避免这个问题的发生。
首先创建一个空的字符串构造器,然后不断的调用 append 方法,当构建完成的时候调用 toString() 得到 String 对象类型的字符串结果。
StringBuilder builder = new StringBuilder(); builder.append("str"); ... String result = builder.toString();
注意,StringBuilder并不是线程安全的,但是效率高,它的前身是StringBuffer,它才是线程安全的,但是效率较低。这两个类的API都是相同的。
输入和输出
键盘读取输入
Scanner
要想通过控制台进行输人,首先需要构造一个 Scanner 对象,并与“标准输入流” System.in 关联。
Scanner in = new Scanner(System.in);
Console
因为输入是可见的,所以 Scanner 类不适用于从控制台读取密码。 Java SE 6 特别引入了 Console 类实现这个目的。要想读取一个密码, 可以采用下列代码:
Console cons = System.console(); String username = cons.readLine("User name: "); char[] passwd = cons.readPassword("Password: ");
为了安全起见,返回的密码存放在一维字符数组中, 而不是字符串中。
输出
System.out.print( )
普通输出
System.out.println( )
换行输出
System.out.printf( )
格式化输出
System.out.printf("Hello, %s. Next year, you'll be %d" , name, age) ;
每一个以 %字符开始的格式说明符都用相应的参数替换。格式说明符尾部的转换符将指示被格式化的数值类型:f 表示浮点数,s 表示字符串,d 表示十进制整数。
流程控制
块作用域
块(即复合语句)是指由一对大括号括起来的若干条简单的 Java 语句。块确定了变量的作用域。一个块可以嵌套在另一个块中。不能在嵌套的两个块中声明同名的变量。
条件控制
if (age >= 0 && age < 1) { System.out.println("婴儿"); } else if (age >= 1 && age < 5) { System.out.println("幼儿"); } else if (age >= 5 && age < 11) { System.out.println("儿童"); } else if (age >= 11 && age < 18) { System.out.println("少年"); } else if (age >= 18 && age < 35) { System.out.println("青年"); } else if (age >= 35 && age < 60) { System.out.println("中年"); } else { System.out.println("老年"); }
循环控制
在循环中可以使用 break 跳出循环,continue 跳过本次循环。
for 循环
for 循环语句是支持迭代的一种通用结构,利用每次迭代之后更新的计数器或类似的变量来控制迭代次数。
在循环中,检测两个浮点数是否相等需要格外小心。由于舍入的误差, 最终可能得不到精确值,无法达成终止条件。
for (int i = 0; i < 10; i++) { // 注意这里是从 0 开始的,0~9 System.out.println("第" + i + "次循环"); }
for each 循环
JDK 5 引入增强 for 循环,for each 循环语句的循环变量将会遍历数组中的每个元素,而不需要使用下标值。
int[] array = new int[]{1, 2, 3, 4, 5}; for (int num : array) { System.out.println(num); }
while 循环
while 循环语句首先检测循环条件。因此,循环体中的代码有可能不被执行。
int i = 0; while (i < 10) { // 循环内容 System.out.println(i); // 更新循环条件 i++; }
Java语法掌握:打好编程基础的关键(三)https://developer.aliyun.com/article/1480873