【JavaSE】05-数组 Array

五、 数组 Array

5.1 数组的概述

  1. 数组属于“引用数据类型”变量。(引用数据类型包括:数组、类)

  2. 注意和数组的元素的数据类型区分,数组的元素的数据类型可以是整型、String型、char型等。

  3. 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址 。

  4. 数组的长度一旦确定就不能修改。

  5. 数组的分类:

    (1) 按照维度:一维数组 、 二维数组 、 三维数组 ……
    (2) 按照元素的数据类型分:基本数据类型元素的数组 、 引用数据类型元素的数组(即对象数组)。

5.2 一维数组的使用

5.2.1 一维数组的声明和初始化

  1. 静态初始化:数组元素的赋值和长度都已经确定。

    int[] i1 = new int[]{1, 2, 3, 4, 5};
    
  2. 动态初始化:数组元素的值不确定,只能确定长度。

    String[] s1 = new String[5];
    

5.2.2 一维数组的调用

一维数组通过索引访问数组元素,并进行读写操作。索引从0开始。

// ② 一维数组的调用(接上代码)
s1[0] = "谢斯航";
s1[1] = "徐瑞华";
s1[2] = "郭梓骞";
s1[3] = "于佳傲";
s1[4] = "庞静溪";

for(int i = 0; i<5; i++){
    System.out.println(s1[i]);
}

输出结果:

谢斯航
徐瑞华
郭梓骞
于佳傲
庞静溪

5.2.3 如何获取数组的长度

使用 .length 获取一维数组的长度:

System.out.println(s1.length);
System.out.println(i1.length);

输出结果:

5
6

5.2.4 如何遍历数组

使用for循环来实现遍历:

for(int i = 0; i<s1.length; i++){
    System.out.println(s1[i]);
}

输出结果:

谢斯航
徐瑞华
郭梓骞
于佳傲
庞静溪

心得:循环条件中的 ” i<s1.length;" 采用了灵活的写法,防止因数组长度改变而需要重新修改此处代码。以后写代码过程中都要注意尽量能用变量就用变量。

5.2.5 数组元素的默认初始化值

(一) 基本数据类型数组的默认初始化值

基本原则就是:全部都是对于类型的0。

int[] array1 = new int[5];
short[] array2 = new short[5];
long[] array3 = new long[5];
float[] array4 = new float[5];
double[] array5 = new double[5];
char[] array6 = new char[5];
boolean[] array8 = new boolean[5];

分别遍历上述数组得:

0
0
0
0.0
0.0
 		//注意这里不是空格,而是ACAII码0号符号
false

(二) 引用数据类型数组的默认初始化值

String[] array7 = new String[5];

输出结果:

null

5.2.6 数组的内存解析

一维数组的内存解析如下图所示:

image-20220205184535835

5.2.7 一维数组练习题

题目
image-20220209180405571

我首次答案:

import java.util.Scanner;
public class Array01Exercise {
    public static void main(String[] args) {
        
        Scanner scan = new Scanner(System.in);
        System.out.print("请输入学生人数:");
        int stuNum = scan.nextInt();
        // 根据学生人数创建数组
        int[] score = new int[stuNum];
        // 从键盘输入成绩, 并比较出最高分
        int max = 0;
        for(int i=0; i<stuNum; i++){
            System.out.print("请输入第" + (i+1) + "个学生的成绩:");
            score[i] = scan.nextInt();
            if(i==0){
                max = score[0];
            }else if(i>0){
                if(score[i]>max){
                    max = score[i];
                }
            }
        }
        System.out.println("最高分是:" + max);

        // 为输入的学生分级
        for(int i=0; i<score.length; i++){
            if(score[i] >= (max-10)){
                System.out.println("student " + i + " score is " + score[i]
                + " grade is A");
            }else if(score[i] >= (max-20)){
                System.out.println("student " + i + " score is " + score[i]
                + " grade is B");
            }else if(score[i] >= (max-30)){
                System.out.println("student " + i + " score is " + score[i]
                + " grade is C");
            }else {
                System.out.println("student " + i + " score is " + score[i]
                + " grade is D");
            }
        }
    }
}

5.3 多维数组的使用

5.3.1 二维数组的声明和初始化

  1. 静态初始化:数组元素的赋值和长度都已经确定。

    //1. 静态初始化:数组元素的赋值和长度都已经确定。
    int [][] arr1 = new int[][]{{1, 2, 3}, {4, 5}, {6, 7, 8}};
    
  2. 动态初始化:数组元素的值不确定,只能确定长度。

    //2. 动态初始化:数组元素的值不确定,只能确定长度。
    String [][] arr2 = new String[3][2];
    
  3. 其他正确的写法:

    String [] arr3 [] = new String[3][];
    String  arr4 [][] = new String[3][];
    int [][] arr5 = {{1, 2, 3}, {4, 5}, {6, 7, 8}}; //类型推断
    

