Java基础语法

Java关键字

abstract assert boolean break byte
case catch char class const
continue default do double else
enum extends final finally float
for goto if implements import
instanceof int interface long native
new null package private protected
public return short static strictfp
super switch synchronized this throw
throws transient try void volatile
while

Java标识符

所有Java组件都需要名称。 用于类,变量和方法的名称称为标识符
在Java中,标识符的命名有几点要记住。 它们如下 -

  • 所有标识符都应以字母(AZaz),货币字符($)或下划线(_)开头。
  • 在第一个字符之后,标识符可以是任何字符组合。
  • 关键字不能用作标识符。
  • 标识符区分大小写。
  • 合法标识符的示例:age$salary_value__1_value
  • 非法标识符的示例:123abc-salary

注 - Java使用的是uicode编码,是可以用中文命名的,不过笔者建议别用中文。

Java程序规范

关于Java程序,请务必牢记以下几点。

  • 区分大小写 - Java区分大小写,因此标识符Hellohello在Java中具有不同的含义。
  • 类名 - 对于所有类名,第一个字母应为大写。 如果使用多个单词来形成类的名称,则每个内部单词的第一个字母应为大写。
    示例:class MyFirstJavaClass
  • 方法名称 - 所有方法名称都应以小写字母开头。如果使用多个单词来形成方法的名称,那么每个内部单词的第一个字母应该是大写字母。
    示例:public void myMethodName()
  • 程序文件名 - 程序文件的名称应与类名完全匹配。保存文件时,应使用类名保存它(记住Java区分大小写)并在名称的末尾使用扩展名称:.java(如果文件名和类名不匹配,则程序将无法编译))。但请注意,如果代码文件中没有public class,则文件名可能与类名不同。在代码文件中也没有强制要求必须有public class
    示例:假设MyFirstJavaProgram是类名,那么该文件应保存为:MyFirstJavaProgram.java
  • public static void main(String args[]) − Java程序处理从main()方法开始,该方法是每个Java程序的必需部分。

Hello,World!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 类名命名规范
* 尽量使用中文,首字母尽量大写,文件名尽量和类名相同
*/
class HelloJava{

/* 方法名单词首字母大写,但开头为小写 */
public void printHelloJava(){
System.out.println("hello,java!");
}

// 结果为 -
// hello
public static void main(String[] args){
new HelloJava().printHelloJava();
}
}

/*
命令行编译命令 javac HelloJava.java
命令行运行命令 java HelloJava
*/

注意,可能在使用javac报错

1
2
3
4
错误 - 编码GBK的不可映射字符
原因 - 命令行是GBK,编辑器是UTF-8
解决办法 - 带上参数如下:
javac -encoding UTF-8 HelloJava.java

Java枚举

枚举是在Java 5.0中引入的。 枚举将变量限制为仅具有少数预定义值之一。此枚举列表中的值称为枚举。
通过使用枚举,可以减少代码中的错误数量。

例如,在新鲜果汁店中,可将玻璃杯大小限制为:小杯,中杯和大杯。 这将确保它不允许购买除了小杯,中杯或大杯之外的玻璃杯。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class FreshJuice {
// 定义枚举
enum FreshJuiceSize{ SMALL, MEDIUM, LARGE }
FreshJuiceSize size;
}

public class FreshJuiceTest {

public static void main(String args[]) {
FreshJuice juice = new FreshJuice();
juice.size = FreshJuice.FreshJuiceSize.MEDIUM ;
System.out.println("玻璃杯大小: " + juice.size);
}
}

编译并执行上面示例代码,得到以下结果:

1
玻璃杯大小: MEDIUM

注 - 枚举可以单独声明或在类中声明。 方法,变量,构造函数也可以在枚举内定义。

Java修饰符

修饰符是一种添加到定义以更改其含义的关键字。Java语言有各种各样的修饰符,包括以下两种:

  • Java访问修饰符 - 例如:private,protected,public等。
  • Java非访问修饰符 - 例如:static,final等。

要使用修饰符,请在类,方法或变量的定义中包含修饰符关键字。 修饰符位于语句之前,如下例所示:

1
2
3
4
5
6
7
8
9
10
11
public class className {
// ...
}

private boolean myFlag;
static final double weeks = 9.5;
protected static final int BOXWIDTH = 42;

public static void main(String[] arguments) {
// body of method
}

访问控制修饰符

Java提供了许多访问修饰符来设置类,变量,方法和构造函数的访问级别。 四个访问级别是:

  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
  • default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
  • public : 对所有类可见。使用对象:类、接口、变量、方法

Java访问修饰符对比

强制执行以下继承方法规则:

  • 在超类中声明为public的方法也必须在所有子类中都是public
  • 在超类中声明为protected的方法必须在子类中也要声明为:protectedpublic; 不能声明为:private
  • 声明为private的方法根本不能被继承,因此没有规则。

非访问修饰符

Java提供了许多非访问修饰符来实现许多其他功能。

  • 用于创建类方法和变量的static修饰符。
  • 用于完成类,方法和变量的实现的final修饰符。
  • 用于创建抽象类和方法的abstract修饰符。
  • synchronizedvolatile修饰符,用于线程。

static修饰符

静态变量

static关键字用于创建独立于类实例的变量。无论类的实例数有多少个,都只存在一个静态变量副本。静态变量也称为类变量。局部变量不能声明为static

静态方法

static关键字用于创建独立于类实例的方法。
静态方法不能使用作为类的对象的实例变量,静态方法也叫作类方法。静态方法从参数中获取所有数据并从这些参数计算某些内容,而不引用变量。可以使用类名后跟一个点(.)以及变量或方法的名称来访问类变量或方法。

  • static修饰符用于创建类方法和变量,如下例所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class InstanceCounter {

private static int numInstances = 0;

protected static int getCount() {
return numInstances;
}

private static void addInstance() {
numInstances++;
}

InstanceCounter() {
InstanceCounter.addInstance();
}

public static void main(String[] arguments) {
System.out.println("Starting with " +
InstanceCounter.getCount() +
" instances");

for (int i = 0; i < 500; ++i) {
new InstanceCounter();
}
System.out.println("Created " + InstanceCounter.getCount() + " instances");
}
}

执行上面示例代码,得到以下结果:

1
2
Started with 0 instances
Created 500 instances

final修饰符

final变量

final变量只能显式地初始化一次,声明为final的引用变量永远不能重新分配以引用不同的对象。但是,可以更改对象内的数据。 因此,可以更改对象的状态,但不能更改引用。
对于变量,final修饰符通常与static一起使用,以使常量成为类变量。

1
2
3
4
5
6
7
8
9
10
11
public class Test {
final int value = 10;

// 以下是声明常量的示例:
public static final int BOXWIDTH = 6;
static final String TITLE = "Manager";

public void changeValue() {
value = 12; // 会出错,不能重新赋值
}
}

final方法

任何子类都不能覆盖final方法。 如前所述,final修饰符可防止在子类中修改方法。

声明final方法的主要目的是不让其它人改变方法的内容。

可以在类声明中使用final修饰符声明方法,如下例所示:

1
2
3
4
5
public class Test {
public final void changeName() {
// 方法主体
}
}

final类

使用声明为final的类的主要目的是防止类被子类化。 如果一个类被标记为final,那么这个类不能被其它类继承。

示例

1
2
3
public final class Test {
// body of class
}

abstract修饰符

抽象类

抽象(abstract)类不能实例化。如果一个类声明为抽象(abstract),那么唯一的目的是扩展该类。

一个类不能是同时是abstractfinal(因为final类不能被扩展)。 如果一个类包含抽象方法,那么该类应该被声明为abstract。 否则,将抛出编译错误。

抽象类可以包含抽象方法以及普通方法。

1
2
3
4
5
6
7
8
abstract class Caravan {
private double price;
private String model;
private String year;
public void getYear(String y){};// 这是一个普通方法
public abstract void goFast(); // 这是一个抽象方法
public abstract void changeColor();// 这是一个抽象方法
}

抽象方法

抽象方法是在没有任何实现的情况下声明的方法。 方法体(实现)由子类提供。 抽象方法永远不会是最终的或严格的。

扩展抽象类的任何类都必须实现超类的所有抽象方法,除非子类也是抽象类。

如果一个类包含一个或多个抽象方法,那么该类必须声明为abstract。 抽象类不需要包含抽象方法。

抽象方法以分号结尾。 示例:public abstract sample();

1
2
3
4
5
6
7
8
9
10
public abstract class SuperClass {
abstract void m(); // 抽象方法
}

class SubClass extends SuperClass {
// 实现抽象方法
void m() {
// 实现代码.........
}
}

synchronized修饰符

synchronized关键字用于指示一次只能访问一个方法的方法。synchronized修饰符可以应用于四个访问级别修饰符中的任何一个。

1
2
3
public synchronized void showDetails() {
.......
}

transient修饰符

实例变量标记为transient,表示JVM在序列化包含它的对象时跳过特定变量。

