Java中的数组

一、介绍

数组可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。即:数(数据)组(一组)就是一组数据。

二、例子

package com.hspedu;

public class hen {

    public static void main(String[] args) {
        //1.double[]表示是double类型的数组,数组名是hens
        //2.{3, 5, 1, 3.4, 2, 50}表示数组的值/元素,以此表示数组的第几个元素
        double[] hens = {3, 5, 1, 3.4, 2, 50};

        //数组可以通过for循环遍历。
        //遍历得到数组的所有元素的和,使用for循环
        for (int i = 0; i < 6; i++){
            //因为数组是0基的
            System.out.println("第" + (i+1) + "个元素的值=" + hens[i]);
        }
        //hens.length返回数组的长度
        System.out.println("数组的长度是 " + hens.length);
    }
}

三、数组的三种使用方式

1、动态初始化1

下面是动态初始化的例子:

import java.util.Scanner;

public class array {
    public static void main(String[] args) {

        //第一种动态分配方式
        double[] scores = new double[5];
        Scanner scanner = new Scanner(System.in);
        //遍历输入数组元素
        for (int i = 0; i < scores.length; i++){
            System.out.println("请输入第" + (i+1) + "个元素的值");
            scores[i] = scanner.nextDouble();
        }
        //输出遍历数组
        System.out.println("数组的元素情况如下");
        for (int i = 0; i <scores.length; i++){
            System.out.println("第" + (i+1) + "个元素的值=" + scores[i]);
        }
    }
}

2、动态初始化2 

import java.util.Scanner;

public class array {
    public static void main(String[] args) {

        //第二种动态分配方式,先声明,再new 分配空间
        double scores[];   //声明数组,此时scores是null
        scores = new double[5];   //分配了内存空间,可以存放数据
        Scanner scanner = new Scanner(System.in);
        //遍历输入数组元素
        for (int i = 0; i < scores.length; i++){
            System.out.println("请输入第" + (i+1) + "个元素的值");
            scores[i] = scanner.nextDouble();
        }
        //输出遍历数组
        System.out.println("数组的元素情况如下");
        for (int i = 0; i <scores.length; i++){
            System.out.println("第" + (i+1) + "个元素的值=" + scores[i]);
        }
    }
}

 3、静态初始化

 例子就是最上面的那个hens代码。

 四、数组的使用细节

  • 数组是多个相同类型数据的组合,实现对这些数据的统一管理。
  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是二者不能混用。
  • 数组创建后,如果没有赋值,有默认值:int0;short0;byte0;long0;float0.0;double0.0;boolean false; String null。
  • 使用数组的步骤:1.声明数组并开辟空间 2.给数组各个元素赋值 3.使用数组
  • 数组的下标是从0开始的。
  • 数组下标必须在指定范围内使用,否则异常。eg:int arr[] = new int[5]; 则有效下标为0~4。
  • 数组是引用类型,数组型数据是对象。

五、数组练习 

1、创建一个char类型的26个元素的数组,分别访问'A'~'Z',使用for循环访问所有元素并打印出来。提示:char类型数据运算‘A’+1 -> 'B'。

package com.hspedu.array;
/*
创建一个char类型的26个元素的数组,分别访问'A'~'Z'
使用for循环访问所有元素并打印出来
提示:char类型数据运算‘A’+1 -> 'B'

1.定义一个数组
2.因为‘A’+1 -> 'B', 使用for循环赋值
3.使用for循环访问所有元素
 */
public class ArrayExercise01 {
    public static void main(String[] args) {
        char chars[] = new char[26];
        //循环给chars[i]赋值
        for (int i = 0; i < chars.length; i++){   //循环26次
            chars[i] = (char)('A' + i);   //'A' + i是int,需要强转
        }

        //循环输出
        System.out.println("===chars数组===");
        for (int i = 0; i < chars.length; i++){
            System.out.println(chars[i]);
        }
    }
}

2、请求出一个数组int[]的最大值{4, -1, 9, 10, 23},并得到对应的下标。

package com.hspedu.array;
/*
请求出一个数组int[]的最大值{4, -1, 9, 10, 23},并得到对应的下标。
 */
