数组

一.数组分类

1、基本数据类型的数组:默认值0;
2、引用数据类型的数组:默认值null;

二.数组的定义

1.方法一
格式:

数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[⻓度];

数组定义格式详解
(1).数组存储的数据类型:创建的数组容器可以存储什么数据类型。
(2).[]:表示数组。
(3).数组名字:为定义的数组起个变量名,满⾜标识符规范,可以使⽤名字操作数组。
(4).new:关键字,创建数组使⽤的关键字。
(5).数组存储的数据类型:创建的数组容器可以存储什么数据类型。
(6).[⻓度]:数组的⻓度,表示数组容器中可以存储多少个元素。
注意:数组有定⻓特性,⻓度⼀旦指定,不可更改
举例:
定义可以存储3个整数的容器,代码如下:

int[] arr=new int[3];

2.方法二
格式:
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3…};
举例:
定义存储1,2,3,4,5整数的数组容器。

int[] arr = new int[] {1, 2, 3, 4, 5};

3.方法三
格式:

数据类型[] 数组名 = {元素1, 元素2, 元素3…};

定义存储1,2,3,4,5整数的数组容器

int[] arr = {1, 2, 3, 4, 5};

三、数组的遍历

数组遍历:就是将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基⽯。
public static void main(String[] args) {
 int[] arr = {1, 2, 3};
 arr = null;
 System.out.println(arr[0]);
}

以上代码是可以将数组中每个元素全部遍历出来,但是如果数组元素⾮常多,这种写法肯定
不⾏,因此我们需要改造成循环的写法。数组的索引是 0 到 lenght - 1 ,可以作为循环的
条件出现。
如:数组获取最⼤值元素
最⼤值获取:从数组的所有元素中找出最⼤值。
实现思路:
1.定义变量,保存数组0索引上的元素
2.遍历数组,获取出数组中的每个元素
3.将遍历到的元素和保存数组0索引上值的变量进⾏⽐较
4.如果数组元素的值⼤于了变量的值,变量记录住新的值
6.数组循环遍历结束,变量保存的就是数组中的最⼤值

public static void main(String[] args) {
 int[] arr = {1, 2, 3, 4, 5};
 System.out.println(arr[0]);
 System.out.println(arr[1]);
 System.out.println(arr[2]);
 System.out.println(arr[3]);
 System.out.println(arr[4]);
}

public static void main(String[] args) {
 int[] arr = {1, 2, 3, 4, 5};
 for (int i = 0; i < arr.length; i++) {
 System.out.println(arr[i]);
 }
}

四、内存

⼀个数组内存图

  public static void main(String[] args) {
 int[] arr = new int[3];
 System.out.println(arr);// [I@5f150435
}

以上⽅法执⾏,输出的结果是[I@5f150435,这个是什么呢?是数组在内存中的地址。new出来
的内容,都是在堆内存中存储的,⽽⽅法中的变量arr保存的是数组的地址。
输出arr[0],就会输出arr保存的内存地址中数组中0索引上的元素。
在这里插入图片描述
两个数组内存图

public static void main(String[] args) {
 int[] arr = new int[3];
 int[] arr2 = new int[2];
 System.out.println(arr);
 System.out.println(arr2);
}

在这里插入图片描述
两个变量指向⼀个数组

public static void main(String[] args) {
 // 定义数组,存储3个元素
 int[] arr = new int[3];
 // 数组索引进⾏赋值
 arr[0] = 5;
 arr[1] = 6;
 arr[2] = 7;
 // 输出3个索引上的元素值
 System.out.println(arr[0]);
 System.out.println(arr[1]);
 System.out.println(arr[2]);
 // 定义数组变量arr2,将arr的地址赋值给arr2
 int[] arr2 = arr;
 arr2[1] = 9;
 System.out.println(arr[1]);
}

在这里插入图片描述

五、数组作为⽅法传参和返回值:

1.数组作为方法参数
数组作为方法参数传递时,传递的参数是数组内存的地址

public static void main(String[] args) {
 int[] arr = {1, 3, 5, 7, 9};
 // 调⽤⽅法,传递数组
 printArray(arr);
}
/*
* 创建⽅法,⽅法接收数组类型的参数
* 进⾏数组的遍历
*/
public static void printArray(int[] arr) {
 for (int i = 0; i < arr.length; i++) {
 System.out.println(arr[i]);
 }
}

在这里插入图片描述2. 数组作为⽅法返回值
数组作为方法的返回值,返回的数组的内存地址

public static void main(String[] args) {
 // 调⽤⽅法,接收数组的返回值
 // 接收到的是数组的内存地址
 int[] arr = getArray();
 for (int i = 0; i < arr.length; i++) {
 System.out.println(arr[i]);
 } }
/*
* 创建⽅法,返回值是数组类型
* return返回数组的地址
*/
public static int[] getArray() {
 int[] arr = {1, 3, 5, 7, 9};
 // 返回数组的地址,返回到调⽤者
 return arr; }

在这里插入图片描述

六.⽅法的参数类型区别

(1)基本数据类型作为参数

public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int result = getSum(a, b);
    }
    public static int getSum(int a, int b) {
        int sum = a+ b;
        return sum; // 方法结束了, 所在的方法栈也就释放了
    }