此修饰符包含在创建变量的语句中,位于变量的类或数据类型之前。

1
2
public transient int limit = 55;   // will not persist
public int b; // will persist

volatile修饰符

volatile修饰符用于让JVM知道访问变量的线程必须始终将其自己的变量私有副本与内存中的主副本合并。

访问volatile变量会同步主内存中变量的所有缓存复制。 volatile只能应用于实例变量,类型为privatevolatile对象引用可以为null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MyRunnable implements Runnable {
private volatile boolean active;

public void run() {
active = true;
while (active) { // line 1
// some code here
}
}

public void stop() {
active = false; // line 2
}
}

通常,在一个线程(使用Runnable开始的线程)中调用run(),并从另一个线程调用stop()。 如果在第1行中使用了active的缓存值,那么当在第2行中将active设置为false时,循环可能不会停止。

Java变量

变量提供了程序可以操作的命名存储。 Java中的每个变量都有一个类型,它决定了变量内存的大小和布局; 可以存储在该存储器中的值的范围; 以及可以应用于变量的操作集。

变量需要先声明才能使用,以下是变量声明的基本形式 -

1
data type variable [ = value][, variable [ = value] ...] ;

这里data type是Java的数据类型之一,variable是变量的名称。要声明具有相同类型的多个变量,可以使用逗号分隔列表。

以下是Java中变量声明和初始化的示例 -

1
2
3
4
5
int a, b, c;         // 声明三个int类型变量:a, b 和 c
int a = 10, b = 10; // 初始化它们的值
byte B = 22; // 声明并初始化一个 byte 类型的变量:B
double pi = 3.14159; // 声明并赋值一个 double 类型的变量:pi
char a = 'a'; // 声明char类型变量 a,并初始化值为:'a'

Java中有三种变量 -

  • 局部变量
  • 实例变量
  • 类/静态变量

局部变量

  • 局部变量一般在方法,构造函数或块中声明。
  • 程序进入方法,构造函数或块时会创建局部变量,并且一旦退出方法,构造函数或块,变量就会销毁。
  • 访问修饰符不能用于局部变量。
  • 局部变量仅在声明的方法,构造函数或块中可见。
  • 局部变量在内部实现堆栈级别。
  • 局部变量没有默认值,因此应声明局部变量后,在第一次使用之前为它分配初始值。

在这里,age是一个局部变量。 这是在dogAge()方法中定义的,它的范围仅限于此方法。

1
2
3
4
5
6
7
8
9
10
11
12
public class Test {
public void dogAge() {
int age = 0;
age = age + 5;
System.out.println("Dog age is : " + age);
}

public static void main(String args[]) {
Test test = new Test();
test.dogAge();
}
}

执行上面示例代码,得到以下结果:

1
Dog age is : 5

下面示例中使用变量 age ,但不初始化它,因此在编译时会出错。

1
2
3
4
5
6
7
8
9
10
11
12
public class Test {
public void dogAge() {
int age;
age = age + 5;
System.out.println("Dog age is : " + age);
}

public static void main(String args[]) {
Test test = new Test();
test.dogAge();
}
}

执行上面示例代码,得到以下结果(出错):

1
2
3
4
Test.java:4:variable number might not have been initialized
age = age + 5;
^
1 error

实例变量

  • 实例变量在类中声明,但在方法,构造函数或块之外。
  • 为堆中的对象分配空间时,将为每个实例变量值创建一个槽。
  • 使用关键字new创建对象时会创建实例变量,并在销毁对象时销毁实例变量。
  • 实例变量包含由多个方法,构造函数或块引用的值,或者在整个类中存在的对象状态的基本部分。
  • 实例变量可以在使用之前或之后在类级别中声明。
  • 可以为实例变量给出访问修饰符。
  • 实例变量对于类中的所有方法,构造函数和块都是可见的。 通常,建议将这些变量设为私有(访问级别)。 但是,可以使用访问修饰符为这些变量提供子类的可见性。
  • 实例变量具有默认值。 对于数字,默认值为0,对于布尔值,它为false,对于对象引用,它为null。 可以在声明期间或构造函数中指定值。
  • 可以通过调用类中的变量名来直接访问实例变量。 但是,在静态方法中(当实例变量具有可访问性时),应使用完全限定名称调用它们,如:ObjectReference.VariableName
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.*;
public class Employee {

// 此实例变量对于子类都是可见的。
public String name;

// salary 变量仅在Employee类中可见。
private double salary;

// name变量在构造函数中指定。
public Employee (String empName) {
name = empName;
}

// 为 salary 变量赋值
public void setSalary(double empSal) {
salary = empSal;
}

// 此方法打印员工详细信息。
public void printEmp() {
System.out.println("name : " + name );
System.out.println("salary :" + salary);
}

public static void main(String args[]) {
Employee empOne = new Employee("Maxsu");
empOne.setSalary(15999);
empOne.printEmp();
}
}

执行上面示例代码,得到以下结果:

1
2
name  : Maxsu
salary :15999.0

类/静态变量

  • 类变量(也称为静态变量)在类中使用static关键字声明,但在方法,构造函数或块之外。
  • 每个类只有一个每个类变量的副本,无论从中创建多少个对象。
  • 除了声明为常量之外,很少使用静态变量。常量是声明为public/privatefinalstatic的变量。常量的初始值不能更改。
  • 静态变量存储在静态存储器中。 除了声明的final之外,很少使用静态变量,并将其用作公共或私有常量。
  • 程序启动时会创建静态变量,程序停止时会销毁静态变量。
  • 可见性类似于实例变量。 但是,大多数静态变量都是公共的,因为它们必须可供该类用户使用。
  • 默认值与实例变量相同。 对于数字,默认值为0; 对于布尔类型来说,默认值为false; 对于对象引用,默认值为null。 可以在声明期间或构造函数中指定值。 此外,可以在特殊的静态初始化程序块中分配值。
  • 可以通过使用类名ClassName.VariableName调用来访问静态变量。
  • 将类变量声明为public static final时,变量名(常量)都是大写的。 如果静态变量不是publicfinal,则命名语法与实例和局部变量命名规则相同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.*;
public class Employee {

// salary变量是一个私有静态变量
private static double salary;

// DEPARTMENT是一个常量
public static final String DEPARTMENT = "研发部";

public static void main(String args[]) {
salary = 19999;
System.out.println(DEPARTMENT + "平均薪水:" + salary);
}
}

执行上面示例代码,得到以下结果 -

1
研发部平均薪水:19999

注 - 如果从外部类访问变量,则应作为:Employee.DEPARTMENT

Java基本数据类型

变量是用于存储值的保留内存位置。当创建变量时,它会在内存中保留一些空间。

根据变量的数据类型,操作系统分配内存并决定可以存储在保留内存中的内容。 因此,通过为变量分配不同的数据类型,可以在这些变量中存储整数,小数或字符。

Java中有两种数据类型 -

  • 原始数据类型
  • 引用/对象数据类型

原始数据类型

Java支持八种原始数据类型。 原始数据类型由语言预定义,并由关键字命名。下面来详细了解和学习这八种原始数据类型。

类型 描述 值范围 默认值 示例
byte 表示8位有符号二进制补码整数 -128 (-2^7) - 127 (2^7 -1) 0 byte a = 100, byte b = -50
short 表示16位有符号二进制补码整数 -2^15-2^15 -1 0 short s = 10000, short r = -20000
int 表示32位有符号二进制补码整数 -2^31-2^31 -1 0 int a = 100000, int b = -200000
long 表示64位带符号的二进制补码整数 -2^63-2^63 -1 0L long a = 100000L, long b = -200000L
float 表示单精度32位IEEE 754浮点数 - 0.0f float f1 = 234.5f
double 表示双精度64位IEEE 754浮点数 - 0.0d double d1 = 123.4
boolean 表示一个比特位的信息 true/false false boolean one = true
char 表示单个16位Unicode字符 \u0000-\uffff - char letterA = 'A'

引用数据类型

  • 使用类中已定义构造函数创建引用变量。 它们用于访问对象。 声明这些变量属于无法更改的特定类型。 例如,EmployeeDog类等。
  • 类对象和各种类型的数组变量属于引用数据类型。
  • 任何引用变量的默认值为null
  • 引用变量可用于引用声明类型的任何对象或任何兼容类型。
  • 示例:Dog dog = new Dog("旺财");

Java文字

文字是固定值的源代码表示。它们直接在代码中表示,无需任何计算。可以将文字分配给任何基本类型变量。 例如 -

1
2
byte a = 68;
char a = 'A';

byteintlongshort也可以用十进制(基数为10),十六进制(基数16)或八进制(基数8)数字表示。

前缀0b用于表示二进制,前缀0用于表示八进制,前缀0x表示使用这些数字系统进行文字时的十六进制。 例如 -

1
2
3
4
int binary = 0b11; // 二进制
int decimal = 100; // 十进制
int octal = 0144; // 八进制
int hexa = 0x64; // 十六进制