public class ArrayExercise02 {
    public static void main(String[] args) {

        //1.定义一个int数组
        //2.假定max=arr[0]是最大值,maxIndex=0
        //3.从下标1开始遍历arr,如果max<当前元素,说明max不是真正的最大值
        //我们就max=当前元素;maxIndex=当前元素下标
        //4.当我们遍历整个arr后,max就是真正的最大值,maxIndex=最大值对应的下标
        int[] arr = {4, -1, 9, 10, 23};
        int max = arr[0];   //假定第一个元素就是最大值
        int maxIndex = 0;

        for (int i = 1; i < arr.length; i++){   //从下标1开始遍历arr
            if (max < arr[i]){  //如果max < 当前元素
                max = arr[i];  //把max设置成当前元素
                maxIndex = i;
            }
        }
        System.out.println("最大值是 " + max + "\t" + "最大值的下标是 " + maxIndex);
    }
}

六、数组赋值机制

普通的值是拷贝赋值,n2的变化,不会影响到n1的值。

//基本数据类型赋值,赋值方式是拷贝
//n2的变化,不会影响到n1的值
int n1 = 10;
int n2 = n1;

n2 = 80;
System.out.println("n1=" + n1);  //10
System.out.println("n2=" + n2);  //80

然而,数组是引用赋值,赋的是地址:

package com.hspedu.array;

public class ArrayExercise03 {
    public static void main(String[] args) {

        //数组在默认情况下是引用传递,赋的值是地址,赋值方式为引用
        //arr2变化会影响到arr1
        int[] arr1 = {1,2,3};
        //看看arr1的值
        System.out.println("=====修改arr2前,arr1的元素=====");
        for (int i = 0; i < arr1.length; i++){
            System.out.println(arr1[i]);
        }
        //把arr1赋值给arr2
        int[] arr2 = arr1;
        arr2[0] = 10;
        //看看修改arr2后,arr1的值
        System.out.println("=====修改arr2后,arr1的元素=====");
        for (int i = 0; i < arr1.length; i++){
            System.out.println(arr1[i]);
        }
    }
}

拷贝赋值和引用赋值图解:

 七、数组拷贝

如果我就想要某个数组的内容,而不是上面那样的地址赋值,就要用到数组拷贝。就是新new一个数组开辟空间,然后遍历拷贝赋值就行。

要求:将int[] arr1 = {10,20,30}; 拷贝到arr2数组,要求数据空间是独立的。

package com.hspedu.array;

public class ArrayCopy {
    public static void main(String[] args) {
        //将int[] arr1 = {10,20,30}; 拷贝到arr2数组,要求数据空间是独立的。
        int[] arr1 = {10,20,30};
        //先创建一个新的数组arr2,开辟新的数据空间
        //大小 arr1.length
        int[] arr2 = new int[arr1.length];
        //遍历arr1,把每个元素拷贝到arr2对应的位置
        for (int i = 0; i < arr1.length; i++){
            arr2[i] = arr1[i];
        }
    }
}

八、数组反转

要求:把数组的元素内容反转。eg:arr{1,2,3,4,5} ---> arr{5,4,3,2,1}

1、通过找规律反转

package com.hspedu.array;
/*
1.通过找规律reverse
 */
public class ArrayReverse {
    public static void main(String[] args) {
        //定义数组
        int[] arr = {11,22,33,44,55,66};
        //1.把arr[0]和arr[5]进行交换  {66,22,33,44,55,11}
        //2.把arr[1]和arr[4]进行交换  {66,55,33,44,22,11}
        //3.把arr[2]和arr[3]进行交换  {66,55,44,33,22,11}
        //4.一共要交换3次 = arr.length / 2
        //5.每次交换时,对应的下标是arr[i]和arr[arr.length - 1 - i]
        int temp = 0;
        int len = arr.length;
        for (int i = 0; i < arr.length/2; i++){
            temp = arr[len - 1 - i];  //先保存在temp
            arr[len - 1 - i] = arr[i];
            arr[i] = temp;
        }
        System.out.println("===反转后的数组===");
        for (int i = 0; i < arr.length; i++){
            System.out.println(arr[i]);
        }
    }
}

