从0开始学Java(008)_数组的定义及使用

数组的定义及使用

基本概念

1.数组是引用数据类型,是一组相同类型数据的集合。
2.数组的定义语法
(1)声明并开辟数组: 数组类型 数组名[] = new 数据类型[数组长度]
(2)分步完成:

// 声明数组
数组类型 数组名[] = null;
// 开辟数组
数组名 = new 数据类型 [数组长度]
  • 数组开辟空间,在未进行赋值的情况下,每个元素的值为该元素数据类型的默认值。
  • 数组中的元素通过数组名[索引]访问,索引从0开始。即长度为3的数组,索引值为0,1,2。索引超出范围,会出现数组越界异常。(ArrayIndexOutOfBoundsException)。
  • 数组是顺序结构且长度固定,可利用循环语句输出,可通过数组名.length获取数组长度。
public class Demo {
    public static void main(String[] args) {
        int datas[] = new int[3]; // 声明并开辟一个长度为3的数组
        datas[0] = 1; // 为数组赋值,如不赋值,默认值为0
        datas[1] = 2;
        datas[2] = 3;
        // for循环输出数组内容,datas.length获取数组长度
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]);
        }
    }
}

数组的引用传递分析

1.数组是引用数据类型,因此要进行内存分配。与对象保存的区别在于对象的堆内存保存属性,数组的堆内存保存数据(元素)。
在这里插入图片描述
范例:分步完成

public class Demo {
    public static void main(String[] args) {
        int datas[] = null; // 声明数组
        datas = new int[3]; // 开辟一个长度为3的数组
        datas[0] = 1;
        datas[1] = 2;
        datas[2] = 3;
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]);
        }
    }
}

在这里插入图片描述
2.数组可以进行引用传递。

public class Demo {
    public static void main(String[] args) {
        int datas[] = new int[3];
        datas[0] = 1;
        datas[1] = 2;
        datas[2] = 3;
        int temp[] = datas; // 引用传递
        temp[0] = 99;
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]); // 99 2 3
        }
    }
}

在这里插入图片描述
以上都是动态初始化数组,即先开辟数组,再为数组赋值。
3.静态初始化数组:
在定义数组的同时为其赋值,语法:
(1)数组类型 数组名[] = {v1, v2 ,…,vn};
(2)数组类型 数组名[] = new 数据类型[] {v1, v2 ,…,vn};
范例:静态初始化数组

public class Demo {
    public static void main(String[] args) {
        int datas[] = new int[]{1, 2, 3}; // 静态初始化数组
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]);
        }
    }
}

数组支持顺序数据访问,最大缺点是长度不能改变,因此在开发中不直接使用数组,但会使用数组的概念。

使用foreach输出数组

JDK1.5之后引入了一个增量型的for循环(foreach),利用foreach的语法结构可以直接自动获取数组中的每个元素。
语法:for ( 数据类型 变量 : 数组 | 集合) {代码块}

public class Demo {
    public static void main(String args[]) {
        int[] datas = new int[]{1, 2, 3, 4, 5};
        for (int data : datas) {
            System.out.println(data);
        }
    }
}

二维数组

1.一维数组就是一行数据:

索引0123
数据0102030

在一维数组中要查询一个数据,只要确定其索引即可。
二维数组,是一个数据表:

索引0123
00102030
11234
212123231233

二维数组中要查询一个数据,需要定位列和行。二维数组中第一个[]确定行,第二个[]确定列。
2. 二维数组定义语法:

// 动态初始化:
数据类型 数组名称[][]=new 数据类型[行数][列数];
// 静态初始化:
数据类型 数组名称[][]=new 数据类型[][]{数组元素} ;

由此可以发现,二维数组就是将多个一维数组变为一个数组。

public class Demo {
    public static void main(String[] args) {
        int datas[][] = new int[][]{
        	{1, 2, 3}, 
        	{4, 5, 6}, 
        	{7, 8, 9}
        }; 
        // 外层循环控制数组的行
        for (int x = 0; x < datas.length; x++) {
            // 内层循环控制数组的列
            for (int y = 0; y < datas[x].length ; y++) {
                System.out.print(datas[x][y] + "\t");
            }
            System.out.println();
        }
    }
}

数组与方法

1.方法的参数可以是数组:

public class Demo {
    public static void main(String[] args) {
        int datas[] = new int[]{1, 2, 3};
        change(datas);
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]);
        }
    }

    public static void change(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            temp[x] *= 2; // 数组元素乘2保存
        }
    }
}

2.方法返回数组:

public class Demo {
    public static void main(String[] args) {
        int data[] = init(); // 接收数组
        print(data);
        System.out.println(init().length);
    }

    public static int[] init() {
        return new int[]{1, 2, 3}; // 方法返回数组
    }

    public static void print(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            System.out.print(temp[x] + "、");
        }
        System.out.println();
    }
}

数组排序

冒泡排序
数据的不同会造成排序次数的不同,但不论有多少数据,总的排序次数不会超过数组长度平方,只要排序次数达到数组长度的平方,就能排序成功。