对应内存图
在这里插入图片描述
(2).引用类型作为参数

public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5};
        printArray1(arr);
        // printArray2(arr);
        System.out.println(arr[0]); // 7
    }
    public static void printArray1(int[] arr) {
        arr[0] = 7;
    }
   
    public static void printArray2(int[] arr) {
          arr = new int[]{7,8,9};
          System.out.println(arr[0]); // 7
      }`.

对应内存图
在这里插入图片描述
(3) 分析下列程序代码,计算输出结果。

   public static void main(String[] args) {
 int a = 1;
 System.out.println(a);

 change(a);
 System.out.println(a);

}
public static void change(int a) {
a=10;
}
 /*  1
     1
     */

change ( )方法在被调用的时候,在内存中也分配一个空间来存储,存的是传过来的值,即10 .而当方法结束时,这块内存就等垃圾回收了,而在main 方法中,它打印的a 的值是在调用main方法时分配的内存空间,他们俩之间没有任何关系,所以打印的还是1.
分析下列程序代码,计算输出结果。

   public static void main(String[] args) {
 int[] arr = {1, 3, 5};
 System.out.println(arr[0]);
 change(arr);
 System.out.println(arr[0]);
}
public static void change(int[] arr) {
 arr[0] = 200; }
 /*1
   200*/

总结: ⽅法的参数为基本类型时,传递的是数据值。⽅法的参数为引⽤类型时,传递的是
地址值

七、数组使用中的问题

1.数组越界 ArrayIndexOutOfBoundsException

  public static void main(String[] args) {
 int[] arr = {1, 2, 3};
 System.out.println(arr[3]);
}

创建数组,赋值3个元素,数组的索引就是0,1,2,没有3索引,因此我们不能访问数组中不存
在的索引,程序运⾏后,将会抛出 ArrayIndexOutOfBoundsException 数组越界异常。在开发
中,数组的越界异常是不能出现的,⼀旦出现了,就必须要修改我们编写的代码。
在这里插入图片描述

2.空指针异常 NullPointerException
出现原因: 调用了空值(null) 的属性或方法

       public static void main(String[] args) {
 int[] arr = {1, 2, 3};
 arr = null;
 System.out.println(arr[0]);
}

arr = null 这⾏代码,意味着变量arr将不会在保存数组的内存地址,也就不允许再操作数组
了,因此运⾏的时候会抛出 NullPointerException 空指针异常。在开发中,数组的越界异常是
不能出现的,⼀旦出现了,就必须要修改我们编写的代码。
在这里插入图片描述
在这里插入图片描述

八、数组相关的方法

1.数组的打印 Arrays.toString(array),返回String结果
2.数组的扩容或者缩容(复制)
(1) Arrays.copyOf(T[] original, int newLength)
复制指定的数组,新数组的长度
该方法会返回一个全新的数组, 源数组没有影响

     //       使用数组方法的方式来扩容
        int[] src = new int[]{1,3,2,4,5};
//        扩容+复制+赋值(src重新指向)
//        Arrays.copyOf(src,src.length+1) 需要扩容的数组和需要扩容的长度
        src= Arrays.copyOf(src,src.length+1);
        src[src.length-1]=6;
//        Arrays.toString(src) 快速打印
        System.out.println(Arrays.toString(src));
        // Arrays.sort(src) 从小到大排序
        Arrays.sort(src);
        System.out.println(Arrays.toString(src));
    }   
    //结果 [1, 3, 2, 4, 5, 6]
           [1, 2, 3, 4, 5, 6]

(2) System.arraycopy()
方法: static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
从指定源数组中复制一个数组,复制从指 定的位置开始,到目标数组的指定位置结束

      public static void main(String[] args) {
    int i, j;
    int[] array = new int[]{1, 2, 3, 4, 5, 7};
    int[] newArray=new int[7];
    //System.arraycopy(原数组,原数组下标,新数组,新数组开始复制的下标,复制的长度);
    System.arraycopy(array,1,newArray,2,3);
    System.out.println(Arrays.toString(newArray));
}
结果 [0, 0, 2, 3, 4, 0, 0]

复制的效率System.arraycopy>clone>Arrays.copyOf>for循环
3.数组的排序 Arrays.sort(arr);
默认排序从小到大;

九、数组的应用

1.双色球: 红球 1~32, 随机生成5个, 不能重复
存在数组中, 并且红球先由小到大排好序
再在数组中, 额外添加一个蓝色球, 范围1~16

   public class BichromaticSphere {
    public static void main(String[] args) {
        int[] balls = new int[5];
        for (int i = 0; i < balls.length; i++) {
            balls[i] = (int) (Math.random() * 32) + 1;
            for (int j = 0; j < i; j++) {
                if (balls[i] == balls[j]) {
                    i--;
                    break;
                }

            }

        }
        Arrays.sort(balls);
        System.out.println("输出从小到大排序后的红色球:");
        System.out.println(Arrays.toString(balls));
        //扩容+复制
        balls = Arrays.copyOf(balls, balls.length + 1);
        //添加最后一个球
        balls[balls.length - 1] = (int) (Math.random() * 16) + 1;
        System.out.println("输出添加蓝球后双色球:");
        System.out.println(Arrays.toString(balls));
    }

}

2.猜字母游戏
1.生成 5 个随机的字母 char[] char 可以用== , toCharArray() 将String类型 转换成char类型
2.用户猜字母 next()
3.比较 正确答案:ERWAG 猜:ABCDE 结果:2个字母正确,其中位置正确的有0个
猜:EABCD 结果:2个字母正确,其中位置正确的有1个
4.输入byebye, 退出程序

public class GuessTheLetters {
    public static void main(String[] args) {
        char[] letter = answer();
        while (true) {

            System.out.println("正确字母"+Arrays.toString(letter));
            System.out.println("输入5个不重复的大写字母,输入byebye可退出程序:");
            Scanner sc = new Scanner(System.in);
            String guessLetter;
            guessLetter = sc.next();
            if ("byebye".equals(guessLetter))
                break;
            //toCharArray() 将String类型 转换成char类型
            char guessLetterChar[];
            guessLetterChar = guessLetter.toCharArray();
            int[] result = compare(letter, guessLetterChar);
            System.out.println(+result[0] + "个字母正确且" + result[1] + "个位置正确");
            if (result[1] == 5) {
                System.out.println("程序结束");
                break;
            }
        }
    }

    //生成5个字母的方法
    public static char[] answer() {
        char[] letter = new char[5];
        char[] letter_26 = new char[26];
        //生成26个大写字母
        for (int i = 0; i < letter_26.length; i++) {
            letter_26[i] = (char) (65 + i);
        }
        for (int i = 0; i < letter.length; i++) {
            int random = (int) (Math.random() * 26);
            letter[i] = letter_26[random];
            //生成不重复的5个字母
            for (int j = 0; j < i; j++)
                if (letter[i] == letter[j]) {
                    i--;
                    break;
                }
        }
        return letter;
    }

    //比较方法
    public static int[] compare(char[] guessLetterChar, char[] letter) {
        int[] result = new int[2];
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++)
                if (guessLetterChar[j] == letter[i]) {
                    result[0]++;
                    if (guessLetterChar[i] == letter[i])
                        result[1]++;
                }
        }
        return result;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值