Java中的字符串文字通过在一对双引号之间包含一系列字符来指定,就像它们在大多数其他编程语言中一样。 字符串文字的例子是 -

1
2
3
"Hello World"
"two\nlines"
""This is in quotes""

字符串和字符类型的文字可以包含任何Unicode字符。 例如 -

1
2
char a = '\u0001';
String a = "\u0001";

Java语言也支持Stringchar文字的几个特殊转义序列。它们是 -

符号 代表的字符
\n 换行符(0x0a)
\r 回车(0x0d)
\f 换页(0x0c)
\b 退格(0x08)
\s 空格(0x20)
\t 制表符
\" 双引号
\' 单引号
\\ 反斜线
\ddd 八进制字符(ddd)
\uxxxx 十六进制UNICODE字符(xxxx)

Java数组

数组是存储多个相同类型变量的对象。 但是,数组本身是堆上的对象。

Java提供了一种叫作数组的数据结构,它是一种用来存储相同类型元素的固定大小顺序集合。 数组用于存储数据集合,但也可以将数组视为相同类型的变量集合。

声明一个数组变量(如:numbers)并使用numbers[0]numbers[1]...numbers[99]来表示单个变量,例如number0number1...number99,而不是单独地声明各个变量。

本教程介绍如何声明数组变量,创建数组和索引访问数组。

声明数组变量

要在程序中使用数组,需要先声明一个变量以引用该数组,并且要指定该变量的数组类型。 以下是声明数组变量的语法 -

1
2
3
dataType[] arrayRefVar;   // 推荐方式。
// 或者
dataType arrayRefVar[]; // 有效,但不是推荐方式。

注 - 格式:dataType [] arrayRefVar是推荐方式。 格式:dataType arrayRefVar []来自C/C++语言,可在Java中采用以适应C/C++程序员。

以下代码片段是此语法的示例 -

1
2
3
double[] myList;   // 推荐方式。
// 或者
double myList[]; // 有效,但不是推荐方式。

创建数组

可以使用new运算符来创建数组,如以下语法 -

1
2
3
4
// 声明
dataType[] arrayRefVar; // 推荐方式。
// 创建
arrayRefVar = new dataType[arraySize];

上面语句做了两件事 -

  • 它使用new dataType[arraySize]来创建了一个数组。
  • 它将新创建的数组的引用分配给变量arrayRefVar

声明一个数组变量,创建一个数组,并将该数组的引用分配给变量,可以在一个语句中完成,如下所示 -

1
dataType[] arrayRefVar = new dataType[arraySize];

或者,可以按如下方式创建数组 -

1
dataType[] arrayRefVar = {value0, value1, ..., valuek};

通过索引访问数组元素。 数组索引值从0开始; 也就是说,它们从0开始到arrayRefVar.length - 1

下面语句中声明了一个数组变量myList,它创建了一个包含10double类型元素的数组,并将数组变量的引用分配给myList -

1
double[] myList = new double[10];

下表表示数组myList。 这里,myList数组中包含十个double值,索引从09

数组下标索引 元素的值
myList[0] 5.6
myList[1] 4.5
myList[2] 3.3
myList[3] 13.2
myList[4] 4.0
myList[5] 34.33
myList[6] 34.0
myList[7] 45.45
myList[8] 99.993
myList[9] 11123

处理数组

处理数组元素时,经常使用for循环或foreach循环,因为数组中的所有元素都是相同的类型,并且数组的大小是已知的。
这是一个完整的示例,演示了如何创建,初始化和处理数组 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.*;

public class Test {

public static void main(String[] args) {
double[] myList = { 10.01, 12.19, 23.44, 43.95, 77.88, 65.00 };

// 打印所有元素
for (int i = 0; i < myList.length; i++) {
System.out.print(myList[i] + ", ");
}
System.out.println(" ");

// 求和
double total = 0;
for (int i = 0; i < myList.length; i++) {
total += myList[i];
}
System.out.println("总和:" + total);

// 查找最大值
double max = myList[0];
for (int i = 1; i < myList.length; i++) {
if (myList[i] > max)
max = myList[i];
}
System.out.println("元素最大值:" + max);
}
}

执行上面示例代码,得到以下结果:

1
2
3
10.01, 12.19, 23.44, 43.95, 77.88, 65.0,  
总和:232.47
元素最大值:77.88

foreach循环

JDK 1.5引入了foreach循环或增强for循环,它能够在不使用索引变量的情况下顺序遍历整个数组。

以下代码演示如何遍历数组myList中的所有元素 -

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.*;

public class Test {

public static void main(String[] args) {
double[] myList = { 10.01, 12.19, 23.44, 43.95, 77.88, 65.00 };

// Print all the array elements
for (double element : myList) {
System.out.print(element+", ");
}
}
}

执行上面示例代码,得到以下结果:

1
10.01, 12.19, 23.44, 43.95, 77.88, 65.0,

将数组传递给方法

就像将原始类型值传递给方法一样,也可以将数组传递给方法。 例如,以下printArray()方法用来打印int数组中的元素 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.*;