public class ArrayDemo {
    public static void main(String[] args) {
        int datas[] = new int[]{2, 1, 9, 0, 5, 7, 6, 8};
        for (int x = 0; x < datas.length; x++) {
            for (int y = 0; y < datas.length - 1; y++) {
                if (datas[y] > datas[x]) {
                    int t = datas[y];
                    datas[y] = datas[x];
                    datas[x] = t;
                }
            }
            // 为更好地理解冒泡排序,输出每轮排序的结果
            System.out.print("第" + (x + 1) + "次排序结果:");
            print(datas);
            System.out.println();
        }
        print(datas);
    }
    // 数组输出的方法
    public static void print(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            System.out.print(temp[x] + " ");
        }
    }
}

建议main()是程序的起点,可以称为客户端。客户端的代码逻辑应简单,因此可将排序封装为方法。

public class ArrayDemo {
    public static void main(String[] args) {
        int datas[] = new int[]{2, 1, 9, 0, 5, 7, 6, 8};
        sort(datas);
        print(datas);
    }

    // 数组冒泡排序方法
    public static void sort(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            for (int y = 0; y < temp.length - 1; y++) {
                if (temp[y] > temp[x]) {
                    int t = temp[y];
                    temp[y] = temp[x];
                    temp[x] = t;
                }
            }
        }
    }

    // 数组输出的方法
    public static void print(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            System.out.print(temp[x] + " ");
        }
    }
}

数组转置

转置的概念(一维数组):·

原始数组1,2,3,4,5,6,7,8
转置后8,7,6,5,4,3,2,1

转置操作的两个思路:
(1)定义一个新的数组,而后将原始数组按照倒序的方式插入到新的数组之中,随后改变原始数组的引用:

 public class ArrayDemo {
    public static void main(String[] args) {
        int datas[] = new int[]{1,2,3,4,5,6,7,8};
        datas = reverseOne(datas); // 让datas指向新数组,原始数据成为垃圾
    }
    // 数组逆序输出方法一
    public static int [] reverseOne(int temp[]) {
        // 定义新数组,长度与原始数组一致
        int temps[] = new int[temp.length];
        int foot = temp.length - 1; // 控制原始数组的索引
        for (int x = 0; x < temps.length ; x++) {
            temps[x] = temp[foot]; // 新数组按照原始数组倒序排列
            foot --;
        }
        return temps;
    }
}

上述代码实现转置,但产生了垃圾,不合理。
(2)利用算法,直接在数组上完成转置:
不论数组个数是奇数还是偶数,转换次数 = 数组长度 / 2;

// 数组逆序输出方法
public static void reverse(int temp[]) {
    int len = temp.length / 2;
    int head = 0;
    int tail = temp.length - 1;
    for (int x = 0; x < len; x++) {
        int t = temp[head];
        temp[head] = temp[tail];
        temp[tail] = t;
        head++;
        tail--;
    }
}

行列数相等的二维数组转置:

public class Demo {
    public static void main(String[] args) {
        int data[][] = new int[][]{
        	{1, 2, 3}, 
        	{4, 5, 6}, 
        	{7, 8, 9}
        };
        reverse(data);
        print(data);
    }

    // 专门实现数组的倒置操作
    public static void reverse(int arr[][]) {
        for (int x = 0; x < arr.length; x++) {
            for (int y = x; y < arr.length; y++) {
                if (x != y) { //行和列相同,进行交换
                    int temp = arr[x][y];
                    arr[x][y] = arr[y][x];
                    arr[y][x] = temp;
                }
            }
        }
    }

    // 专门输出的方法
    public static void print(int temp[][]) {
        for (int x = 0; x < temp.length; x++) {
            for (int y = 0; y < temp[x].length; y++) {
                System.out.print(temp[x][y] + "、");
            }
            System.out.println();
        }
        System.out.println();
    }

}

转置过程

1[0][0]  2[0][1]  3[0][2]
4[1][0]  5[1][1]  6[1][2]
7[2][0]  8[2][1]  9[2][2]
第一次转换(x=0,y=x=0,循环3次)
 ·y的第一次循环(x==y)
  1[0][0]  2[0][1]  3[0][2]
  4[1][0]  5[1][1]  6[1][2]
  7[2][0]  8[2][1]  9[2][2]
 ·y的第二次循环(x=0,y=1,进行交换)
  1[0][0]  4[1][0]  3[0][2]
  2[0][1]  5[1][1]  6[1][2]
  7[2][0]  8[2][1]  9[2][2]
 ·y的第三次循环(x=0,y=2,进行交换)
  1[0][0]  4[1][0]  7[2][0]
  2[0][1]  5[1][1]  6[1][2]
  3[0][2]  8[2][1]  9[2][2]
第二次转换(x=1,y=x=1,循环2次)
 ·y的第一次循环(x=1,y=1,不交换)
  1[0][0]  4[1][0]  7[2][0]
  2[0][1]  5[1][1]  6[1][2]
  3[0][2]  8[2][1]  9[2][2]
 ·y的第二次循环(x=1,y=2,进行交换)
  1[0][0]  4[1][0]  7[2][0]
  2[0][1]  5[1][1]  8[2][1]
  3[0][2]  6[1][2]  9[2][2]
