1.数组的初始化方式有哪些?
Java语言中数组必须先初始化,然后才可以使用。所谓初始化就是为数组的数组元素分配内存空间,并为每个数组元素附初始值。
初始化方式共有三种。
第一种:静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组的长度。
arrayName = new type[]{element1,element2,element3…}
int[] intArr = new int[]{1,2,3,4,5};
第二种:简化的静态初始化方式。
type[] arrayName = {element1,element2,element3…}
String[] strArr = {"张三", "李四", "王五"...};
第三种:动态初始化:初始化由程序员指定数组的长度,由系统初始化每个数组元素的默认值。
arrayName = new type[length];
int[] price = new int[4];
注意:不要同时使用静态初始化和动态初始化,也就是说,不要在进行数组初始化时,既指定数组的长度,也为每个数组元素分配初始值。
一旦数组完成初始化,数组在内存中所占的空间将被固定下来,所以数组的长度将不可变。
2.二维数组怎么写?
参考链接:https://www.cnblogs.com/bfcs/p/10315057.html
1.二维数组:二维数组就是存储一维数组(内存地址/引用)的数组
2.二维数组的初始化
(1) int intA[][] = {{1,2},{2,3},{3,4,5}};
(2) int[][] intB = new int[3][5];
(3) int[] intC[] = new int[3][];
intC[0] = new int[2];
intC[1] = new int[3];
intC[2] = new int[5];
public class TestArray {
public static void main(String[] args){
//二维数组不是规则的矩阵
int[] intA[] = {{1,2},{2,3,4},{3,4,5,6}};
System.out.println(intA); //[[I@1b6d3586
//声明一个二维数组,用于存储3个一维数组,每一个一维数组存多少个数组,不知道null
int[][] intB = new int[3][];
intB[0] = new int[3];
intB[1] = new int[]{1,2,3,4};
intB[2] = new int[2];
System.out.println(intB[1]); //[I@4554617c
System.out.println(intB[1][1]); //2
//声明一个二维数组,同时创建出一维数组,每个一维数组的长度均相同
//存储三个一维数组,每个一维数组的长度为4
int[] intC[] = new int[3][4];
System.out.println(intC); //[[I@74a14482
}
}
3.二维数组的遍历
(1)普通for循环
(2)加强for循环
(3)普通for循环+加强for循环
public class TestArray1 {
public static void main(String[] args){
//二维数组
int[] intA[] = {{1,2},{2,3,4},{3,4,5,6}};
//(1)普通for循环
for (int i=0;i<intA.length;i++){
for (int j=0;j<intA[i].length;j++){
System.out.print(intA[i][j] + "\t");
}
System.out.println();
}
System.out.println("————————————————————");
//(2)加强for循环
//int[]二维数组中元素的类型,arr迭代变量,intA二维数组的名称
for (int[] arr : intA){
for (int i : arr){
System.out.print(i + "\t");
}
System.out.println();
}
System.out.println("————————————————————");
//(3)普通与加强for循环的混搭
//加强for
for (int[] arr : intA){
for (int i=0;i<arr.length;i++){
System.out.print(arr[i] + "\t");
}
System.out.println();
}
System.out.println("————————————————————");
for (int i=0;i<intA.length;i++){
for(int j:intA[i]){
System.out.print(j + "\t");
}
System.out.println();
}
}
}
4.对象数组存储表格数据
姓名 | 年龄 | 性别 |
---|---|---|
张三 | 19 | 男 |
李四 | 20 | 男 |
王五 | 21 | 女 |
数组存基本数据类型,也可以存引用数据类型
对象数组:使用数组存储对象(自定义对象)
public class Person {
private String name;//姓名
private int age;//年龄
private String gender;//性别
//重写toString以打印想要的输出 否则只会打印对象的内存地址
@Override
public String toString() {
// TODO Auto-generated method stub
return name + "\t" + age + "\t" + gender;//
}
public Person(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public Person() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
public class TestArray2 {
public static void main(String[] args){
//创建一个Person类型的数组,用于存储3个Person类型的对象
Person[] pers = new Person[3];
//创建Person类型的对象
Person p1 = new Person("zs",19,"男");
//将p1对象存储到Person类型的数组中
pers[0] = p1;
pers[1] = new Person("ls",20,"男");
pers[2] = new Person("ww",21,"女");
for (int i=0;i<pers.length;i++){
System.out.println(pers[i]);
}
//对象数组中存储的是对象的引用(内存地址)
}
}
5.数组拷贝
地址的拷贝
int[] array = {11,22,33,44};
int[] arrayB = new int[5];
arrayB = array; //两个数组指向同一内存
值拷贝
int[] array = {11,22,33,44};
int[] arrayB = new int[5];
arrayB[0] = array[0];
System类的arraycopy()方法:快速,数组大时用此方法
public class TestArrayCopy3 {
public static void main(String[] args){
int[] arrA = {11,22,33,44}; //源数组
int[] arrB = new int[5]; //目标数组
System.out.println("数组拷贝前:");
for (int num : arrB){
System.out.print(num + "\t");
}
//拷贝
System.out.println();
System.arraycopy(arrA,0, arrB,1,2);
System.out.println("数组拷贝后:");
for (int num : arrB){
System.out.print(num + "\t");
}
}
}
附上该方法参数解释:https://blog.csdn.net/qq_39597203/article/details/79452872
3.把数组当成方法参数又该怎么处理?
public class TestArray3 {
public static void array(int[] arrayA){
arrayA[0] = 0;
}
public static void main(String[] args){
int[] arrayA = new int[]{1,2,3,4};
//传递的是地址值
array(arrayA);
System.out.printf("%d", arrayA[0]);
}
}
在程序中,调用方法并且把数组的名称作为参数传递到方法中,本质上是传递数组的地址值。
既然传递的是数组的地址,那么方法就可以通过数组的地址改变内存中数组的效果。类似于C语言中调用函数传递数组的指针一样,可以在函数中通过指针改变数组的内容;所以在Java中,数组为引用类型,可以把数组作为参数传递到方法中去改变数组。
4.Java中,声明一个数组的过程,是如何分配内存的?
1.当声明数组类型变量时,为其分配了(32位)引用空间,由于未赋值,因此并不执行任何对象。
2.当创建了一个数组对象(new出来的)并将其地址赋值给变量,其中创建出来的那几个数组元素相当于引用类型变量,因此各自占用(32位的)引用空间并按其默认初始化规则被赋值为null
3.程序继续运行,当创建新的对象并(按其地址)赋值给各数组元素,此时堆内存就会有值了。
5.Java变量一定要初始化吗?
不一定,Java数组变量是引用数据类型变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,即可使用该数组变量。对数组进行初始化,并不是对数组变量进行初始化,而是对数组对象进行初始化——也就是为该数组对象分配一块连续的内存空间,这块连续的内存空间就是数组的长度。
6.基本类型变量都放在栈内存中?
错。应该这样说:所有局部变量都放在栈内存中保存的,不管其是基本类型的变量,还是引用类型的变量,都是存储在各自的方法栈区中;但是引用类型变量所引用的对象(包括数组、普通Java对象)则总是存储在堆内存中。
7.引用变量何时只是栈内存中的变量本身,何时又变为引用实例的Java对象。
引用变量本质上只是一个指针,只要程序通过引用变量访问属性,或者通过引用变量来调用方法,该引用变量将会由他所引用的对象代替。