public class Test {

public static void main(String[] args) {
double[] myList = { 10.01, 12.19, 23.44, 43.95, 77.88, 65.00 };

// Print all the array elements
printArray(myList);
}

public static void printArray(double[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
}

执行上面示例代码,得到以下结果:

1
10.01 12.19 23.44 43.95 77.88 65.0

从方法返回数组

方法可以返回数组。 例如,以下方法返回一个与给定参数数组相反的数组 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.*;

public class Test {

public static void main(String[] args) {
double[] myList = { 10.01, 12.19, 23.44, 43.95, 77.88, 65.00 };

// Print all the array elements
printArray(myList);
printArray(reverse(myList));
}

public static void printArray(double[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println(" ");
}

public static double[] reverse(double[] list) {
double[] result = new double[list.length];

for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
result[j] = list[i];
}
return result;
}
}

执行上面示例代码,得到以下结果:

1
2
10.01 12.19 23.44 43.95 77.88 65.0  
65.0 77.88 43.95 23.44 12.19 10.01

Arrays类

java.util.Arrays类包含各种静态方法,用于排序和搜索数组,比较数组和填充数组元素。 对于所有基本类型,这些方法都会重载。

方法 描述
public static int binarySearch(Object[] a, Object key) 使用二进制搜索算法搜索指定的Object(Byte,Int,double等)数组以获取指定值。 必须在进行此调用之前对数组进行排序。 如果搜索关键字包含在列表中,则返回搜索关键字的索引; 否则,它返回( -(插入点 + 1))。
public static boolean equals(long[] a, long[] a2) 如果两个指定的long数组相等,则返回true。 如果两个数组包含相同数量的元素,则两个数组被认为是相等的,并且两个数组中的所有相应元素对相等。如果两个数组相等,则返回true。 所有其他原始数据类型(Byte,Short,Int等)可以使用相同的方法。
public static void fill(int[] a, int val) 将指定的int值分配给指定的int数组的每个元素。所有其他原始数据类型(Byte,Short,Int等)可以使用相同的方法。
public static void sort(Object[] a) 根据元素的自然顺序,将指定的对象数组按升序排序。 所有其他原始数据类型(Byte,Short,Int等)可以使用相同的方法。

Java基本运算符

Java提供了一组丰富的操作符来操作变量。 我们可以将所有Java运算符划分为以下几个分类 -

  • 算术运算符
  • 关系运算符
  • 按位运算符
  • 逻辑运算符
  • 赋值运算符
  • 其他运算符

算术运算符

算术运算符在数学表达式中的使用方式与在代数中使用的方式相同。下表列出了算术运算符的使用示例 -

假设整数类型变量A的值为:10,变量B的值为:20,则 -

运算符 描述 示例
+ 加法运算符,第一个操作数加上第二个数操作数 A + B结果为:30
- 减法运算符,从第一个操作数减去第二个操作数 A - B结果为:-10
* 两个操作数相乘 A * B结果为:200
/ 左操作数除以右操作数返回模值 B / A结果为:2
% 左操作数除以右操作数返回余数 B / A结果为:0
++ 将操作数的值增加1 A++,则A的值为:11
-- 将操作数的值减1 A--,则A的值为:9

算术运算符示例代码 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Test {

public static void main(String args[]) {
int a = 10;
int b = 20;
int c = 25;
int d = 25;

System.out.println("a + b = " + (a + b) );
System.out.println("a - b = " + (a - b) );
System.out.println("a * b = " + (a * b) );
System.out.println("b / a = " + (b / a) );
System.out.println("b % a = " + (b % a) );
System.out.println("c % a = " + (c % a) );
System.out.println("a++ = " + (a++) );
System.out.println("b-- = " + (a--) );

// 对比 d++ 和 ++d 有什么区别
System.out.println("d++ = " + (d++) );
System.out.println("++d = " + (++d) );
}
}

执行上面示例代码,得到以下结果:

1
2
3
4
5
6
7
8
9
10
a + b = 30
a - b = -10
a * b = 200
b / a = 2
b % a = 0
c % a = 5
a++ = 10
b-- = 11
d++ = 25
++d = 27

关系运算符

Java语言支持以下关系运算符。假设变量A的值是10,变量B的值是20,则 -

运算符 描述 示例
== 等于运算符,检查两个操作数的值是否相等,如果相等,则条件变为真。 A==B结果为假。
!= 不等于运算符,检查两个操作数的值是否不相等,如果不相等,则条件变为真。 A!=B结果为真。
> 大于运算符,检查左操作数的值是否大于右操作数的值,如果大于,则条件变为真。 A>B结果为假。
< 小于运算符,检查左操作数的值是否小于右操作数的值,如果小于,则条件变为真。 A<B结果为真。
>= 大于或等于运算符,检查左操作数的值是否大于等于右操作数的值,如果大于或等于,则条件变为真。 A>=B结果为假。
<= 小于或等于运算符,检查左操作数的值是否小于或等于右操作数的值,如果小于或等于,则条件变为真。 A<=B结果为真。

Java关系运算符示例代码如下 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test {

public static void main(String args[]) {
int a = 10;
int b = 20;

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("b >= a = " + (b >= a) );
System.out.println("b <= a = " + (b <= a) );
}
}

执行上面示例代码,得到以下结果:

1
2
3
4
5
6
a == b = false
a != b = true
a > b = false
a < b = true
b >= a = true
b <= a = false

按位运算符

Java定义了几个按位运算符,可以应用于整数类型, 如:longintshortcharbyte。按位运算符处理位并执行逐位运算。 假设a = 60b = 13; 采用二进制格式,它们将如下 -

1
2
3
4
5
6
7
8
9
10
11
12
13
a = 0011 1100

b = 0000 1101

-----------------

a&b = 0000 1100

a|b = 0011 1101

a^b = 0011 0001

~a = 1100 0011

下面的表中列出了按位运算符,假设整数变量A=60,变量B=13,那么 -

运算符 描述 示例
& 二进制AND运算符,如果存在于两个操作数中,则它会将结果复制到结果中。 A & B的结果为:12,也就是:0000 1100
Ι 二进制OR运算符,如果存在于任一操作数中,则复制一位。 A Ι B 的结果为:61,也就是:0011 1101
^ 二进制异或运算符,如果在一个操作数中设置但不在两个操作数中设置,则复制该位。 A ^ B的结果为:49,也就是:0011 0001
~ 二元一元补充运算符是一元的,具有“翻转”位的效果。 ~A的结果为:-61,也就是:1100 0011
<< 二进制左移运算符,左操作数值向左移动右操作数指定的位数。 A << 2的结果为:240,也就是:1111 0000
>> 二进制右移运算符,左操作数值向右移动右操作数指定的位数。 A >> 2的结果为:15,也就是:1111
>>> 右移零填充运算符。 左操作数值向右移动右操作数指定的位数,移位值用零填充。 A >>>2的结果为:15,也就是:0000 1111

按位运算符示例代码如下 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Test {

public static void main(String args[]) {
int a = 60; /* 60 = 0011 1100 */
int b = 13; /* 13 = 0000 1101 */
int c = 0;

c = a & b; /* 12 = 0000 1100 */
System.out.println("a & b = " + c );

c = a | b; /* 61 = 0011 1101 */
System.out.println("a | b = " + c );

c = a ^ b; /* 49 = 0011 0001 */
System.out.println("a ^ b = " + c );

c = ~a; /*-61 = 1100 0011 */
System.out.println("~a = " + c );

c = a << 2; /* 240 = 1111 0000 */
System.out.println("a << 2 = " + c );

c = a >> 2; /* 15 = 1111 */
System.out.println("a >> 2 = " + c );

c = a >>> 2; /* 15 = 0000 1111 */
System.out.println("a >>> 2 = " + c );
}
}

执行上面示例代码,得到以下结果:

1
2
3
4
5
6
7
a & b = 12
a | b = 61
a ^ b = 49
~a = -61
a << 2 = 240
a >> 2 = 15
a >>> 2 = 15

逻辑运算符

下表列出了逻辑运算符 -

假设布尔变量A的值为:true,变量B 的值为:false,则 -

运算符 描述 示例
&& 逻辑AND运算符。 如果两个操作数都不为零,则条件成立。 (A && B)结果为:false
ΙΙ 逻辑OR运算符。 如果两个操作数中的任何一个非零,则条件变为真。 (A ΙΙ B)结果为:true
! 逻辑非运算符。用于反转其操作数的逻辑状态。 如果条件为真,则口逻辑NOT运算符将为false !(A && B)结果为:true

逻辑运算符示例代码如下 -

1
2
3
4
5
6
7
8
9
10
11
public class Test {

public static void main(String args[]) {
boolean a = true;
boolean b = false;

System.out.println("a && b = " + (a&&b));
System.out.println("a || b = " + (a||b) );
System.out.println("!(a && b) = " + !(a && b));
}
}

执行上面示例代码,得到以下结果:

1
2
3
a && b = false
a || b = true
!(a && b) = true

赋值运算符

以下是Java语言支持的赋值运算符 -

运算符 描述 示例
= 简单赋值运算符。 将右侧操作数的值分配给左侧操作数。 C = A + BA + B的值分配给C
+= 相加与赋值运算符。 它将右操作数相加到左操作数并将结果分配给左操作数。 C += A等于C = C + A
-= 减去与赋值运算符。 它从左操作数中减去右操作数,并将结果赋给左操作数。 C -= A等于C = C - A
*= 乘以与赋值运算符。 它将右操作数与左操作数相乘,并将结果赋给左操作数。 C *= A等于C = C * A
/= 除以与赋值运算符。 它将左操作数除以右操作数,并将结果赋给左操作数。 C /= A等于C = C / A
%= 模数与赋值运算符。 它使用两个操作数来计算获取模数,并将结果赋给左操作数。 C %= A等于C = C % A
<<= 左移与赋值运算符。 C <<= 2C = C << 2相同
>>= 右移与赋值运算符。 C >>= 2C = C >> 2相同
&= 按位与赋值运算符。 C &= 2C = C & 2相同
^= 按位异或和赋值运算符。 C ^= 2C = C ^ 2相同
Ι= 按位包含或与赋值运算符。 C Ι= 2与C = C Ι=2相同

赋值运算符示例代码如下 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class Test {

public static void main(String args[]) {
int a = 10;
int b = 20;
int c = 0;

c = a + b;
System.out.println("c = a + b = " + c );

c += a ;
System.out.println("c += a = " + c );

c -= a ;
System.out.println("c -= a = " + c );

c *= a ;
System.out.println("c *= a = " + c );

a = 10;
c = 15;
c /= a ;
System.out.println("c /= a = " + c );

a = 10;
c = 15;
c %= a ;
System.out.println("c %= a = " + c );

c <<= 2 ;
System.out.println("c <<= 2 = " + c );

c >>= 2 ;
System.out.println("c >>= 2 = " + c );

c >>= 2 ;
System.out.println("c >>= 2 = " + c );

c &= a ;
System.out.println("c &= a = " + c );

c ^= a ;
System.out.println("c ^= a = " + c );

c |= a ;
System.out.println("c |= a = " + c );
}
}

执行上面示例代码,得到以下结果 -

1
2
3
4
5
6
7
8
9
10
11
12
c = a + b = 30
c += a = 40
c -= a = 30
c *= a = 300
c /= a = 1
c %= a = 5
c <<= 2 = 20
c >>= 2 = 5
c >>= 2 = 1
c &= a = 0
c ^= a = 10
c |= a = 10

其它运算符

Java语言支持的其他运算符很少。

条件运算符(?:)

条件运算符也称为三元运算符。 此运算符由三个操作数组成,用于计算布尔表达式。 运算符的目标是确定应将哪个值赋给变量。 运算符写成 -

1
variable x = (expression) ? value if true : value if false

下面是一段示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
public class Test {

public static void main(String args[]) {
int a, b;
a = 10;
b = (a == 1) ? 20: 30;
System.out.println( "Value of b is : " + b );

b = (a == 10) ? 20: 30;
System.out.println( "Value of b is : " + b );
}
}

执行上面示例代码,得到以下结果 -

1
2
Value of b is : 30
Value of b is : 20

instanceof运算符

此运算符仅用于对象引用变量。 运算符检查对象是否属于特定类型(类类型或接口类型)。 instanceof运算符写成 -

1
( Object reference variable ) instanceof  (class/interface type)

如果操作符左侧的变量引用的对象是右侧的类/接口类型,则结果为真。 以下是一个例子 -

1
2
3
4
5
6
7
8
9
10
11
public class Test {

public static void main(String args[]) {

String name = "Kobe";

// 当 name 的类型是 String 时,则返回为:true
boolean result = name instanceof String;
System.out.println( result );
}
}

执行上面示例代码,得到以下结果:

1
true

如果要比较的对象与右侧类型兼容,则此运算符仍将返回true。 以下是另一个例子 -

1
2
3
4
5
6
7
8
9
10
11
class Vehicle {}

public class Car extends Vehicle {

public static void main(String args[]) {

Vehicle a = new Car();
boolean result = a instanceof Car;
System.out.println( result );
}
}

执行上在示例代码,得到以下结果:

1
true

Java循环控制

在程序执行过程中,存在需要多次执行代码块的情况。 通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。

编程语言提供各种控制结构,允许更复杂的执行路径。

三大循环

Java编程语言提供以下类型的循环来处理循环要求 -

编号 循环 描述
1 while循环 在给定条件为真时重复语句或语句组,它在执行循环体之前测试条件。
2 for循环 多次执行一系列语句,并缩写管理循环变量的代码。
3 do…while循环 while语句一样,但是它在末端测试循环体的条件。

while循环

只要给定条件为真,Java编程语言中的while循环语句就会重复执行目标语句。

语法

while循环的语法是 -

1
2
3
while(boolean_expression) {
// 执行语句
}

这里,语句可以是单个语句或语句块。 条件(boolean_expression)可以是任何表达式,true是任何非零值。

执行时,如果boolean_expression结果为true,则执行循环内的操作。只要表达式结果为true,它将继续执行。

示例1. Java while循环
这是一个简单的java while循环示例,用于打印510之间的数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
//package com.yiibai.javawhileloop;

public class JavaWhileLoop {

public static void main(String[] args) {

int i = 5;
while (i <= 10) {
System.out.println(i);
i++;
}
}
}

请注意,在循环中增加了i的值,否则while循环永远不会终止,因为它变成了无限循环。 终止程序在无限循环中运行的唯一方法是手动退出它或JVM内存不足时。

请注意,如果布尔表达式返回false,则while循环内的语句将不会执行。 所以while循环中的语句有可能永远不会执行。

示例2. Java迭代循环与迭代器

Java while循环在java中经常与迭代器一起使用。 下面来看一个使用while循环迭代ArrayList的简短示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class JavaWhileLoop {
public static void main(String[] args) {
List<String> veggies = new ArrayList<>();
veggies.add("油麦菜");
veggies.add("红豆角");
veggies.add("西红柿");

Iterator<String> it = veggies.iterator();

while (it.hasNext()) {
System.out.println(it.next());
}
}
}

执行上面示例代码,得到以下结果 -

1
2
3
油麦菜
红豆角
西红柿

示例3. while无限循环示例

有时希望循环无限运行。在这种情况下,可以使用while循环。 无限运行的一个例子是在特定位置连续查找文件,如果找到则然后处理它。 下面是java中while循环的伪代码示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//package com.yiibai.javawhileloop;

public class WhileTrueJava {

public static void main(String[] args) {
while(true) {
System.out.println("开始处理");
// 在特定目录中查找文件
// 如果找到则处理它,比如将文件信息插入数据库
System.out.println("结束处理");

// 等待10秒,再继续处理...
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
System.out.println("Thread Interrupted, exit now");
System.exit(0);
}
}
}

}

如果运行上面的程序,需要在终端上使用Ctrl + C手动退出程序。 如果使用的是Eclipse,则会有一个红色按钮来终止当前正在运行的程序。

for循环

for循环是一种重复控制结构,用于有效地编写需要执行特定次数的循环。当知道要重复任务的次数时,for循环就很有用。

语法

for循环的语法是 -

1
2
3
for(initialization; boolean_expression; update) {
// Statements
}

在上面语法中,