第三次转换(x=2,y=x=2,循环11次)
 ·y的第二次循环(x=2,y=2,不交换)
  1[0][0]  4[1][0]  7[2][0]
  2[0][1]  5[1][1]  8[2][1]
  3[0][2]  6[1][2]  9[2][2]

行列数不同的数组进行倒置,其思路是:数组的行数是原数组的列数,数组的列数是源数组的行数。需要改变原始数组的引用,会产生垃圾。

数组相关的类库

Java对数组提供类库支持,下面介绍两个类库中的方法:

  • 数组拷贝:用一个数组的指定内容覆盖另一个数组指定内容。
    语法:System.arraycopy(源数组名,源数组拷贝开始索引,目标数组名,目标数组开始拷贝索引,拷贝长度)
    范例:数组拷贝
    ·数组A:1,2,3,4,5,6,7,8;
    ·数组B:11,22,33,44,55,66,77,88;
    ·拷贝后的数组B:11,22,5,6,7,66,77,88
 public class Demo {
    public static void main(String[] args) {
        int dataA[] = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
        int dataB[] = new int[]{11, 22, 33, 44, 55, 66, 77, 88};
        System.arraycopy(dataA, 4, dataB, 2, 3);
        ArrayDemo.print(dataB); // 调用之前代码中的数组输出方法
    }
}
  • 数组排序:
    语法:java.util.Arrays.sort(数组名)
public class Demo {
    public static void main(String[] args) {
        int dataA[] = new int[]{3, 2, 1, 4, 7, 0, 6, 5};
        java.util.Arrays.sort(dataA);
        ArrayDemo.print(dataA); // 调用之前代码中的数组输出方法
    }
}

方法可变参数

要求:定义一个方法,可以接收多个整型数据的相加。
范例:用数组解决该问题

public class Demo {
    public static void main(String[] args) {
        System.out.println(add(new int[]{1, 2, 3}));
        System.out.println(add(new int[]{1, 2}));
    }
    
    // 实现任意多个整型数据的相加
    // 因为有多个数据,所以用数组接收
    // return 累加的结果
    public static int add(int[] data) {
        int sum = 0;
        for (int x = 0; x < data.length; x++) {
            sum += data[x];
        }
        return sum;
    }
}

使用数组是因为JDK1.5之前传入方法的参数个数是固定的,无法接收随机个参数。但通过数组接收参数不符合预期,理想的调用形式:add(1,2,3),add(10,20);
该功能从JDK1.5后可以实现,它主要是在方法上使用,定义形式:

[public | protected | private] [static] [final] [abstract] 返回值类型 方法名称(数据类型 ... 变量){
    [return [返回值] ;]
}

上述代码中,[]中的内容可以忽略。上述形式中的参数不再是一个内容,而是多个内容,尽管参数的定义形式变了,但是参数的访问却没变,即进行参数访问的时候按照数组的形式操作。

public class Demo {
    public static void main (String [] args){
        // 可变参数支持数组
        System.out.println(add(new int[] {1,2,3}));// 传递3个整型数据
        // 可变参数支持参数
        System.out.println(add(1,2,3));// 传递3个整型数据
        System.out.println(add(10,20));// 传递2个整型数据
        System.out.println(add());// 不传递数据
    }
    
    //        实现任意多个整型数据的相加操作
    //        由于要接收多个整型数据,所以要用数组完成接收
    //        return 多个整型数据的累加结果
    public static int add(int ... data){
        int sum = 0 ;
        for (int x = 0 ; x < data.length ; x ++){
            sum += data[x] ;
        }
        return sum;
    }
}

在大部分开发中,参数的个数应该是固定,因此可变参数多用于一些程序相关系统类的设计使用上,而不是开发中。可变参数属于数组的变形应用。

对象数组

1.对象数组是将多个对象交由数组处理。
2.对象数组的定义与一般数组一致:
范例: 动态初始化对象数组

class Book {
    private String title;
    private double price;

    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

    // setter和getter方法略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    }
}

public class Demo {
    public static void main(String[] args) {
        Book books[] = new Book[3];
        books[0] = new Book("Java开发", 66.6);
        books[1] = new Book("JSP", 6.6);
        books[2] = new Book("C++", 16.6);
        for (int x = 0; x < books.length; x++) {
            System.out.println(books[x].getInfo()); 
//未实例化对象时,输出值全为null
        }
    }  
}

范例:静态初始化对象数组:

class Book {
    private String title;
    private double price;

    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

    // setter和getter方法略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    }
}

public class Demo {
    public static void main(String[] args) {
        Book books[] = new Book[]{
                new Book("Java开发", 66.6),
                new Book("JSP", 6.6),
                new Book("C++", 16.6)
        };
        for (int x = 0; x < books.length; x++) {
            //未实例化对象时,输出值全为null
            System.out.println(books[x].getInfo()); 
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值