Java数组、字符串、正则表达式
数组
基本知识
Java中,数组元素可以为简单数据类型,也可以为对象。 数组声明方式,有以下两种:
- 数据类型 数组名[ ];
- 数据类型[ ] 数组名;
int tempArray1[] = {1,2,3};
System.out.println(Arrays.toString(tempArray1));
int[] tempArray2 = {6,7,8};
System.out.println(Arrays.toString(tempArray2));
与C/C++不同,Java在数组的定义中并不为数组元素分配内存,因此[ ]中不能指出数组中元素的个数,即数组长度。数组必须经过初始化后,才能使用数组的元素。
数组初始化分为静态初始化和动态初始化。
- 静态初始化:在定义数组的同时对数组元素进行初始化。
- 动态初始化:声明数组时先使用关键字new为数组分配空间,需要用到数组时再初始化。用new分配内存的同时,数组的每个元素都会自动赋默认值,整型为0,实数为0.0,布尔型为false,引用型为null。
// 静态初始化
int[] intArray={1,2,3,4};//定义了一个含有4个元素的int型数组。
//动态初始化
int[] x; //声明名为x的int型数组,未分配内存给数组
x = new int[10]; //x中包含有10个元素,并分配空间
// 或
int[] x = new int[10]; //声明数组并动态分配内存
// 同态分配内存的同时初始化
int[] x=new int[] {1,2,3,4,5,6,7,8,9,10};
数组名不是常量,而是相当于一个指针变量。用户可以改变x的值,让它指向另外一个数组对象,或者不指向任何数组对象(如x=null;
)。数组和对象在没有引用变量指向它时,就会变成垃圾,不被使用,但占内存,在随后不确定的时间会被垃圾回收器自动释放。
Java会自动进行数组下标越界检查,如果下标超出范围,会产生数组下标越界异常。因此,写程序时最好使用数组的length属性获得数组大小。
二维数组
- 二维数组(可看作是由多个一维数组构成),Java的二维数组与C语言的二维数组不同,C语言的二维数组是矩形,即一定被分配了“行x列”个空间,而Java语言的二维数组不一定是矩形。
- 二维数组初始化:数据类型[ ][ ]数组名= new 数据类型 [行数][列数];
- 二维数组申请内存时,必须指定高层维数,即必须指定行数。
- 二维数组赋初值:数据类型[][] 数组名 = {{第1行初值}, …{第n+1行初值}};
- 声明多维数组并初始化时不能指定其长度,否则出错。
// Java二维数组初始化
// 1.分配规则的矩形空间
int[][] x = new int [2][3];
// 2.分配不规则的矩形空间
int[][] x;
x = new int [3][];
x[0]=new int[3];
x[1]=new int[2];
// x[2]对应的行不分配空间,即为null
// 数组的length
x.length; //计算数组x的行数
x[0].length; //计算数组x的第1行元素的个数
x[2].length; //计算数组x的第3行元素的个数
// 二维数组赋初值
int[][] a = {{11,22,33,44}, {66,77,88,99}};
字符串
初始化
Java语言中,字符串常量或变量均用String类实现。
字符串变量的创建:
- 格式一:String 变量名;变量名 = new String(“字符串”);
- 格式二:String 变量名 = new String(“字符串”);
- 格式三:String 变量名 = “字符串”;
格式二与格式三的区别:格式二不管字符串池中是否已经存在相同内容的字符串,都会创建一个新的String
对象;格式三使用字符串字面量,如果字符串池中已经存在该字符串,则会直接引用池中的字符串,否则会在池中创建该字符串。
基本用法
- 字符串数组:初始化需要经过两步空间分配(与二维数组初始化类似)。
// 字符串数组初始化
String[] stringArray;//声明一个String类型的数组
stringArray = new String[3]; //给数组stringArray分配3个应用空间,初始化每个引用值为null
stringArray[0]=new String(“Who”);
stringArray[1]=new String(“are”);
stringArray[2]=new String(“you?”);
- 字符数组:需注意,字符数组不是字符串,但是可以通过调用特定的方法进行转换。字符数组中的每个元素都是字符类型的数据,它的创建方法与一般的数组相似。
char[] str1=new char[3];// 该数组中可以存储3个字符
str1[0] = 'a';
str1[1] = 'b';
str1[2] = 'c';
char[] str2={'a', 'b', 'c ', 'd ', 'e '};// 字符数组初始化
- 字符串与字符数组。字符串和字符数组之间的转换有以下几种形式:使用
toCharArray
方法将字符串转换为字符数组。使用String(char[])
构造方法或valueOf(char[])
方法,将字符数组转换为字符串。
// 字符串转换成字符数组
char[] charArray2="word".toCharArray();
System.out.println(charArray2[1]);
// 字符数组转换成字符串
String str1=new String(new char[]{'w','o','r','d'});
String str2=String.valueOf(new char[]{'w','o','r','l','d'});
System.out.println(str1+str2);
正则表达式
正则表达式常用语法可以参考:正则表达式常用表示
在Java中的应用举例:
import java.util.*;
//...//
String qq1 = "135792468";
String qq2 = "135792468AC";
// 验证QQ号
String regex = "^[1-9][13579]\\d{4,14}$";
boolean flag1 = qq1.matches(regex);
boolean flag2 = qq2.matches(regex);
System.out.println(flag1);
System.out.println(flag2);
相关知识点
Java语言的内存分配
- 栈内存(静态分配空间):存放基本类型的变量和对象的引用变量。内存随着方法的调用而开辟,随着方法调用结束而自动释放。
- 堆内存(动态分配空间):存放由new运算符创建的对象和数组。由Java虚拟机的自动垃圾回收器来管理。
- 静态域:存放在对象中用static定义的静态成员。
- 常量池:用于存储编译期常量和一些符号引用的区域。
- 引用变量:为数组或对象起的一个名字。在堆中创建一个数组或对象后,在栈中定义一个引用变量存放该数组或对象在堆内存中的首地址(对象的句柄),以后就可在程序中使用栈的引用变量来访问堆中的数组或对象。
Java的增强for循环
增强for循环也叫for each循环。优点是不用下标就可遍历整个数组,但需提供元素类型、变量的名字(用于存放数组元素)和数组名。
// for each循环举例
int[] arr={1,2,3,4,5};
for (int element : arr)
{
System.out.print(element+" ");
}
类和对象
基本概念
面向对象技术的基本特征:
- 封装性。封装就是把对象的属性和行为结合成一个独立的单位,并尽可能对外隐蔽对象的内部细节。只保留有限的接口与外界联系。
- 继承性。继承是一种联结类与类的层次模型。继承性是指子类对象自动拥有其父类的属性和行为。同时可以增添自身的属性和方法。
- 多态性。多态性是指“一个接口,多种实现”。一个程序中可以有同名的多个不同方法共存。常用重载和覆盖。
对象的概念:对象都是由属性(Attribute)和行为(Action)两部分组成。对象是属性和行为的封装体。 - 属性:用来描述对象静态特征的一个数据项。
- 行为:用来描述对象动态特征的一个操作。
类的概念:类(Class)是具有相同属性和行为的一组对象集合的再抽象。类为属于它的全部对象提供了统一的抽象描述。
对象是类的实例。
定义与创建
类的定义:数据表示存储在每个对象里的值,而方法则表示对象可以提供的功能。数据和方法统称为类的成员。
class 类名 // 类说明
{ // 花括号中为类体部分
//<类的数据>
//<类的方法>
}
// 定义People类
class People
{
// 类变量
int age; // 年龄
String name; // 内容
// 类方法
int aged()
{
// 方法内容
}
}
对象的创建:创建对象必须使用操作符new,其格式可以有两种。
类名 对象名;
对象名=new 类名(参数1,参数2,…);
// 或者
类名 对象名=new 类名(参数1,参数2,…);
new
关键字的作用:
- 为对象分配内存空间。
- 自动调用类的构造方法,以实现对象的初始化。若未定义构造方法,则系统会提供一个缺省的无参构造方法,该方法用默认值初始化成员变量。
- 为对象返回一个引用,即对象名。
成员变量访问权限符:
- public:用该public修饰的成员变量称为公共变量,可以被程序中任何类访问。
- protected:用protected修饰的成员变量可以被本类、本包、以及子类(不管是否在同一包中)访问。
- private:用private修饰的成员变量只能被本类访问。用private修饰成员变量可以实现数据隐藏机制。
- default:如果没有修饰符,它的访问权限就是默认的,默认为“本包”。表示它可以被本类及同一包中的其他类访问。
成员变量与局部变量的区别:
- 成员变量属于类,而局部变量是方法中定义的变量或方法的参数。
- 成员变量可以被public、private和static等修饰,而局部变量则不能,二者都可以被final修饰。
- 成员变量是对象的一部分,对象是存储在堆内存的,局部变量存于栈。
- 成员变量是对象的一部分,它随着对象的创建而存在;局部变量随着方法的调用而产生,随着方法调用的结束而消失。
- 成员变量若没有被赋初值,则自动初始化默认为0,局部变量不会自动赋初值,必须显式赋值。
成员方法的修饰符:public
、private
、protected
、 friendly
、 final
、static
、abstract
、synchronized
、native
。方法可以是有返回值也可以无返回值(void,主体中不用return语句)。方法调用的格式:对象名.方法名(实参列表)
类修饰符:
- public:说明该类为公共类,它可以被本类和其他任何类访问。Java源文件中至多有一个类是public类。
- default:如果类名前不加修饰符,即默认访问权限,默认为“本包”。能被本类和同一个包中的任何其他类访问。
- abstract:用abstract修饰的类称为抽象类。它是一种没有具体对象的概念类,是它所有公共子类的公共属性集合。
- final:用该修饰符修饰的类不能有子类,称为最终类。
构造方法:
- 构造方法的名字必须和类名相同,并且没有返回值。
- 必须通过new关键字来自动调用,从而创建类的实例。
- Java的类都要求有构造方法,如果没有定义构造方法,Java编译器会为我们提供一个缺省的构造方法,也就是不带参数的构造方法。
class Example {
int value;
// 自定义构造方法
pbulic Example(int value) {
this.value = value;
}
}
Example obj = new Example(10); // 调用自定义构造方法
静态成员:
- 用static修饰的成员变量称为“静态变量”,也称为类变量。
- 静态成员可以实现同一个类的不同对象之间的数据和方法共享。
- 静态成员仅有一个副本,使用同一块内存空间。为类的所有对象共享。
- 当程序一开始运行,静态变量和静态方法就被分配了内存空间,所以可以在未创建对象时直接通过类名引用它们。
- 在静态方法中不能直接调用非静态的方法,不能直接引用非静态的成员变量,只能通过对象来引用。反之,则可以。
应用
- 对象的赋值与比较。当对象被赋值时(如volu2=volu1),复制的是对象的首地址。
- 对象数组。
Person[] per; //定义一个Person类型的数组
per = new Person[3]; //给数组分配3个应用空间,初始化每个引用值为null
per[0]=new Person(“张三”,20);
per[1]=new Person(“李四”,21);
per[2]=new Person(“王二”,19);
- 八种基本数据类型与其对应包装类:
byte
-Byte
short
-Short
int
-Integer
long
-Long
float
-Float
double
-Double
char
-Character
boolean
-Boolean
- 八种基本数据类型与其对应包装类之间的自动转换:基本类型转换为包装类的过程称为“装箱”,包装类转换为基本类型的过程称为“拆箱”。从Java SE5开始,提供了自动装箱和拆箱功能。
Integer i = 10;// 系统自动调用Integer.valueOf()方法来进行装箱
int n = i;// 系统自动调用Integer.intValue()方法进行拆箱
- 匿名对象:没有对象名来调用成员方法,直接使用类名来调用成员方法。
// 创建对象,通过对象调用方法
Cylinder volu=new Cylinder();
volu.SetCylinder(2.5, 5,3.14);
// 通过匿名对象调用方法
new Cylinder().SetCylinder(2.5, 5,3.14);
- Java语言的垃圾回收
- 只有当一个对象不被任何引用变量使用时,它的内存才可能被垃圾回收器回收;
- 不能通过程序强迫回收器立即执行;
- 当垃圾回收器将要释放无用对象的内存时,先调用该对象的finalize()方法。