Java两周半速成之路(第四天)

一、 数组的初始化以及内存分布图

1.数组的定义:

     固定大小存储统一数据类型元素数据的容器

2.特点:

(1)大小是固定的

(2)对于同一个数组而言,元素数据类型是一样的

(3)对于不同的数组,他们的元素数据类型可以是不一样的

(4)数组既可以存储基本数据类型,也可以存储引用数据类型

3.数组的定义格式:

     第一种:       数据类型  []  数组名;   

     第二种:       数据类型  数组名  [];

注意:

数组只是定义,就相当于定义了一个没有值的变量,无法直接使用。 给值的过程实际上就是初始化值的过程。

4.数组的初始化

 java中数组的初始化有两种初始化方式:

1、动态初始化:我们指定数组的大小,初始化值由系统决定

                           byte,short,int,long类型的数组初始化默认值为0;

                           float,double类型的数组的初始化默认值为0.0;

                           布尔类型的数组的初始化默认值为false;

                           char类型的数组的初始化默认值为’\u0000’;

                           引用类型的数组的初始化默认值为null;

2、静态初始化:在创建数组的时候,我们将元素一并赋值上去,由系统来判断数组的大小

4.1动态初始化:

语句定义格式:   数据类型[] 数组名 = new 数据类型[元素个数];

举例:int[] arr = new int[3];

其中    []: 表示这是一个一维数组

           new:表示在堆内存中开辟空间

4.2静态初始化

语句定义格式: 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3,...};

简化写法 数据类型[] 数据名 = {元素1,元素2,元素3,...};

举例:创建一个存储了11,22,33,44,55这些元素的一维数组

int[] arr = new int[]{11,22,33,44,55};

简化写法: int[] arr = {11,22,33,44,55};

5.数组的索引操作

1.利用索引得到数组中存储的元素

2.索引操作时的常见问题:

3.演示:


        int [] arr1={11,22,33,44,55};
        int [] arr2=null;
        System.out.println(arr1[0]);
        System.out.println(arr1[4]);
        System.out.println(arr1.length);       //获取数组的长度
        System.out.println(arr1[5]);           //数组索引越界
        System.out.println(arr2[0]);            //空指针异常

6.  Java中的内存分配      

内存图解:

图解1: 静态初始化

图解2: 定义两个数组,先定义一个数组,赋值,输出。然后定义第二个数组的时候把第一个数组的地址赋值给第二个数组。然后给第二个数组赋值,再次输出两个数组的名及元素。

图解3:方法传参的问题

总结:

(1)方法传参时,当基本数据类型作为方法的参数传递时候,外部的变量值不会受到影响

当引用数据类型作为方法的参数传递的时候,堆内存中的数据值会受到影响

(2)==比较:

                         1、如果比较的是基本数据类型,比较的是数值

                         2、如果比较的是引用数据类型,比较的是地址值

7.练习

(1)数组遍历(依次输出数组中的每一个元素),并以数组的形式打印在控制台

        int [] arr1 = {11,22,33,44,55,66,77,888,999,189};
        for (int i = 0; i < arr1.length; i++) {
            if(i==0){
                System.out.print("["+arr1[i]);
            } else if (i==arr1.length-1) {
                System.out.print(","+arr1[i]+"]");
            }else{
                System.out.print(","+arr1[i]);
            }

        }

结果: [11,22,33,44,55,66,77,888,999,189]

(2)获取数组中的最大值最小值

int[] arr = {11, 23, 31, 4, 12, 41, 11, 31, 4, 12, 41, 11};
        //1、默认第一个元素为最大值和最小值
        int maxNumber = arr[0];
        int minNumber = arr[0];
        //2、从第二个元素开始依次遍历,与最大值和最小值进行比较
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > maxNumber) {
                maxNumber = arr[i];
            }

            if (arr[i] < minNumber) {
                minNumber = arr[i];
            }
        }

        System.out.println("最大值为:" + maxNumber);
        System.out.println("最小值为:" + minNumber);


结果: 最大值为:41
            最小值为:4

(3)数组元素查找(查找指定元素第一次在数组中出现的索引)

        Scanner sc = new Scanner(System.in);
        System.out.print("请输入一个元素:");
        int numnber = sc.nextInt();
        int[] arr1 = {11, 22, 33, 44, 55, 66, 77, 888, 999, 11, 189, 999};
        boolean flag = true; // 定义标志位
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] == numnber) {
                System.out.println("该元素的索引为"+i);
                flag = false;
                break;
            }
        }
        if (flag) {
            System.out.println("没有该元素!!");
        }