  • 首先执行初始化(initialization)步骤,并且仅执行一次。此步骤用于声明和初始化循环控制变量,此步骤以分号(;)结束。
  • 接下来,计算布尔表达式(boolean_expression)。 如果结果为:true,则执行循环体。 如果为false,则不执行循环体,控制跳转到for循环之后的下一个语句。
  • 在执行for循环体之后,控件跳回到update语句。 此语句用于更新任何循环控制变量。此语句可以留空,最后是分号(;)。
  • 现在再次评估布尔表达式(boolean_expression)。 如果结果为:true,则循环执行并重复该过程(循环体,然后是更新步骤,然后是布尔表达式)。 布尔表达式为false后,for循环终止。

java中有三种类型的for循环,它们分别如下:

  • 简单for循环
  • for-each或增强for循环
  • for循环与标签

1. 简单for循环实例

Java中的简单for循环与C/C ++相同。可以初始化变量,检查条件和增量/减量值。
假设要打印510的整数,在这种情况下可以使用基本的for循环。

1
2
3
4
5
6
7
8
9
10
11
12
//package com.yiibai.javaforloop;

public class JavaForLoop {

public static void main(String[] args) {

//print integers 5 to 10
for (int i=5; i<=10; i++) {
System.out.println("Java for loop example - " + i);
}
}
}

执行上面示例代码,得到以下结果 -

1
2
3
4
5
6
Java for loop example - 5
Java for loop example - 6
Java for loop example - 7
Java for loop example - 8
Java for loop example - 9
Java for loop example - 10

示例2. for增强型循环

Java中的for each循环也称为增强型循环。可以使用for each迭代数组或集合元素。Java for each循环是推荐的循环方式,因为它的代码编写比较简单和紧凑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//package com.yiibai.javaforloop;

import java.util.ArrayList;
import java.util.List;

public class JavaForEachLoopExample {

public static void main(String[] args) {
int[] intArray = { 10, 20, 30, 40, 50 };

for (int i : intArray)
System.out.println("Java for each loop with array - " + i);

List<String> fruits = new ArrayList<>();
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橙子");

for (String f : fruits)
System.out.println("Java for each loop with collection - " + f);
}

}

执行上面示例代码,得到以下结果 -

1
2
3
4
5
6
7
8
Java for each loop with array - 10
Java for each loop with array - 20
Java for each loop with array - 30
Java for each loop with array - 40
Java for each loop with array - 50
Java for each loop with collection - 苹果
Java for each loop with collection - 香蕉
Java for each loop with collection - 橙子

从上面的例子中可以看出,如果for循环中只有一个语句,不需要将它们放在花括号{}中。

示例3. for循环与标签

可以在for循环中添加一个标签,它对breakcontinue语句有用,可以退出外循环。 请注意,默认情况下,breakcontinue语句仅适用于内部循环。 下面是带有标签的for循环的示例以及它如何与continue语句一起使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import  java.util.Arrays;
public class JavaForLoopWithLabel {
public static void main(String[] args) {
int[][] intArr = { { 1, -2, 3 }, { 0, 3 }, { 1, 2, 5 }, { 9, 2, 5 } };
process: for (int i = 0; i < intArr.length; i++) {
boolean allPositive = true;
for (int j = 0; j < intArr[i].length; j++) {
if (intArr[i][j] < 0) {
allPositive = false;
continue process;
}
}
if (allPositive) {
// process the array
System.out.println("Processing " + Arrays.toString(intArr[i]));
}
allPositive = true;
}
}
}

执行上面示例代码,得到以下结果 -

1
2
3
Processing [0, 3]
Processing [1, 2, 5]
Processing [9, 2, 5]

do…while循环

其实笔者基本也只在算法题里面用的比较多

do...while循环类似于while循环,除了do...while循环保证至少执行一次。

语法
以下是do...while循环的语法 -

1
2
3
do {
// Statements
}while(boolean_expression);

请注意,布尔表达式在循环的末尾,因此循环中的语句在测试布尔值之前已经执行了一次。

如果布尔表达(boolean_expression)式评估结果为true,则控制跳回到do语句,循环中的语句再次执行。 重复此过程,直到布尔表达式(boolean_expression)评估结果为false

示例1. do…while循环

这是一个简单的java do while循环示例,用于打印510之间的数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//package com.yiibai.javadowhileloop;

public class JavaDoWhileLoop {

public static void main(String[] args) {

int i = 5;
do {
System.out.println(i);
i++;
} while (i <= 10);
}
}
Java

执行上面示例代码,得到以下结果:

1
2
3
4
5
6
5
6
7
8
9
10

示例2. do…while无限循环

通过在do...while循环中将布尔表达式使用true值来创建无限循环。下面是一个简单的做java无限循环的例子(伪代码)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//package com.java.javadowhileloop;

public class DoWhileTrueJava {

public static void main(String[] args) throws InterruptedException {
do {
System.out.println("Start Processing inside do while loop");
// 在指定目录中查找文件
// 如果找到,则处理它,例如:将文件信息插入数据库
System.out.println("End Processing of do while loop");

Thread.sleep(5 * 1000); // 暂停5秒,接着执行
} while (true);
}
}

请注意,如果在终端中执行程序,则可使用Ctrl + C手动退出应用程序。 如果已在Eclipse IDE中执行程序,则会有一个红色按钮来终止程序。

do…while与while循环比较

当希望在循环内的语句至少执行一次时,则应该使用do...while循环。 否则,使用while循环总是更好选择。Java while循环看起来比do...while循环更干净。

循环控制语句

循环控制语句将执行从正常执行顺序更变。 当执行离开作用域时,将销毁在该作用域中创建的所有自动对象。

Java支持以下控制语句,可通过单击以下每个链接来了解和学习。

编号 控制语句 描述
1 break语句 终止循环或switch语句,并立即将执行转移到在循环或switch之后的语句。
2 continue语句 使循环跳过其主体的其余部分,并在重复之前立即重新测试其状态。

break语句

Java编程语言中的break语句有以下两种用法 -