2、通过逆序赋值反转

package com.hspedu.array;
/*
2.通过逆序赋值反转
 */
public class ArrayReverse02 {
    public static void main(String[] args) {
        //定义数组
        int[] arr1 = {11,22,33,44,55,66};
        //1.先创建一个数组arr2,大小arr.length
        //2.逆序遍历 arr1,将每个元素拷贝到arr2的元素中(顺序拷贝)
        //3.增加一个循环变量
        int[] arr2 = new int[arr1.length];
        for (int i = arr1.length - 1, j = 0; i >= 0; i--, j++){
            arr2[j] = arr1[i];
        }
        //4.当for循环结束,arr2就是一个逆序的数组{66,55,44,33,22,11}
        //5.让arr1指向arr2数据空间,此时arr1原来的数据空间就没有使用了,会被当作垃圾销毁。
        arr1 = arr2;
        System.out.println("===arr2的内容===");
        for (int i =0; i < arr1.length; i++){
            System.out.println(arr1[i]);
        }
    }
}

九、数组添加

要求:实现动态的给数组添加元素,实现对数组扩容。

  1. 原始数组使用静态分配 int[] arr = {1,2,3}
  2. 增加的元素,直接放在数组的最后 arr = {1,2,3,4}
  3. 用户可以通过如下方法决定是否继续添加,添加成功,是否继续? y/n
package com.hspedu.array;

import java.util.Scanner;
/*
1.原始数组使用静态分配 int[] arr = {1,2,3}
2.增加的元素,直接放在数组的最后 arr = {1,2,3,4}
3.用户可以通过如下方法决定是否继续添加,添加成功,是否继续? y/n
 */
public class ArrayAdd {
    public static void main(String[] args) {
        //1.定义初始数组 int[] arr = {1,2,3}
        //2.定义一个新的数组,int[] arrNew = new int[arr.length + 1];
        //3.遍历arr数组,依次将arr的元素拷贝到arrNew数组
        //4.将4拷贝给arrNew[arrNew.length - 1] = addNum; 把addNum赋给arrNew最后一个元素
        //5.让arr指向arrNew;
        //6.创建一个Scanner可以接受用户输入
        //7.因为用户什么时候退出不确定,故使用do-while + break来控制

        Scanner myScanner = new Scanner(System.in);
        //初始化的数组
        int[] arr = {1,2,3};
        do {
            int[] arrNew = new int[arr.length + 1];
            //3.遍历arr数组,依次将arr的元素拷贝到arrNew数组
            for (int i = 0; i < arr.length; i++) {
                arrNew[i] = arr[i];
            }
            System.out.println("请输入你要添加的元素");
            int addNum = myScanner.nextInt();

            //把addNum赋值给arrNew的最后一个元素
            arrNew[arrNew.length - 1] = addNum;
            //让arr指向arrNew,原来的数组arr就没有使用了,被销毁
            arr = arrNew;
            //输出arr看看效果
            System.out.println("===arr扩容后元素情况===");
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i]);
            }

            //问用户是否继续
            System.out.println("是否继续添加y/n");
            //Scanner是java.util包下的一个类,.next()是Sanner类下面的一个方法。
            // .next()方法是接收用户输入的字符串,但Scanner类下面没有接收字符(.nextChar())的方法
            //因此出现了charAt(int index),返回 char指定索引处的值。
            //Scanner.next().charAt(0)具体含义就是,获取用户输入的字符串中的第一个字符。
            char key = myScanner.next().charAt(0);
            if (key == 'n'){  //如果输入n,就结束
                break;  //break就是跳出循环了
            }
        }while (true);
        System.out.println("你退出了添加...");
    }
}

十、排序

1、内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序。

2、外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。

十一、冒泡排序法(Bubble Sorting)

