自学Java随时放弃(十四 数组 ②)

发布于:2022-07-17 ⋅ 阅读:(388) ⋅ 点赞:(0)

在这里插入图片描述

四、数组操作时常见的问题

小白在写程序的时候,可能经常会面临报错提醒的问题,这个时候不要慌,也没必要烦躁,因为烦躁也没用。我们能做的正面动作,就是尽量把这些出现的错误提示记录下来,这样会大大节省以后找bug的时间,也是逐渐向大神晋级的垫脚砖。

(一)、数组索引越界

先写一段代码:

public class demon {
    public static void main(String[] args) {
       //定义第一个数组:
        int [] cc={1,2,3};

        System.out.println(cc[3]);
        
 }

}

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
	at demon.main(demon.java:6)

Process finished with exit code 1

Array Index Out Of Bounds Exception
数组索引越界,因为访问了不存在的索引。

在这段代码中,索引有3个,分别是0,1,2,没有索引为3的元素。

这种感觉,就相当于你在一栋只有三户的公寓里(101,102,103),非要找第四户(104),结果肯定找不到。

(二)、空指针异常

来看一段代码:

public class demon {
    public static void main(String[] args) {
       //定义第一个数组:
        int [] cc={1,2,3};
        cc=null;

        System.out.println(cc[2]);

 }

}
Exception in thread "main" java.lang.NullPointerException
	at demon.main(demon.java:7)

Process finished with exit code 1

Null Pointer Exception
空指针异常,因为数组已经不再指向堆内存,而你还用数组名访问元素。

在这段代码中,本来int [] cc后,系统在堆内存里new出一块空间,并分配了地址值给int [] cc,但是由于你强行把null 赋值给
int [] cc,导致该地址值丢失。

至于指针是啥,我后面会讲,现在请不要考虑这么费脑子的问题。

这里报错的感觉就好像是,一栋公寓,本来被政府分配好了一个名字——恒远地产,结果开发商不喜欢,非要改成自己喜欢的——翠花大楼,导致某度地图上只能通过翠花大楼找到该公寓,而找不到恒远地产

五、数组的常见操作

(一)、数组遍历

①、定义

所谓数组遍历,就是依次输出数组中的每一个元素。

如此说来,这不就是上一篇里咱们经常执行的动作吗?定义一个数组,然后依次输出其中的每一个元素。