结果:请输入一个元素:33
           该元素的索引为2

注意:

如果数组是String类型,要想比较内容值的话,String类中有一个方法equals方法。

使用方式:确定值的字符串.equals(被比较的字符串);

举例:比较字符串"java"与变量s1的值是否相等:

方式1:s1.equals("java")             不推荐 当s1为空的时候,会发生空指针异常

方式2:"java".equals(s1)                推荐   永远不会发生空指针异常

(4)综合题:

              某个公司采用公用电话传递数据信息,数据是小于8位的整数,为了确保安全, 在传递过程中需要加密,加密规则如下: 首先将数据倒序,然后将每位数字都加上5,再用和除以10的余数代替该数字, 最后将第一位和最后一位数字交换。 请任意给定一个小于8位的整数, 然后,把加密后的结果在控制台打印出来。

       int[] arr = {3, 4, 1, 2, 5, 2, 1, 2};
        System.out.println("逆序前:");
        printArray(arr);
        //1、
        int[] arr2 = niXu(arr);
//        System.out.println("逆序后:");
//        printArray(arr2);

        //2、
        for (int i = 0; i < arr2.length; i++) {
            //每位数字都加上5,用和除以10的余数
            arr2[i] = (arr2[i] + 5) % 10;
        }

        //3、
        //最后将第一位和最后一位数字交换
        int tmp = arr2[0];
        arr2[0] = arr2[arr2.length - 1];
        arr2[arr2.length - 1] = tmp;

        System.out.println("加密后:");
        printArray(arr2);


    }

    public static int[] niXu(int[] arr) {
        for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
            int tmp = arr[start];
            arr[start] = arr[end];
            arr[end] = tmp;
        }
        return arr;
    }

    public static void printArray(int[] arr) {
        for (int index = 0; index < arr.length; index++) {
            if (index == 0) {
                System.out.print("[" + arr[index] + ",");
            } else if (index == arr.length - 1) {
                System.out.println(arr[index] + "]");
            } else {
                System.out.print(arr[index] + ",");
            }
        }
    }

本题中逆序的思想是利用两个指针变量start,end不断向中间靠拢,不断交换两边的值,直到start大于等于end时,循环停止,此时两边的数据已全部交换完成,则逆序完成。

二.二维数组

1.二维数组:元素为一维数组的数组

2.如何定义一个二维数组:

                                            数据类型[][] 数组名;     (规范写法)

                                            数据类型[] 数组名[];

                                            数据类型 数组名[][];

                                            数据类型 [] [] 数组名;

                                            数据类型 [] 数组名 [];

3.如何创建一个二维数组:

3.1语句定义格式1:

数据类型[][] 变量名 = new 数据类型[m][n];

m:表示有多少个一维数组 n:表示每个一维数组的元素个数

举例:int[][] arr = new int[3][3] 表示二维数组中有三个一维数组的元素,每个一维数组的长度为3,元素的数据类型为int

演示:

        int[][] arr = new int[3][3];
        System.out.println(arr);    //二维数组的地址值
        System.out.println(arr[0]); // 第一个一维数组元素的地址值
        System.out.println(arr[1]); // 第二个一维数组元素的地址值
        System.out.println(arr[2]); // 第三个一维数组元素的地址值
        //获取第一个一维数组中的第二个元素值
        System.out.println(arr[0][1]);   //int类型默认值为0

3.2语句定义格式2:

数据类型[][] 变量名 = new 数据类型[m][];

演示:

        int[][] arr = new int[3][];
        System.out.println(arr[0]);       //null
        int [] arr1={1,2,3};
        int [] arr2={4,5,6};
        int [] arr3={7,8,9};
        arr[0]=arr1;
        arr[1]=arr2;
        arr[2]=arr3;
        //利用索引获取元素5
        System.out.println(arr[1][1]);

3.2语句定义格式3:

数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…}};

简化写法数据类型[][] 变量名 = {{元素…},{元素…},{元素…}};

演示:

//        int[][] arr = new int[][]{{11, 22, 33}, {1, 2, 3}, {100, 200, 300, 400}};
        int[][] arr = {{11, 22, 33}, {1, 2, 3}, {100, 200, 300, 400}};
        System.out.println(arr[2][1]);      //200

//        int[][] arr;
//        arr = new int[][]{{11, 22, 33}, {1, 2, 3}, {100, 200, 300, 400}};