基本思想:通过对待排序内容从后向前(从下标较大的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒。

案例:五个无序:24,69,80,57,13。使用Bubble Sorting将其排成一个从小到大的有序排列。

 麻烦的写法:(这样写非常麻烦!!因此要嵌套for循环)

package com.hspedu.array;

public class BubbleSort {
    public static void main(String[] args) {
        //化繁为简,先死后活
    /*
    数组[24, 69, 80, 57, 13]
    第一轮排序:目标把最大数放在最后
    第1次比较[24, 69, 80, 57, 13]
    第2次比较[24, 69, 80, 57, 13]
    第3次比较[24, 69, 57, 80, 13]
    第4次比较[24, 69, 57, 13, 80]
     */
        int[] arr = {24, 69, 80, 57, 13};
        int temp = 0;  //用于辅助变换的变量

        //第一轮排序,目标是把最大的数放最后
        for (int j = 0; j < 4; j++){  //4次比较
            //如果前面的数大于后面的数,就交换
            if (arr[j] > arr[j+1]){
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("===第1轮===");
        for (int j = 0; j < arr.length; j++){
            System.out.print(arr[j] + "\t");
        }
        System.out.println();

        //第二轮排序:目标把第二大的数放后面
        for (int j = 0; j < 3; j++){  //3次比较
            //如果前面的数大于后面的数,就交换
            if (arr[j] > arr[j+1]){
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("===第2轮===");
        for (int j = 0; j < arr.length; j++){
            System.out.print(arr[j] + "\t");
        }
        System.out.println();

        //第三轮排序:目标把第三大的数放在后面
        for (int j = 0; j < 2; j++){  //2次比较
            //如果前面的数大于后面的数,就交换
            if (arr[j] > arr[j+1]){
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("===第3轮===");
        for (int j = 0; j < arr.length; j++){
            System.out.print(arr[j] + "\t");
        }
        System.out.println();

        //第四轮排序:目标把第四大的数放在后面
        for (int j = 0; j < 2; j++){  //2次比较
            //如果前面的数大于后面的数,就交换
            if (arr[j] > arr[j+1]){
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("===第4轮===");
        for (int j = 0; j < arr.length; j++){
            System.out.print(arr[j] + "\t");
        }
        System.out.println();

        //第五轮排序:目标把第五大的数放在后面
        for (int j = 0; j < 1; j++){  //1次比较
            //如果前面的数大于后面的数,就交换
            if (arr[j] > arr[j+1]){
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("===第5轮===");
        for (int j = 0; j < arr.length; j++){
            System.out.print(arr[j] + "\t");
        }
        System.out.println();
    }
}

for循环嵌套的写法:(从上面那种写法一步步推导过来的)

package com.hspedu.array;

public class BubbleSort {
    public static void main(String[] args) {

        int[] arr = {24, 69, 80, 57, 13, -1, 100, 500};
        int temp = 0;  //用于辅助变换的变量

        for (int i = 0; i < arr.length-1; i++){  //外层循环是四次
            for (int j = 0; j < arr.length-1 - i; j++){  //4次比较:3次-2次-1次
                //如果前面的数大于后面的数,就交换
                if (arr[j] > arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
            System.out.println("===第"+(i+1)+"轮===");
            for (int j = 0; j < arr.length; j++){
                System.out.print(arr[j] + "\t");
            }
            System.out.println();
        }
    }
}

十二、数组中的查找

1、顺序查找

2、二分法查找

下面是顺序查找的例子,里面有一个编程技巧需要学习:

package com.hspedu.array;

import java.util.Scanner;

/*
有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏:
从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
要求:如果找到了,就提示找到,并给出下标值

1.定义一个字符串数组
2.接受用户输入,遍历数组,逐一比较,如果有,则提示信息并退出
 */
public class SequenceSearch {
    public static void main(String[] args) {
        String[] names = {"白眉鹰王","金毛狮王","紫衫龙王","青翼蝠王"};
        Scanner myScanner = new Scanner(System.in);

        System.out.println("请输入名字");
        String findName = myScanner.next();

        //遍历数组,逐一比较,如果有就退出
        //一种编程思想/技巧,经典用法
        int index = -1;
        for (int i = 0; i < names.length; i++){
            if (findName.equals(names[i])){
                System.out.println("恭喜你找到了 " + findName);
                System.out.println("下标为= " + i);
                //把i保存到index
                index = i;
                break;
            }
        }
        if (index == -1){  //没有找到,都没有进入上面一个if循环
            System.out.println("sorry, 没有找到 " + findName);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m1m-FG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值