  • 当在循环内遇到break语句时,循环立即终止,程序控制在循环体之后的下一个语句处重新开始。
  • 它可以用于在switch语句中终止一个case

语法

break的语法是循环内的单个语句 -

1
break;

示例1. break简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Test {

public static void main(String args[]) {
int [] numbers = {10, 20, 30, 40, 50};

for(int x : numbers ) {
if( x == 30 ) {
break;
}
System.out.print( x );
System.out.print("\n");
}
}
}

执行上面示例代码,得到以下结果 -

1
2
10
20

示例2. break语句示例

在这个示例中,演示如何在java的for循环,while循环和do-while循环中使用break语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// package com.yiibai.util;

public class JavaBreak {

public static void main(String[] args) {
String[] arr = { "Y", "I", "I", "B", "A", "I" };

// 在 for 循环中使用 break
for (int len = 0; len < arr.length; len++) {
if (arr[len].equals("I")) {
System.out.println("Array contains 'I' at index: " + len);
// 当找到字母时使用`break`语句中断循环
break;
}
}

// 在 while 循环中使用 break
int len = 0;
while (len < arr.length) {
if (arr[len].equals("B")) {
System.out.println("Array contains 'B' at index: " + len);
// 当找到字母时使用`break`语句中断循环
break;
}
len++;
}

len = 0;
// 在 do-while循环中使用 break
do {
if (arr[len].equals("A")) {
System.out.println("Array contains 'A' at index: " + len);
// 当找到字母时使用`break`语句中断循环
break;
}
len++;
} while (len < arr.length);
}

}

执行上面示例代码,得到以下结果:

1
2
3
Array contains 'I' at index: 1
Array contains 'B' at index: 3
Array contains 'A' at index: 4

请注意,如果删除break语句,程序的输出将没有任何差异。 对于此示例中的小型迭代,没有的性能问题。 但是如果迭代器次数很大,那么它可以节省大量的处理时间。

示例3. Java break标签
break语句标签化用于终止外部循环,应该标记循环以使其起作用。这是一个演示java break标签语句用法的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// package com.yiibai.util;

public class JavaBreakLabel {

public static void main(String[] args) {
int[][] arr = { { 1, 2 }, { 3, 4 }, { 9, 10 }, { 11, 12 } };
boolean found = false;
int row = 0;
int col = 0;
// 查找第一个大于10的整数所在的索引值
searchint:

for (row = 0; row < arr.length; row++) {
for (col = 0; col < arr[row].length; col++) {
if (arr[row][col] > 10) {
found = true;
// 使用 break 标签来终止外部语句
break searchint;
}
}
}
if (found)
System.out.println("First int greater than 10 is found at index: [" +
row + "," + col + "]");
}

}

执行上面示例代码,得到以下结果:

1
First int greater than 10 is found at index: [3,0]

continue语句

Java continue语句用于继续循环。 它继续程序的当前流程,并在指定条件下跳过剩余的代码。在内循环的情况下,它仅继续内循环。

语法:

1
2
jump-statement;    
continue;

Java continue语句示例

1
2
3
4
5
6
7
8
9
10
public class ContinueExample {
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
continue;
}
System.out.println(i);
}
}
}

执行上面示例代码,得到如下结果 -

1
2
3
4
5
6
7
8
9
1
2
3
4
6
7
8
9
10

Java continue语句与内循环

如果在内循环中使用continue语句,它将继续内循环。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
public class ContinueExample2 {
public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (i == 2 && j == 2) {
continue;
}
System.out.println(i + " " + j);
}
}
}
}

执行上面示例代码,得到如下结果 -

1
2
3
4
5
6
7
8
1 1
1 2
1 3
2 1
2 3
3 1
3 2
3 3

Java决策制定

Java编程语言提供以下类型的决策制定语句。 可通过单击以下链接来了解和学习。

编号 语句 描述
1 if语句 if语句由布尔表达式后跟一个或多个语句组成。
2 if…else语句 if语句后面可以跟一个可选的else语句,else语句在布尔表达式为false时执行。
3 switch语句 switch语句允许测试变量与值列表的相等性。

if语句

if语句由一个布尔表达式后跟一个或多个语句组成。

语法

以下是if语句的语法 -

1
2
3
if(boolean_expression) {
// 如果布尔表达式为`true`,则将执行这里的语句
}

如果布尔表达式(boolean_expression)的计算结果为true,那么将执行if语句中的代码块。 如果计算结果为false,将执行if语句结束后(在结束大括号之后)的第一组代码。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class IfExample {

public static void main(String[] args) {
int age = 20;
if (age > 18) {
System.out.println("年龄大于 18 岁");
}
if (age <= 20) {
System.out.println("年龄小于或等于 20 岁");
}

if (age >= 20 && age < 30) {
System.out.println("年龄小于或等于 20 岁,并且小于 30 岁");
}
}
}

执行上面示例代码,得到以下结果:

1
2
3
年龄大于 18 岁
年龄小于或等于 20 岁
年龄小于或等于 20 岁,并且小于 30 岁

if…else语句

if语句后面可以跟一个可选的else语句,else语句在布尔表达式为false时执行。

语法

以下是if...else语句的语法 -

1
2
3
4
5
if(boolean_expression) {
// 布尔表达式为true时执行
}else {
// 布尔表达式为false时执行
}

如果布尔表达式的计算结果为true,那么将执行if代码块,否则将执行else代码块。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//一个用于演示if-else语句的Java程序。  
public class IfElseExample {
public static void main(String[] args) {
// 定义一个变量
int number = 133;
// 检查数字是否可以被 2 整除?
if (number % 2 == 0) {
System.out.println(number + " 是一个偶数");
} else {
System.out.println(number + " 是一个奇数");
}

// 示例2
int x = 30;

if (x < 20) {
System.out.println(x + " 是一个小于 20 的整数");
} else {
System.out.println(x + " 是一个大于 20 的整数");
}

}
}

执行上面示例代码,得到以下结果:

1
2
133 是一个奇数
30 是一个大于 20 的整数

if…else if…else语句

if语句之后可以跟一个可选的else if语句,这对于使用if...else if语句测试各种条件非常有用。

当使用ifelse ifelse语句时,需要记住几点:

  • 一个if语句之后可以有零个或一个else语句,但它必须在else...if之后。
  • if可以有零或多个else...if,并且它们必须在else语句之前。
  • 当有一个else if条件匹配成功,其余的else...if或者else都将不会执行。

语法

以下是if...else语句的语法 -

1
2
3
4
5
6
7
8
9
if(boolean_expression_1) {
// 当 boolean_expression_1 结果为 true 时,执行这里的代码块
}else if(boolean_expression_2) {
// 当 boolean_expression_2 结果为 true 时,执行这里的代码块
}else if(boolean_expression_3) {
// 当 boolean_expression_3 结果为 true 时,执行这里的代码块
}else {
// 当上面表达式都没有一个计算结果为 true 时,执行这里的代码块
}

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Java程序演示如何使用 if else-if 梯形。 
//它是一个判断分数级别为:D级,C级,B级,A级和A+级 的程序。
public class IfElseIfExample {
public static void main(String[] args) {
int marks = 65;

if (marks < 60) {
System.out.println("D级");
} else if (marks >= 60 && marks < 70) {
System.out.println("C级");
} else if (marks >= 70 && marks < 80) {
System.out.println("B级");
} else if (marks >= 80 && marks < 90) {
System.out.println("A级");
} else if (marks >= 90 && marks < 100) {
System.out.println("A+级");
} else {
System.out.println("无效!");
}
}
}

执行上面示例代码,得到以下结果:

1
C级

switch语句

switch语句用于测试变量与值列表的相等性。 每个值称为一个case,并且针对每种情况检查对应的变量值。

语法
增强for循环的语法是 -

1
2
3
4
5
6
7
8
9
10
11
12
13
switch(expression) {
case value :
// 执行语句块
break; // 可选

case value :
// 执行语句块
break; // 可选

// 可以拥有任意数量的 case 语句。
default : // 可选
// 执行语句块
}

以下是适用于switch语句的规则 -

  • switch语句中使用的变量只能是整数,可转换为整数(如:byteshortchar),字符串和枚举类型。
  • 可以在switch中包含任意数量的case语句。每个case后跟要与之比较的值和冒号。
  • case的值必须与switch中的变量具有相同的数据类型,并且必须是常量或文字。
  • switch的变量等于case中的值时,该case之后的语句将一直执行,直到达到break语句。
  • 当达到break语句时switch终止,控制流跳转到switch语句块后面的下一行代码。
  • 不是每个case都需要包含break语句。 如果没有指定break语句,则控制流将落到后续case中,直到达到break语句。
  • switch语句可以有一个可选的default,它必须出现在switch语句的末尾。 当没有任何case匹配时,执行default中的代码块。default中不需要break语句。