4.二维数组的遍历:

  要求:以一维数组的形式打印在控制台  

  int[][] arr = {{11, 21, 31, 41}, {15, 16,17, 18}, {19, 17, 91, 12}};

        for (int i = 0; i < arr.length; i++) {       //遍历二维数组得到一维数组
            for (int j = 0; j < arr[i].length; j++) {        //遍历一维数组得到元素的值
                if(j==0){
                    System.out.print("["+arr[i][j]+",");
                } else if (j == arr[i].length - 1) {
                    System.out.print(arr[i][j]+"]");
                }else {
                    System.out.print(arr[i][j]+",");
                }
            }
            System.out.println();
        }

三.数组排序和二分查找

1.冒泡排序:

原理:冒泡排序就是从序列中的第一个元素开始,依次对相邻的两个元素进行比较,如果前一个元素大于后一个元素则交换它们的位置。如果前一个元素小于或等于后一个元素,则不交换它们;这一比较和交换的操作一直持续到最后一个还未排好序的元素为止。

图文演示:

代码演示:

        int [] arr = {34,23,43,22,22,321,74,224,64,28,54,65};
        for (int i = 1; i < arr.length; i++) {         //控制比较的轮次
            int j = 0;
            for (; j < arr.length-i; j++) {                 //控制每轮元素之间比较的次数
                if(arr[j]>arr[j+1]){
                    int bigNumber=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=bigNumber;
                }
            }
        }
        printArray(arr);

    }

    public static void printArray(int[] arr) {
        for (int index = 0; index < arr.length; index++) {
            if (index == 0) {
                System.out.print("[" + arr[index] + ",");
            } else if (index == arr.length - 1) {
                System.out.println(arr[index] + "]");
            } else {
                System.out.print(arr[index] + ",");
            }
        }
    }

结果:[22,22,23,28,34,43,54,64,65,74,224,321]

2.反转排序

即逆序,在上文中数组初始化练习中的综合题中提到,在此不在赘述

3.选择排序

算法原理:每次从待排序的数据元素选出最小(最大)的一个元素,顺序的放在一已排好序的数列的最后,直到全部待排序的数据元素排完;(可以参考上述冒泡图来理解)

代码演示: 

        int[] arr = {33, 22, 44, 11, 55,324,344,54,67,88,565,23,1};
        for (int i = 1; i < arr.length; i++) {       //控制比较的轮次
            int maxFlag = 0;
            for (int j = 1; j < arr.length - i + 1; j++,maxFlag++) {               //控制每轮比较的次数
                if (arr[j] > arr[maxFlag]) {
                    int tmp =arr[j];
                    arr[j]=arr[maxFlag];
                    arr[maxFlag]=tmp;
                }
            }

        }
        MaoPaoDemo.printArray(arr);

结果:[565,344,324,88,67,55,54,44,33,23,22,11,1]

3.二分查找

二分法查找(折半查找)操作:使用二分法查找有序数组中元素。找到返回索引,不存在输出-1。
-----------------------------------------
分析:二分法查找的前提是数组有序。!!!!!!!
-----------------------------------------
假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量
front,mid,end分别指向数据的上界,中间和下界,mid=(front+end)/2.
1)开始令front=0(指向3),end=7(指向88),则mid=3(指向36)。因为mid>x, 故应在前半段中查找。
2)令新的end=mid-1=2,而front=0不变,则新的mid=1。此时x>mid,故确定应在后半段中查找。
3)令新的front=mid+1=2,而end=2不变,则新mid=2,此时a[mid]=x,查找成功。
4)如要查找的数不是数列中的数,例如x=25,当第三次判断时,x>a[mid],按以上规律,令front=mid+1,即front=3,出现front>end的情况,表示查找不成功。

代码演示:

 int[] arr = {3, 12, 24, 36, 55, 68, 75, 88};
        int number = 18;
        int front = 0;
        int end = arr.length - 1;
        int mid = (front + end) / 2;

        boolean flag = true;
        while (front <= end) {
            if (number > arr[mid]) {
                front = mid + 1;
            } else if (number < arr[mid]) {
                end = mid - 1;
            } else {
                System.out.println("找到该元素,索引为:" + mid);
                flag = false;
                break;
            }

            //重新算中间位置
            mid = (front + end) / 2;
        }

        if (flag) {
            System.out.println("没有该元素!");
        }

  • 33
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值