Java语法掌握:打好编程基础的关键(二)

简介: Java语法掌握:打好编程基础的关键

Java语法掌握:打好编程基础的关键(一)https://developer.aliyun.com/article/1480871


字符串

从概念上讲,Java 字符串就是 Unicode字符序列。 例如, 串 Java\u2122 由 5 个Unicode 字符 Java

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

相关文章
|
1天前
|
并行计算 Java 大数据
Java中的高效并行计算与多线程编程技术
Java中的高效并行计算与多线程编程技术
|
1天前
|
Java API 数据库
深研Java异步编程:CompletableFuture与反应式编程范式的融合实践
【7月更文挑战第1天】Java 8的CompletableFuture革新了异步编程,提供链式处理和优雅的错误处理。反应式编程,如Project Reactor,强调数据流和变化传播,擅长处理大规模并发和延迟敏感任务。两者结合,如通过Mono转换CompletableFuture,兼顾灵活性与资源管理,提升现代Java应用的并发性能和响应性。开发者可按需选择和融合这两种技术,以适应高并发环境。
13 1
|
1天前
|
安全 Java
打破常规!JAVA反射技术让你“动态”编程
【7月更文挑战第1天】Java反射技术是动态编程的利器,它揭示了类的内部信息,允许运行时操作对象、调用方法和创建实例。动态加载类、调用方法和创建对象是其常见应用场景,但需注意反射带来的性能损失、安全风险和代码可读性下降。在平衡灵活性与效率时谨慎使用。
6 0
|
1天前
|
Java UED
Java中的事件驱动编程模型
Java中的事件驱动编程模型
|
1天前
|
Java
解决Java中Socket编程中的常见问题
解决Java中Socket编程中的常见问题
|
1天前
|
安全 Java 容器
Java并发编程:避免常见的陷阱
Java并发编程:避免常见的陷阱
|
1天前
|
监控 Java API
Java Socket编程入门
Java Socket编程入门
|
1天前
|
算法 安全 Java
Java小白教学—五千字带你了解多线程机制及线程安全问题
Java小白教学—五千字带你了解多线程机制及线程安全问题
|
1天前
|
安全 Java
解决Java中多线程同步问题的方案
解决Java中多线程同步问题的方案
|
1天前
|
安全 Java 开发者
Java多线程编程实践中的常见问题与解决方案
Java多线程编程实践中的常见问题与解决方案