示例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class SwitchExample {
public static void main(String[] args) {
// 为switch表达式声明一个变量
int number = 20;
// Switch表达式
switch (number) {
// Case语句
case 10:
System.out.println("10");
break;
case 20:
System.out.println("20");
break;
case 30:
System.out.println("30");
break;
// Default case statement
default:
System.out.println("Not in 10, 20 or 30");
}
}
}

执行上面示例代码,得到以下结果:

1
20

示例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class SwitchExample {
public static void main(String args[]) {
// char grade = args[0].charAt(0);
char grade = 'B';

switch (grade) {
case 'A':
System.out.println("相当优秀!");
break;
case 'B':
case 'C':
System.out.println("一般优秀");
break;
case 'D':
System.out.println("还不错");
case 'F':
System.out.println("好像不太行");
break;
default:
System.out.println("无效级别");
}
System.out.println("您的级别是:" + grade);
}
}

执行上面示例代码,得到以下结果:

1
2
一般优秀
您的级别是:B

Java方法

Java中的方法是一组语句,它们组合在一起以执行各种操作。 例如,当调用System.out.println()方法时,系统实际上会执行多个语句,以便在控制台上显示消息。

下面将学习如何使用或不使用返回值创建自己的方法,使用或不使用参数调用方法,以及在程序设计中应用方法抽象。

创建方法

下面来看看方法的语法 -

1
2
3
public static int methodName(int a, int b) {
// body
}

在上面语法中,

  • public static − 修辞符
  • int − 返回值的类型
  • methodName − 方法的名称
  • a, b − 形式参数
  • int a, int b − 参数列表

方法定义由方法头和方法体组成。以下语法中显示了相同的内容 -

1
2
3
modifier returnType nameOfMethod (Parameter List) {
// method body
}

上面显示的语法包括 -

  • modifier - 它定义方法的访问类型,它可能是:public,private,protected或不指定。
  • returnType - 方法可以返回一个值。
  • nameOfMethod - 这是方法名称,方法签名由方法名称和参数列表组成。
  • Parameter List - 参数列表,它是方法的类型,顺序和参数数量。 这些是可选的,方法可能包含零参数。
  • method body - 方法体定义方法对语句的作用。

示例

以下代码中定义了min()方法。 这个方法有两个int类型的参数:num1num2,并返回两者之间的最大值 -

1
2
3
4
5
6
7
8
9
10
/** 返回两个数字之间的最小值 */
public static int minFunction(int n1, int n2) {
int min;
if (n1 > n2)
min = n2;
else
min = n1;

return min;
}

方法调用

可通过调用方法来使用方法,调用方法有两种方式,即方法有返回值或无返回任何值。

方法调用的过程很简单。 当程序调用方法时,程序控制将转移到被调用的方法。 这个被调用的方法然后在两个条件下将控制权返回给调用者,即 -

  • return语句被执行。
  • 它到达方法的结束,即右大括号(})。

对返回void的方法的调用 -

1
System.out.println("This is Yiibai.com!");

对有返回值的方法的调用 -

1
int result = sum(6, 9);

以下是演示如何定义方法以及如何调用方法的示例 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ExampleMinNumber {

public static void main(String[] args) {
int a = 111;
int b = 125;
int c = getMin(a, b);
System.out.println("最小值 = " + c);
}

/** 返回两个 int 数值的最小值 */
public static int getMin(int n1, int n2) {
int min;
if (n1 > n2)
min = n2;
else
min = n1;

return min;
}
}

执行上面示例代码,得到以下结果:

1
最小值 = 111

void关键字

void关键字允许创建不返回值的方法。在下面的例子中有一个返回值是void的方法methodRankPoints,它不返回任何值。 调用void方法必须是一个语句,即methodRankPoints(245.67);. 它是一个以分号结尾的Java语句,如以下示例所示 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ExampleVoid {

public static void main(String[] args) {
methodRankPoints(245.67);
}

public static void methodRankPoints(double points) {
if (points >= 202.5) {
System.out.println("Rank:A1");
}else if (points >= 122.4) {
System.out.println("Rank:A2");
}else {
System.out.println("Rank:A3");
}
}
}

执行上面示例代码,得到以下结果:

1
Rank:A1

按值传递参数

在按值传递参数时需要传递参数。它们的顺序应与方法规范中的参数顺序相同。参数可以通过值或引用传递。

通过值传递参数是使用参数调用方法。 通过这样将参数值将传递给参数。

示例

以下程序显示了按值传递参数的示例。 即使在方法调用之后,参数的值仍保持不变。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class swappingExample {

public static void main(String[] args) {
int a = 30;
int b = 45;
System.out.println("Before swapping, a = " + a + " and b = " + b);

// 调用交换方法
swapFunction(a, b);
System.out.println("Now, Before and After swapping values will be same here:");
System.out.println("After swapping, a = " + a + " and b is " + b);
}

public static void swapFunction(int a, int b) {
System.out.println("Before swapping(Inside), a = " + a + " b = " + b);
// 交换 n1 和 n2
int c = a;
a = b;
b = c;
System.out.println("After swapping(Inside), a = " + a + " b = " + b);
}
}

执行上面示例代码,得到以下结果:

1
2
3
4
5
Before swapping, a = 30 and b = 45
Before swapping(Inside), a = 30 b = 45
After swapping(Inside), a = 45 b = 30
Now, Before and After swapping values will be same here:
After swapping, a = 30 and b is 45

方法重载

当一个类有两个或多个同名但方法不同参数的方法时,称为方法重载。 它与重写不同。 在重写中,方法具有相同的方法名称,类型,参数数量等。

在前面讨论的用于查找最小整数类型数的示例中,假设想要查找两个double类型的最小数值。 可引入重载的概念以创建具有相同名称但不同参数的两个或更多方法。

参考以下示例代码 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class ExampleOverloading {

public static void main(String[] args) {
int a = 11;
int b = 6;
double c = 7.3;
double d = 9.4;
int result1 = getMin(a, b);

// 具有相同函数名称,但数字不同参数
double result2 = getMin(c, d);
System.out.println("Minimum Value = " + result1);
System.out.println("Minimum Value = " + result2);
}

// 处理 int 类型的数值(方法重载)
public static int getMin(int n1, int n2) {
int min;
if (n1 > n2)
min = n2;
else
min = n1;

return min;
}

// 处理 double 类型的数值(方法重载)
public static double getMin(double n1, double n2) {
double min;
if (n1 > n2)
min = n2;
else
min = n1;

return min;
}
}

执行上面示例代码,得到以下结果:

1
2
Minimum Value = 6
Minimum Value = 7.3

重载方法使程序可读。这里,两个方法由相同的名称给出但具有不同的参数类型。结果是求int类型和double类型的最小数。

使用命令行参数

有时希望在运行程序时将一些信息传递给程序。它是通过将命令行参数传递给main()来实现的。

命令行参数是执行时在命令行上直接跟随程序名称的信息。 要访问Java程序中的命令行参数非常简单。 它们作为字符串存储在传递给main()String类型数组中。

示例

以下程序显示传递给程序的所有命令行参数 -

1
2
3
4
5
6
7
8
public class CommandLine {

public static void main(String args[]) {
for(int i = 0; i<args.length; i++) {
System.out.println("args[" + i + "]: " + args[i]);
}
}
}

使用以下方式执行此程序 -

1
java CommandLine this is a command line 200 -100

那么将得到以下结果:

1
2
3
4
5
6
7
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

this关键字

this是Java中的一个关键字,用作对当前类对象的引用,在实例方法或构造函数中。 使用它可以引用类的成员,例如:构造函数,变量和方法。

注 - this关键字仅在实例方法或构造函数中使用。

通常,this关键字用于 -

  • 如果实例变量在构造函数或方法中具有相同的名称,则将它们与局部变量区分开来。

    1
    2
    3
    4
    5
    6
    class Student {
    private int age;
    Student(int age) {
    this.age = age;
    }
    }
  • 从类中的其他方法调用一种类型的构造函数(参数化构造函数或默认值),称为显式构造函数调用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Student {
    int age;
    Student() {
    this(20);
    }
    Student(int age) {
    this.age = age;
    }
    }

以下是使用this关键字访问类成员的示例 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class ThisExample {
// 实例变量:num
int num = 10;
ThisExample() {
System.out.println("This is an example program on keyword this");
}

ThisExample(int num) {
// 调用默认构造方法
this();

// 将局部变量 num 分配给实例变量 num
this.num = num;
}

public void greet() {
System.out.println("Hi Welcome to Yiibai");
}

public void print() {
// 局部变量:num
int num = 20;

// 打印局部变量
System.out.println("value of local variable num is : "+num);

// 打印实例变量
System.out.println("value of instance variable num is : "+this.num);

// 调用类方法
this.greet();
}

public static void main(String[] args) {
// 实例化该类
ThisExample obj1 = new ThisExample();

// 调用 print 方法
obj1.print();

//通过参数化构造函数将新值传递给 num 变量
ThisExample obj2 = new ThisExample(30);

// 再次调用 print 方法
obj2.print();
}
}

