目录
1.数组
一组相关类型的变量集合
- 缺点:长度固定,存在越界问题
2.数组初始化
-
2.1 动态初始化(声明并开辟数组)
数据类型[] 数组名称 = new 数据类型 [长度] ;
- 数组下标(从0开始)超出数组长度,数组越界异常(运行时异常)
- 数组中每个元素都有默认值,默认值是该数据类型默认值
- 数组名称.length(属性):取得数组长度
- 数组的默认值:
/**
* 数组动态初始化
* Author: qqy
*/
public class Test {
public static void main(String[] args) {
//基本类型实例化后,在该内存空间的值就是默认值
int[] data = new int[5];
print(data);
//编译通过,运行发生空指针异常——NPE
int[] b=null;
print(b);
//引用类型默认值为null
String[] a=new String[9];
print(a);
}
public static void print(String[] i){
//i.length——length是属性
for(int j=0;j<i.length;j++){
System.out.println(i[j]);
}
}
}
-
2.2 引用传递的内存分析
同一块堆内存空间可以被不同的栈内存所指向
- 2.2.1 数组的空间开辟
public class Test1 {
public static void main(String[] args) {
int[] x = null;
x = new int[3];
x[0] = 10;
x[1] = 20;
x[2] = 30;
x = null;
}
}
-
2.2.2 引用传递
public class Test1 {
public static void main(String[] args) {
int[] x = null;
x = new int[3];
x[0] = 10;
x[1] = 20;
x[2] = 30;
//引用传递
int[] y=x;
y[1]=25;
}
}
-
2.3 静态初始化(开辟同时赋值)
//简化格式
数据类型[] 数组名称 = {值,值,....}
//完整格式
数据类型[] 数组名称 = new 数据类型[] {值,值,....}
- 匿名数组:在栈内存中没有任何引用,只在堆内存开辟空间,存放数据
public class ArrayTest{
public static void main(String [] args){
System.out.println(new int[]{1,2,3}.length);
}
练习(数组的拼接):
public class ArrayTest {
public static void main(String[] args) {
int[] a = new int[]{1, 2, 3};
int[] b = new int[]{4, 5, 6, 7, 8};
//动态初始化
int[] c = new int[a.length + b.length];
for (int i = 0; i < a.length; i++) {
c[i] = a[i];
}
for (int i = a.length; i < c.length; i++) {
c[i] = b[i - a.length];
}
for (int i = 0; i < c.length; i++) {
System.out.print(c[i] + " ");
}
}
}
3.二维数组
数组的数组
- 二维数组中,a.length表示行数,a[i].length表示第i行的列数
- 动态初始化时,多维数组的行数不可省略,列数可省略
/**
* 二维数组动态初始化
* Author: qqy
*/
public class Test3{
public static void main(String[] args) {
int[][] arr=new int[3][]; //-> arr=int[3][]{null,null,null}
//如果没有下面三行,则会出现空指针异常
arr[0]=new int[6]; //int[6]={0,0,0,0,0,0} -> arr=int[3][]{int[6]{0,0,0,0,0,0},null,null}
arr[1]=new int[6];
arr[2]=new int[6];
arr[0][1]=2; //arr=int[3][]{int[6]{0,2,0,0,0,0},null,null} (假设没有第12.13行)
arr[1][3]=5;
arr[2][5]=8;
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
- 动态初始化:
public class ArrayTest {
public static void main(String[] args) {
//动态初始化
int[][] a = new int[2][3];
a[0][0] = 2;
a[1][2] = 5;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.print(a[i][j] + "\t");
}
System.out.println();
}
}
}
- 静态初始化:
public class ArrayTest {
public static void main(String[] args) {
int[][] a = new int[][]{{1, 2}, {3, 5, 6, 4, 1}, {8, 9, 7}};
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.print(a[i][j] + "\t");
}
System.out.println();
}
}
}
疑问:
为什么动态初始化会出现默认值0,而静态初始化不会???
解答:
动态初始化:建立相应的空间,并附上默认值,再赋值时,是将默认值更改为新赋的值。
静态初始化:建立空间同时赋值,赋多少值,开辟多少空间。
4.数组与方法互操作
给一个方法中传入数组类型,在引用传递的情况下,如果新数组对值进行改变,则原数组的值也随之改变。
- 扩展数组值:
public class ArrayExpend {
public static void main(String[] args) {
int[] a = new int[]{1, 2, 3, 4};
System.out.println("数组a:");
arrayPrint(a);
int[] result1 = arrayExpend(a);
System.out.println("扩展结果:");
arrayPrint(result1);
System.out.println("after数组a:");
arrayPrint(a);
int[] result2 = arrayExpend2(a);
System.out.println("扩展结果:");
arrayPrint(result2);
System.out.println("after数组a:");
arrayPrint(a);
}
public static int[] arrayExpend(int[] a) {
if (a == null) {
return new int[]{};
}
//数组引用传递
int[] temp = a;
for (int i = 0; i < a.length; i++) {
temp[i] = temp[i] * 5;
}
return temp;
}
public static int[] arrayExpend2(int[] a) {
if (a == null) {
return new int[]{};
}
//空间重新分配
int[] temp = new int[a.length];
for (int i = 0; i < a.length; i++) {
temp[i] = a[i] * 4;
}
return temp;
}
public static void arrayPrint(int[] c) {
if (c == null) {
return;
}
for (int j = 0; j < c.length; j++) {
System.out.print(c[j] + " ");
}
System.out.println();
}
}
5.Java对数组的支持
-
5.1 排序:
- 数字升序排序
java.util.Arrays.sort(arrayName) ;
import java.util.Arrays;
public class ArrayUtil {
public static void main(String[] args) {
int[] a = new int[]{1, 33, 5, 44, 76};//1,5,33,44,76
System.out.println("排序之前:");
arrayPrint(a);
Arrays.sort(a);
System.out.println("排序之后:");
//改变原数组
arrayPrint(a);
}
public static void arrayPrint(int[] c) {
if (c == null) {
return;
}
for (int j = 0; j < c.length; j++) {
System.out.print(c[j] + " ");
}
System.out.println();
}
}
-
5.2 拷贝
方法一:将指定源数组中的数组从指定位置复制到目标数组的指定位置。
java.lang.System.arraycopy(Object src,int srcPos,Object dest, int destPos,int length);
public class ArrayUtil {
//拷贝
public static void main(String[] args) {
int[] src = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
int[] dest = new int[3];
arrayPrint(src);
arrayPrint(dest);
//方法一
// for(int i=2;i<5;i++){
// dest[i-2]=src[i];
// }
//方法二
System.arraycopy(src, 2, dest, 0, 3);
arrayPrint(src);
arrayPrint(dest);
}
public static void arrayPrint(int[] c) {
if (c == null) {
return;
}
for (int j = 0; j < c.length; j++) {
System.out.print(c[j] + " ");
}
System.out.println();
}
}
方法二:复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度。
java.util.Arrays.copyOf(源数组名称,新数组长度)
import java.util.Arrays;
public class ArrayUtil {
public static void main(String[] args) {
int[] src = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
arrayPrint(src);
int[] dest1 = Arrays.copyOf(src, 7);
//Arrays.copyOf不改变原数组
arrayPrint(src);
arrayPrint(dest1);
int[] dest2 = Arrays.copyOf(src, 10);
arrayPrint(dest2);
}
public static void arrayPrint(int[] c) {
if (c == null) {
return;
}
for (int j = 0; j < c.length; j++) {
System.out.print(c[j] + " ");
}
System.out.println();
}
}
6.对象数组
对象数组往往是以引用数据类型为主的定义,例如:类、接口。
存放引用数据类型——通过类来创建的对象
-
6.1初始化
//动态初始化
类名称[] 对象数组名称 = new 类名称[长度];
//静态初始化
类名称[] 对象数组名称 = new 类名称[] {};
public class ArrayOfObjects {
//类方法
public static void printArray(Person[] persons) {
for (int i = 0; i < persons.length; i++) {
System.out.println(persons[i]);
}
}
public static void main(String[] args) {
Person person = new Person(1, "唐僧");//email=null; phone=null;
System.out.println(person);//person.toString(); ——继承自Object
String s = "Bonjour"; //引用类型
System.out.println(s); //s.toString(); ——继承
//动态初始化
Person[] persons = new Person[3];
persons[0] = new Person(1, "Jack");
persons[1] = new Person(2, "Tom", "tom@gmail.com");
persons[2] = new Person(3, "Alice", "alice@gmail.com", "15265478955");
ArrayOfObjects.printArray(persons);
//静态初始化
Person[] persons2 = new Person[]{
new Person(4, "Tony")
};
ArrayOfObjects.printArray(persons2);
}
}
class Person {
private int id;
private String name;
private String email;
private String phone;
//构造方法
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public Person(int id, String name, String email) {
this(id, name);
this.email = email;
}
public Person(int id, String name, String email, String phone) {
this(id, name, email);
this.phone = phone;
}
//getter方法
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getEmail() {
return this.email;
}
public String getPhone() {
return this.phone;
}
//setter方法
public void setEmail(String email) {
this.email = email;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String toString() {
return " 编号:" + this.id + " 姓名:" + this.name + " 邮箱:" + this.email + " 电话:" + this.phone;
}
}