5.3.2 二维数组的调用

调用范式:

System.out.println(arr5[1][0]);

5.3.3 如何获取二维数组的长度

int [][] arr5 =new int [][] {{1, 2, 3}, {4, 5}, {6, 7, 8}};
System.out.println(arr5.length);
System.out.println(arr5[1].length);

输出结果:

3
2

5.3.4 遍历二维数组

通过2层嵌套循环遍历二维数组:

//遍历二维数组
for(int i=0; i< arr5.length; i++){
    for(int j=0; j<arr5[i].length; j++){
        System.out.print(arr5[i][j] + " ");
    }
    System.out.println();
}

输出结果:

1 2 3 
4 5 
6 7 8 

5.3.5 二维数组元素的默认初始化值

//二维数组元素的默认初始化值
int [][] array1 = new int[3][2];
System.out.println(array1[0]);
System.out.println(array1[0][0]);
System.out.println(array1);

输出结果:

[I@58372a00		//地址值,8位十六进制数,4GB
0
[[I@4dd8dc3		

其中,两个“[["代表二维数组地址值,”I“代表int型数据,@后面跟的是十六位地址值。

例2:

String [][] array2 = new String[3][];
System.out.println(array2[1]);		//null
System.out.println(array2[1][0]);	//报错

输出结果:

null
Exception in thread "main" java.lang.NullPointerException: Cannot load from object array because "array2[1]" is null
	at ch05.Array02.main(Array02.java:47)

5.3.6 二维数组的内存解析

image-20220210134709709

5.3.7 二维数组练习题

  1. 练习1:

    image-20220210141931860

我首次答案:

public class Array02Exercise {
    public static void main(String[] args){
        //获取arr数组中所有元素的和。创建二维数组
        int [][] arr = new int[][]{{3,5,8}, {12,9}, {7,0,6,4}};
        //
        int sum = 0;
        for(int i=0; i<arr.length; i++){
            for(int j=0; j<arr[i].length; j++){
                sum += arr[i][j];
            }
        }
        //
        System.out.println("The sum of the array is: " + sum);
    }
}

输出结果:

The sum of the array is: 54
  1. 练习2:

image-20220210142612744

我的首次答案:

public class Array02Exercise {
    public static void main(String[] args){
        
        //杨辉三角
        int [][] yhsj = new int[10][];
        for(int i=0; i<yhsj.length; i++){
            yhsj[i] = new int[i+1];
            for(int j=0; j<yhsj[i].length; j++){
                if(j==0 || j==i){
                    yhsj[i][j] = 1;
                }else {
                    yhsj[i][j] = yhsj[i-1][j-1] + yhsj[i-1][j];
                }
            }
        }
        
        for(int i=0; i<yhsj.length; i++){
            for(int j=0; j<yhsj[i].length; j++){
                System.out.print(yhsj[i][j] + " ");
            }
            System.out.println();
        }
    }
}

输出结果:

1 
1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1 
1 5 10 10 5 1 
1 6 15 20 15 6 1 
1 7 21 35 35 21 7 1 
1 8 28 56 70 56 28 8 1 
1 9 36 84 126 126 84 36 9 1 

5.4 数组相关算法

5.4.1 数组元素的赋值

  1. 例1:

    创建一个长度为 6 的 int 型数组,要求数组元素的值都在1-30 之间,且是随机赋值。同时,要求元素的值各不相同。
    

    我的首次答案:不会

    老师答案:

    //创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值。同时,要求元素的值各不相同。
    int [] arr1 = new int [6];
    for(int i=0; i<arr1.length; i++){
        arr1[i] = (int)(Math.random() * 30) + 1;
        for(int j=0; j<i; j++){
            if(arr1[i] == arr1[j]){
                i--;		//点睛之笔,妙啊~
                break;
            }
        }
    }
    //输出结果
    for(int i=0; i<arr1.length; i++){
        System.out.print(arr1[i] + "  ");
    }
    
  2. 例2:回形数

5.4.2 求数值型数组中元素的最大值、最小值、平均数、总和等

  1. 例1:
    image-20220210170413451

我首次答案:

int max = 0, min = 0, sum = 0;
double average = 0.;
int[] arr2 = new int[10];

for (int i = 0; i < arr2.length; i++) {
    arr2[i] = (int) (Math.random() * 90) + 10;
    if (i == 0) {
        max = arr2[0];
        min = arr2[0];
    }

    sum += arr2[i];
    if (arr2[i] > max) {
        max = arr2[i];
    } else if (arr2[i] < min) {
        min = arr2[i];
    }
}
for (int i = 0; i < arr2.length; i++) {
    System.out.print(arr2[i] + "  ");
}
average = (double) sum / arr2.length;
System.out.println();
System.out.println("最大值:" + max);
System.out.println("最小值:" + min);
System.out.println("和值:" + sum);
System.out.println("平均值:" + average);

输出结果:

26  97  59  27  24  96  42  30  16  70  
最大值:97
最小值:16
和值:487
平均值:48.7

5.4.3 数组的复制、反转、查找

  1. 数组的复制

    题目:

    image-20220211194736342

​ 我首次答案:

public class Array02Exercise2 {
    public static void main(String[] args){
        //定义array1
        int[] array1 = new int[]{2,3,5,7,11,13,17,19};
        int[] array2 = new int[array1.length];
        System.out.println("Origin array1: ");
        for(int i=0; i<array1.length; i++){
            System.out.print(array1[i] + "  ");
        }
        System.out.println();

        //把array1复制到array2
//        array2 = array1;          //复制语句一,这样会直接把array1的地址值复制到array2的堆中,在栈中其实还是只有一个
        System.out.println("Origin array2: ");
        for(int i=0; i<array1.length; i++){
            array2[i] = array1[i];  //复制语句二, 这样是真正在栈空间中开辟了另一个空间存放array2,两者独立
            System.out.print(array2[i] + "  ");
        }
        System.out.println();

        //修改array2偶元素值
        for (int i=0; i< array2.length; i+=2){
            array2[i] = i;
        }
        System.out.println("After array2: ");
        for (int i=0; i< array2.length; i++){
            System.out.print(array2[i] + "  ");
        }
        System.out.println();
        //查看复制完array1中的值
        System.out.println("After array1: ");
        for (int i=0; i< array1.length; i++){
            System.out.print(array1[i] + "  ");
        }
    }
}

输出结果:

Origin array1: 
2  3  5  7  11  13  17  19  
Origin array2: 
2  3  5  7  11  13  17  19  
After array2: 
0  3  2  7  4  13  6  19  
After array1: 
2  3  5  7  11  13  17  19

注意:此处复制语句有两种方式

操作一:这不能称作数组的复制!

array2 = array1;

这样会直接把array1的地址值复制到array2的堆中,在栈中其实还是只有一个。修改array2数组元素中的值,也会导致array1数组元素中的值改变。【因为两个变量地址一致,指向栈中同一块内存空间】

image-20220211202738620

操作二:这才是数组的复制!

for(int i=0; i<array1.length; i++){
	array2[i] = array1[i];
}

这样是真正在栈空间中开辟了另一个空间存放array2数组元素。【因为两个变量地址不一致,指向栈中不同的内存空间】,两者独立。修改array2数组元素中的值,并不会导致array1数组元素中的值改变。

image-20220211203321926

  1. 数组的反转

    题目:反转上述array1的元素。

    我的首次答案:

    System.out.println("------------------反转------------------");
    int[] array3 = new int[array1.length];
    for (int i = 0; i<array3.length; i++){
        array3[i] = array1[(array1.length -1- i)];
    }
    for (int i = 0; i<array3.length; i++){
        System.out.print(array3[i] + "  ");
    }
    

    定义一个新的数组效率要差些:

    老师的答案:

    for (int i = 0; i<array1.length/2; i++){
        int temp = array1[i];
        array1[i] = array1[(array1.length -1- i)];
        array1[(array1.length -1 -i)] = temp;
    }
    for (int i = 0; i<array1.length; i++){
        System.out.print(array1[i] + "  ");
    

    输出结果:

    19  17  13  11  7  5  3  2  
    

    只需要一个int temp变量,就能完成array1的反转操作,效率更高。

  2. 数组的查找

    1. 1 线性查找

      String[] arr = new String[]{"谢斯航","庞静溪","徐瑞华","郭梓骞","魏伟","于佳傲","孙鑫"};
      Scanner scan = new Scanner(System.in);
      System.out.print("请输入您想查找的同学: ");
      String target = scan.next();
      boolean isFlag = true;
      for (int i=0; i<arr.length; i++){
          if (target.equals(arr[i])){
              System.out.println("恭喜您!找到您的同学的索引为:" + i);
              isFlag = false;
          }
      }
      if (isFlag){
          System.out.println("很遗憾,未能找到该名同学!");
      }
      

      输出结果示例:

      请输入您想查找的同学: 谢斯聪
      很遗憾,未能找到该名同学!
      
      请输入您想查找的同学: 徐瑞华
      恭喜您!找到您的同学的索引为:2
      

      知识点:

      ① 判断String型是否一致时用 .equals(),而不是==:

      if (target.equals(arr[i])){
          ...
      }
      

      ② isFlag的使用,很有用。

    二分查找

    条件: 数组元素要有序【升序、降序都可】。

    问题:查找array1中的某个元素。

    答案:

    Scanner scan = new Scanner(System.in);
    System.out.print("请输入您想查找的数字: ");
    int target = scan.nextInt();
    int head = 0;
    int end = array1.length - 1;
    boolean isFlag1 = true;
    
    while (head <= end){
        int middle = (head + end) / 2;
        if (target == array1[middle]){
            System.out.println("恭喜您!找到您的同学的索引为:" + middle);
            isFlag1 = false;
            break;
        }else if (target < array1[middle]){
            end = middle - 1;
        }else {
            head = middle + 1;
        }
    }
    if (isFlag1){
        System.out.println("很遗憾,未能找到这个数!");
    }
    

    输出结果1:

    Origin array1: 
    2  3  5  7  11  13  17  19  21  23  29  31  37  
    请输入您想查找的数字: 7
    恭喜您!找到您的同学的索引为:3
    

    输出结果2:

    请输入您想查找的数字: 22
    很遗憾,未能找到这个数!
    

5.4.4 数组的排序

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fWgCPvwC-1652427589138)(https://raw.githubusercontent.com/SihangXie/pic-bed/master/img/image-20220211221024374.png)]

在这里插入图片描述

算法的五大特征:

在这里插入图片描述

5.4.4.1 冒泡排序

冒泡排序思想

介绍:冒泡排序的原理非常简单,它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

排序思想

  1. 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较为止 。

我的首次代码:

public class Array03Sort {
    public static void main(String[] args) {
        // 1. Bubble Sort 冒泡排序
        int[] arr1 = new int[10];
        for (int i=0; i<arr1.length; i++){
            arr1[i] = (int)(Math.random()*90) + 10;
            System.out.print(arr1[i] + "  ");
        }
        System.out.println();
        for (int i=arr1.length-1; i>=0; i--){
            for (int j=0; j<i; j++){
                int temp = arr1[j];
                if (arr1[j] > arr1[j+1]){
                    arr1[j] = arr1[j+1];
                    arr1[j+1] = temp;
                }
            }
        }
        //排序完成
        for (int i=0; i<arr1.length; i++){
            System.out.print(arr1[i] + "  ");
        }
        System.out.println();
    }
}

输出结果:

58  52  36  10  68  34  99  19  47  75  
10  19  34  36  47  52  58  68  75  99  
5.4.4.2 Arrays工具类的使用

这部分可以直接在api文档里搜索:java.util.Arrays来查找是否有相应的方法可以直接调用。里面定义了很多操作数组的方法。下面只列举常用的几种方法:

1.判断两个数组是否相等。

boolean equals(int[] a,int[] b)

2.输出数组信息。

String toString(int[] a) 

3.将指定值填充到数组之中。

void fill(int[] a,int val) 

4.对数组进行排序。

void sort(int[] a) 

5.对排序后的数组进行二分法检索指定的值。

int binarySearch(int[] a,int key)
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
面向对象编程是一种编程范式,它将程序的构建和设计思路以面向对象的方式进行组织和实现。在Java中,面向对象编程是基于Java SE(Standard Edition)的一种编程方式。第07讲主要介绍了面向对象编程中的一些基本概念和关键术语。 在面向对象编程中,我们将程序中的数据和对数据的操作(方法)封装在一起,形成一个对象。对象由两部分构成:属性和方法。属性是用来描述对象的特征,而方法则是对象可以执行的操作。对象之间通过消息(方法调用)进行通信和交互。面向对象的核心思想是通过封装、继承和多态实现程序的复用和扩展。 封装是面向对象编程中的一个重要概念,它指的是将类的属性和方法进行封装,使得外部无法直接访问和修改对象的内部状态,只能通过公共的方法来操作属性和执行方法。封装提供了一种将数据和行为组合在一起的方式,可以保护数据的完整性和安全性。 继承是面向对象编程中的另一个重要概念,它指的是通过定义一个新的类来继承现有类的属性和方法。通过继承,子类可以继承父类的属性和方法,并可以在此基础上进行扩展和修改。继承提供了一种代码复用的机制,可以减少重复编码的工作量。 多态是面向对象编程的又一个重要概念,它指的是同一类型的对象在不同的情况下可以有不同的表现形式。多态通过方法的重写和方法的重载实现。方法的重写指的是在子类中重新定义和实现父类的方法,方法的重载指的是在同一个类中可以定义多个同名但参数列表不同的方法。 总结来说,面向对象编程是一种将程序组织和设计思路以对象为中心的编程方式。在JavaSE中,我们可以通过封装、继承和多态来实现面向对象编程的目标。封装可以提高程序的可维护性和可复用性,继承可以减少重复编码的工作量,多态可以灵活地操作对象。掌握这些基本概念和关键术语,可以帮助我们更好地理解和应用面向对象编程的思想。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

自牧君

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

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

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

打赏作者

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

抵扣说明:

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

余额充值