public class demon {
    public static void main(String[] args) {
       //定义第一个数组:
        int [] cc={13,34,55,67,88};

        //输出元素
        System.out.println(cc);
        System.out.println(cc[0]);
        System.out.println(cc[1]);
        System.out.println(cc[2]);
        System.out.println(cc[3]);
        System.out.println(cc[4]);
    }
}
[I@1b6d3586
13
34
55
67
88

Process finished with exit code 0

虽然这种方法可行,但作为一个合格的懒惰的程序员,难道不觉得代码的重复率太高了吗?

想一个办法,既能降低代码重复率,又能达到题目要求。

提示:用之前学过的一种语句。

②、单个数组的遍历

????????

答案公布:可以使用循环语句来实现。

比如我们可以这样写:

public class demon {
    public static void main(String[] args) {
        //定义第一个数组:
        int [] cc={13,34,55,67,88};

        //循环语句
        for(int x=0;x<5;x++){
            System.out.println(cc[x]);
        }

        }
}

13
34
55
67
88

Process finished with exit code 0

是不是清爽了许多,也增加了代码的可读性。

但这里面还有一个问题,即 x的范围是如何得知的?即,x<5的这个数字是怎么界定的?

数出来的……吗?

o( ̄▽ ̄)d o( ̄▽ ̄)d o( ̄▽ ̄)d

给你点个赞,大聪明!

那麻烦下面这个数组,也请你帮我数一数:

int[] cc1={1,3,4,6,8,44,55,77,33,66,73,2,33,8,9,54,5,26,45,76,87,98,22,23,24,25,27,28,82,84,83,82,81,80,36,37,38,39,83,56,57,58,59};

在这里插入图片描述
很显然,总有一些数组,里面的元素是不能靠出来的。所以这时,数组也很贴心的给我们提供了一个属性length,专门用于获取数组的长度,具体格式如下:

数组名.length

所以上面例子里的数组长度,就可以这样得出:

public class demon {
    public static void main(String[] args) {
        //定义第一个数组:
        int[] cc1={1,3,4,6,8,44,55,77,33,66,73,2,33,8,9,54,5,26,45,76,87,98,22,23,24,25,27,28,82,84,83,82,81,80,36,37,38,39,83,56,57,58,59};

        //length
        System.out.println(cc.length);

    }
}
43

Process finished with exit code 0

就是说,这个数组里面有43个元素,因此,之前的例子可以这样改写:

public class demon {
    public static void main(String[] args) {
        //定义第一个数组:
        int [] cc={13,34,55,67,88};

        //循环语句
        for(int x=0;x<cc.length;x++){
            System.out.println(cc[x]);
        }

        }
}

③、多个数组的遍历

以上是针对单个数组的遍历,但当我们要对多个数组进行遍历时,同样面临代码重复率高的问题,这时同样需要用方法进行改进。

下面,我要对数组CC和CC1进行遍历。

首先明确两点:

第一、返回值类型——void;
第二、参数列表——int [] cc和 int [] cc1

代码如下所示:

public class demon {
    public static void main(String[] args) {
        //定义第一个数组:
        int[] cc = {13, 34, 55, 67, 88};
        int[] cc1 = {1, 3, 4, 6, 8, 44, 55, 77, 33, 66, 73, 2, 33, 8, 9, 54, 5, 26, 45, 76, 87, 98, 22, 23, 24, 25, 27, 28, 82, 84, 83, 82, 81, 80, 36, 37, 38, 39, 83, 56, 57, 58, 59};

        shuzu(cc);
        
        shuzu(cc1);

    }

    //方法
    public static void shuzu(int[] cc) {
        for (int x = 0; x < cc.length; x++) {
            System.out.println(cc[x]);
        }
       }
     }
13
34
55
67
88
1
3
4
6
8
44
55
77
33
66
73
2
33
8
9
54
5
26
45
76
87
98
22
23
24
25
27
28
82
84
83
82
81
80
36
37
38
39
83
56
57
58
59

Process finished with exit code 0

(二)、数组获取最值

①、定义

所谓获取最值,就是获取数组中的最大值或最小值

假设现在有一个数组:

int[] cc={23,76,45,65,11,86,51};

要求获取该数组中的最大值最小值

应该怎么做呢。

正常思维下,首先应找到一把标尺,然后将数组中的每一个元素,依次与其进行对比,找到最大和最小值。

但是这个标尺不能随便找,最简单有效的方法是,从数组里的元素里找。

比如我们可以将23这个元素作为临时标尺,比他大的留下,成为新标尺,比他小的扔回数组,以此类推,直到找出最大值

最小值也如法炮制,只不过反过来比较。

之所以不从外部寻找标尺,是因为可能会出现以下两种情况:

第一、找到的标尺比数组里所有元素都
第二、找到的标尺比数组里所有元素都

这样虽然能找到最大值或最小值,但这个值不属于该数组,答案无意义。

捋清思路后,关于数组获取最值的步骤就呼之欲出了。

②、步骤

第一步:定义一个数组,并对该数组的元素进行静态初始化;

第二步:从数组中任意找一个元素作为参照物(一般取第一个),默认该元素为最大值;

第三步:遍历其他元素,并依次和其他元素进行比较,如果大于参照物,就留下作为新参照物,若小,原参照物不变;

第四步:当数组内所有元素都参与比较后,参照物里面保存的元素就是最大值。

在这里插入图片描述
求数组 int[] cc={23,76,45,65,11,86,51}的最值

public class demon {
    public static void main(String[] args) {
        //定义第一个数组:
        int[] cc={23,76,45,65,11,86,51};

        //用第一个元素(编码为0)作为参照物:
        int max=cc[0];

        //遍历其他数组:
        for(int x=1;x<cc.length;x++){
            if (cc[x] >max){
                max=cc[x];
            }
        }
        System.out.println("max:"+max);
	}
}

max:86

Process finished with exit code 0

由于在以后的码农生涯中,我们会更多接触到方法这步分,所以上面的题,又可以改写为:

public class demon {
    public static void main(String[] args) {
        //定义第一个数组:
        int[] cc = {23, 76, 45, 65, 11, 86, 51};

        //调用
        int max = getmax(cc);
        System.out.println("max:"+max);
    }

    //方法改写
    public static int getmax(int[] cc) {
        //用第一个元素(编码为0)作为参照物:
        int max=cc[0];

        //遍历其他数组:
        for (int x = 1; x < cc.length; x++) {
            if (cc[x] > max) {
                max = cc[x];
            }
        }
        return max;
    }
}

max:86

Process finished with exit code 0

求最小值同理,只需要把max改成min就OK,具体代码此处略。

(三)、数组元素逆序

①、定义

所谓数组元素逆序,就是把原数组中的起始元素末尾元素进行互换,实现数组元素倒序存放的操作。比如数组12345,变成数组54321

②、步骤

根据上文中给出的定义,数组元素逆序的大体步骤,也就呼之欲出了。

第一步:定义一个数组,并进行静态初始化;

第二步:把索引为0的元素,和索引为数组名.length-1的元素进行交换;
把索引为1的数据,和索引为数组名.length-2的数据进行交换……

第三步:只需要交换到数组名.length/2的长度即可。

在这里插入图片描述
假设现在有一个数组:

int[] cc={2,13,23,55,56,7,18,77};

问题:请对该数组进行逆序操作。

根据前面总结的步骤,一般人的思路可能是这样:

//第一次交换:
int temp=cc[0];
cc[0]=cc[cc.length-1];
cc[cc.length-1]=temp;

//第二次交换:
int temp=cc[1];
cc[1]=cc[cc.length-2];
cc[cc.length-2]=temp;

//第三次交换:
int temp=cc[3];
cc[3]=cc[cc.length-3];
cc[cc.length-3]=temp;
………………………………………………

思路很清晰,但不会有人想这样一只写下去的。

通过仔细观察,上面代码中的cc.length-1cc.length-2cc.length-3可以改写为:

cc.length-1 = cc.length-1-0

cc.length-2 = cc.length-1-1

cc.length-3 = cc.length-1-2

那么这道题的代码,用方法写成:

public class demon {
    public static void main(String[] args) {
        //定义第一个数组:
        int[] cc={2,13,23,55,56,7,18,77};

        //调用
        System.out.println("顺序:");
        bianli(cc);
        System.out.println("逆序:");
        nixu(cc);
        bianli(cc);

    }
    //遍历
    public static void bianli(int[] cc) {
        for (int x = 0; x < cc.length; x++) {
            System.out.println(cc[x]);
        }
    }

    //逆序
    public static void nixu(int[] cc) {

        for (int x = 0; x < cc.length/2; x++) {
            int temp=cc[x];
            cc[x]=cc[cc.length-1-x];
            cc[cc.length-1-x]=temp;
            }
        }
}

顺序:
2
13
23
55
56
7
18
77
逆序:
77
18
7
56
55
23
13
2

Process finished with exit code 0

这道题的代码,有很多种写法,下面再介绍一种:

public class demon {
    public static void main(String[] args) {
        //定义第一个数组:
        int[] cc={2,13,23,55,56,7,18,77};

        //调用
        System.out.println("顺序:");
        bianli(cc);
        System.out.println("逆序:");
        nixu(cc);
        bianli(cc);

    }
    //遍历
    public static void bianli(int[] cc) {
        for (int x = 0; x < cc.length; x++) {
            System.out.println(cc[x]);
        }
    }

    //逆序
    public static void nixu(int[] cc) {

        for (int start = 0, end=cc.length-1;start<=end;start++,end--) {
            int temp=cc[start];
            cc[start]=cc[end];
            cc[end]=temp;
            }
        }

}

关于这道题,其实还有别的写法,但我实在懒得动脑筋了,大家可以自己开发,在此就不一一赘述。

Thanks♪(・ω・)ノ 观看

部分图片来自网络,侵权立删

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到