执行上面示例代码,得到以下结果 -

1
2
3
4
5
6
7
8
This is an example program on keyword this 
value of local variable num is : 20
value of instance variable num is : 10
Hi Welcome to Yiibai
This is an example program on keyword this
value of local variable num is : 20
value of instance variable num is : 30
Hi Welcome to Yiibai

变量参数(var-args)

JDK 1.5允许将可变数量的相同类型的参数传递给方法。方法中的参数声明如下 -

1
typeName... parameterName

在方法声明中,指定类型后跟省略号(...)。 在方法中只能指定一个可变长度参数,并且此参数必须是最后一个参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class VarargsDemo {

public static void main(String args[]) {
// 使用变量参数调用方法
printMax(314, 321, 213, 212, 356.5);
printMax(new double[]{1, 2, 3});
}

public static void printMax( double... numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}

double result = numbers[0];

for (int i = 1; i < numbers.length; i++)
if (numbers[i] > result)
result = numbers[i];
System.out.println("参数列表中的最大值是:" + result);
}
}

执行上面示例代码,得到以下结果 -

1
2
参数列表中的最大值是:356.5
参数列表中的最大值是:3.0

finalize()方法

finalize()方法在垃圾收集器对象最终销毁之前调用,它可用于确保对象完全终止。例如,可以使用finalize()来确保该对象拥有的打开文件已关闭。

要将终结器添加到类中,只需定义finalize()方法即可。只要Java方法要回收该类的对象,它就会调用该方法。

finalize()方法中,将指定在销毁对象之前必须执行的操作。finalize()方法有这种一般形式 -

1
2
3
protected void finalize( ) {
// finalization code here
}

这里,关键字protected是一个修辞符,它阻止通过类外部定义的代码访问finalize()
我们无法知道Java何时或甚至是否将执行finalize()方法。如果程序在垃圾收集发生之前结束,则finalize()将不会执行。

Java正则表达式

Java提供了java.util.regex包,用于与正则表达式进行模式匹配。 Java正则表达式与Perl编程语言非常相似,非常容易学习。

正则表达式是一种特殊的字符序列,可使用模式中的专用语法来匹配或查找其他字符串或字符串集。 它们可用于搜索,编辑或操作文本和数据。

java.util.regex包主要由以下三个类组成 -

  • Pattern类 - Pattern对象是正则表达式的编译表示。 Pattern类不提供公共构造函数。 要创建模式,需要首先调用它的公共静态compile()方法,然后返回Pattern对象。 这些方法接受正则表达式作为第一个参数。
  • Matcher类 - Matcher对象是解释模式并对输入字符串执行匹配操作的引擎。 与Pattern类一样,Matcher没有定义公共构造函数。 通过在Pattern对象上调用matcher()方法获取Matcher对象。
  • PatternSyntaxException - PatternSyntaxException对象是未经检查的异常,指示正则表达式模式中的语法错误。

捕获组

捕获组是将多个字符视为一个单元的一种方法。 它们是通过将要分组的字符放在一组括号中来创建的。 例如,正则表达式(dog)创建包含字母dog的单个组。

捕获组通过从左到右计算它们的左括号来编号。 在表达式((A)(B(C)))中,例如,有四个这样的组 -

  • ((A)(B(C)))
  • (A)
  • (B(C))
  • (C)

要查找表达式中存在多少个组,请在Matcher对象上调用groupCount()方法。 groupCount()方法返回一个int类型值,显示Matcher模式中存在的捕获组数。

还有一个特殊组,即组0,它始终代表整个表达式。 该组未包含在groupCount()报告的总数中。

示例

以下示例说明如何从给定的字母数字字符串中查找数字字符串 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

public static void main( String args[] ) {
// String to be scanned to find the pattern.
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";

// Create a Pattern object
Pattern r = Pattern.compile(pattern);

// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Found value: " + m.group(0) );
System.out.println("Found value: " + m.group(1) );
System.out.println("Found value: " + m.group(2) );
}else {
System.out.println("NO MATCH");
}
}
}

执行上面示例代码,得到以下结果:

1
2
3
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

正则表达式语法

下面列出了Java中可用的所有正则表达式元字符语法 -

编号 子表达式 匹配
1 ^ 匹配行的开头。
2 $ 匹配行的结尾。
3 . 匹配除换行符之外的任何单个字符,使用m选项也可以匹配换行符。
4 [...] 匹配括号中的任何单个字符。
5 [^...] 匹配括号内的任何单个字符。
6 \A 整个字符串的开头。
7 \z 整个字符串的结尾。
8 \Z 除允许的最终行终止符之外的整个字符串的结尾。
9 re* 匹配前面表达式的0次或更多次出现。
10 re+ 匹配前面表达式的1次或更多次出现。
11 re? 匹配前面表达式的01次出现。
12 re{n} 准确匹配前面表达式的n次出现次数。
13 re{n,} 准确匹配前面表达式的n次以上出现次数。
14 aΙb 匹配ab
15 (re) 对正则表达式进行分组并记住匹配的文本。
16 (?: re) 将正则表达式分组而不记住匹配的文本。
17 (?> re) 匹配独立模式而无需回溯。
18 \w 匹配单词字符。
19 \W 匹配非单词字符。
20 \s 匹配空白符,相当于:[\t\n\r\f]
21 \S 匹配非空白。
22 \d 匹配数字,相当于:[0-9]
23 \D 匹配非数字。
24 \A 匹配字符串的开头。
25 \Z 匹配字符串的结尾。如果存在换行符,则它在换行符之前匹配。
26 \z 匹配字符串的结尾。
27 \G 匹配最后一个匹配结束的点。
28 \n 反向引用以捕获组号:n
29 \b 在括号外部匹配单词边界,在括号内匹配退格(0x08)。
30 \B 匹配非字边界。
31 \n,\t 匹配换行符,回车符,制表符等。
32 \E 转义(引用)所有字符直到\E
33 \Q 结束以\Q开头引用。

start()和end()方法

以下是计算字符串中:cat一词的出现次数示例 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

private static final String REGEX = "\\bcat\\b";
private static final String INPUT = "cat cat cat cattie cat";

public static void main( String args[] ) {
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT); // get a matcher object
int count = 0;

while(m.find()) {
count++;
System.out.println("Match number "+count);
System.out.println("start(): "+m.start());
System.out.println("end(): "+m.end());
}
}
}

执行上面示例代码,得到以下结果:

1
2
3
4
5
6
7
8
9
10
11
12
Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

可以看到此示例使用单词边界来确保字母:c,a,t不仅仅是较长单词中的子字符串。 它还提供了有关输入字符串中匹配发生位置的一些有用信息。

start方法返回上一个匹配操作期间给定组捕获的子序列的起始索引,end返回匹配的最后一个字符的索引加1

matches和lookingAt方法

matches()lookingAt()方法都尝试将输入序列与模式匹配。 然而,不同之处在于匹配需要匹配整个输入序列,而查找则不需要。

两种方法总是从输入字符串的开头开始。 以下是上述方法的示例 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

private static final String REGEX = "foo";
private static final String INPUT = "fooooooooooooooooo";
private static Pattern pattern;
private static Matcher matcher;

public static void main( String args[] ) {
pattern = Pattern.compile(REGEX);
matcher = pattern.matcher(INPUT);

System.out.println("Current REGEX is: "+REGEX);
System.out.println("Current INPUT is: "+INPUT);

System.out.println("lookingAt(): "+matcher.lookingAt());
System.out.println("matches(): "+matcher.matches());
}
}

执行上面示例代码,得到以下结果:

1
2
3
4
Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

replaceFirst和replaceAll方法
replaceFirst()replaceAll()方法替换匹配给定正则表达式的文本。 正如其名称所示,replaceFirst()替换第一个匹配项,replaceAll()替换所有匹配项。

以下是上述功能的示例 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

private static String REGEX = "dog";
private static String INPUT = "The dog says meow. " + "All dogs say meow.";
private static String REPLACE = "cat";

public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);

// get a matcher object
Matcher m = p.matcher(INPUT);
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
}
}

执行上面示例代码,得到以下结果:

1
The cat says meow. All cats say meow.

appendReplacement和appendTail方法

Matcher类还提供了appendReplacementappendTail方法来替换文本。

以下是上述方法的示例 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

private static String REGEX = "a*b";
private static String INPUT = "aabfooaabfooabfoob";
private static String REPLACE = "-";
public static void main(String[] args) {

Pattern p = Pattern.compile(REGEX);

// get a matcher object
Matcher m = p.matcher(INPUT);
StringBuffer sb = new StringBuffer();
while(m.find()) {
m.appendReplacement(sb, REPLACE);
}
m.appendTail(sb);
System.out.println(sb.toString());
}
}

执行上面示例代码,得到以下结果:

1
-foo-foo-foo-