Java基础day04笔记:数组的常见操作|排序|查找|进制转换|二维数组

01-数组(静态初始化-常见问题)

        数组的定义方式:

        int[] arr=new int[2];

        或者

        int arr[]=new int[2];

        虽然两种都可以,但还是用第一种方式比较规范哦。

        还有一种定义方式:

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

        这种方式叫做静态初始化方式。创建了一个数组实体,并且给这个实体中的每一个位置都添加了元素。

        注意后面的方括号里不要写长度,因为写了长度容易出错~而且数字的个数和数值都已经列举出来了,再写长度也没有必要~

        它的简化形式为:

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

        一般在数据明确的情况下都可以用这种简化形式,数据不明确的话还是乖乖用第一种~

        例:

        int[] arr=new int[5];

        arr[0]=90;

        arr[1]=80;

        数组的一些常见问题:

        没有结果。

        但是编译的时候为什么没有错误提示呢?

        因为编译只检查语法错误,而到运行的时候,才会到堆内存当中去开辟一个数组空间,并分配0、1、2这三个角标,这时,当你想要打印3号角标的时候发现不存在,才会产生问题。

        所以运行的时候就会产生问题啦:  

        这个问题是:数组角标越界异常,具体哪个角标越界了,会显示在上面框出的那句话后面。

        红框框出来的那句话意思是:操作数组时,访问到了数组中不存在的角标。

        还有一种情况,也是编译时没有问题,运行时会报错:

        红框里的话报错内容为:空指针异常:当引用没有任何指向,值为null的情况时,该引用还用于操作实体。

    02-数组(常见操作-遍历)

        数组的操作:

        获取数组中的元素。通常会用到遍历。

        例:

        int[] arr=new int[3];

        for(int x=0;x<3;x++)

        {

                System.out.println("arr["+x+"]="+arr[x]+";");

        }

        用for循环,循环结束变量就消失啦,不再占用内存。

        数组中有一个属性可以直接获取到数组元素的个数。

        使用方式:数组名称.length=

        例:

        int[] arr={3,6,5,1,8,9,67};

        System.out.println("length:"+arr.length);

        for(int x=0;x<arr.length;x++)

        {

                System.out.println("arr["+x+"]="+arr[x]+";");

        }

        求和:

        int sum=0;

        for(int x=0;x<arr.length;x++)

        {

                sum+=arr[x];

                System.out.println("sum="+sum);

        }

        操作数组,通常都会用到for循环~

        一个例子:

        //定义功能:用于打印数组中的元素,元素间用逗号隔开。

        System.out.print("[");

        for(int x=0;x<arr.length;x++)

        {

                if(x!=arr.length-1)

                        System.out.print(arr[x]+",");

                else

                        System.out.print(arr[x]+"]");

        }

        运行下述语句会出现下述结果,说明把数组的地址给输出啦。

        System.out.println(arr);

    03-数组(常见操作-获取最值)

        获取数组中的最大值:

        思路:

        1,获取最值需要进行比较,每一次比较都会有一个较大的值,因为该值不确定。通过一个变量进行存储。

        2,让数组中的每一个元素都和这个变量中的值进行比较。

        如果大于变量中的值,就用该变量记录较大值。

        3,当所有的元素都比较完成,那么该变量中存储的就是数组中的最大值。

        步骤:

        1,定义变量。初始化为数组中任意一个元素即可。

        2,通过循环语句对数组进行遍历。

        3,在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量。

        需要定义一个功能来完成,以便提高复用性。

        1,明确结果,数组中的最大元素 int

        2,未知内容:一个数组,int[]

        public static int getMax(int[] arr)

        {

                int max=arr[0];

                for(int x=1;x<arr.length;x++)

                {

                        if(arr[x]>max)

                                max=arr[x];

                }

                return max;

        }

        获取最大值的另一种方式,可不可以将临时变量初始化为0呢?

        但是如果这个数组中全是负数,临时变量初始化为0就不可行。

        换一个思路,我们不仅可以将临时变量初始化为数组中的元素,也可以初始化为数组的角标。这样就可以将临时变量初始化为0啦。

        public static int getMax(int[] arr)

        {

                int max=0;

                for(int x=1;x<arr.length;x++)

                {

                        if(arr[x]>max)

                                max=x;

                }

                return arr[max];

        }

        获取最小值也是同理。

    04-数组(排序-选择排序)

        选择排序思想:

        以从小到大排序为例:

        先用0角标位置的元素依次和后面的元素相比,如果后面位置的元素比角标位置元素小,则将该位置元素与0角标位置元素做交换。比完所有元素之后,0角标位置存放的将是数组中的最小元素。接着,将1角标元素依次和后面的元素相比,......,1角标位置存放的将是数组中次小元素。依次类推,就可以排序完成。

        public static void selectSort(int[] arr)

        {

                for(int x=0;x<arr.length-1;x++)

                {

                        for(int y=x+1;y<arr.length-1;y++)

                        {

                                if(arr[x]>arr[y])

                                {

                                        int temp=arr[x];

                                        arr[x]=arr[y];

                                        arr[y]=arr[temp];

                                }

                        }

                }

        }


        两个问题:

        1,返回值类型,假设传进来的数组为a,那么操作原数组arr和操作a,其实都是在操作同一个数组实体,只是多个引用在操作同一个数组。因此不用返回a,因为arr和a都指向同一个数组。所以返回值类型为void。

        2,没有必要遍历到最后一个角标,因为最后只剩一个元素了,没有和它比的了~

        选择排序特点:

        内循环结束一次,最值出现在头角标位置上。

    05-数组(排序-冒泡排序)

        冒泡排序思想:

        相邻的两个元素进行比较,如果符合条件就换位。

        每循环一次,最值出现在最后位,最末一个元素下次就不参与循环了。

        小的元素往前跑,大的元素往后跑,这就是冒泡排序的思想。

        public static void bubbleSort(int[] arr)

        {

                for(int x=0;x<arr.length-1;x++)

                {

                        for(int y=0;y<arr.length-x-1;y++)//-x:让每一个比较的元素减少,-1:避免角标越界

                        {

                                if(arr[y]>arr[y+1])

                                {

                                        int temp=arr[y];

                                        int arr[y]=arr[y+1];

                                        int arr[y+1]=temp;

                                }

                        }

                }

        }

        选择和冒泡排序是面试中最经常被问到的,排序的代码写法有很多,这只是其中一种。如果需要排序的元素不多,可以采用上面这种写法,如果比较多,用这种写法效率就不高啦。

        优化的方法的思想:在比较的过程中,为了减少在堆内存中换位置的次数,则先不换位置,在栈内存中记录下每次比较的结果,当一个内循环结束后,确定了最末位置是最值后,直接将最后一次比较的元素进行交换即可。一次内循环下来,堆内存中就只换了一次位置。

        而在真实的Java开发中,我们不用选择也不用冒泡,我们用到的排序方法是Arrays.sort(arr);,这是Java怕我们不会排序,特意提供给我们的排序方法,哈哈~(import java.util.*;)

        这就意味着我们不用学选择排序和冒泡排序吗?

        不。

        我们依然要学,原因有两个:

        1,我们可以借此了解排序中的算法。

        2,应付面试。去面试,面试官说,来~写个冒泡排序~

    06-数组(排序-位置置换功能抽取)

        不管是什么排序方法,都有一个共性:都需要对满足条件的元素进行位置置换,所以我们可以把换位置这个功能提取出来,封装成一个函数。

        public static void swap(int[]arr,int a,int b)

        {

                int temp=arr[a];

                arr[a]=arr[b];

                arr[b]=temp;

        }

    07-数组(折半查找)

        //定义功能:获取key第一次出现在数组中的位置。如果返回是-1,那么代表该key在数组中不存在。  

        public static int getIndex(int[] arr,int key)

        {

                for(int x=0;x<arr.length;x++)

                {

                        if(arr[x]==key)

                        {

                                return x;//返回该元素的角标

                        }

                        return -1;//代表没有找到

                }

        }

        接下来介绍另外一种更有效率的查找方式:折半查找

        缩小范围的查找会使查找速度更快,但是这种查找方式要求数组必须是有序的。

        public static int halfSearch(int[] arr,int key)

        {

                int min,max,mid;

                min=0;

                max=arr.length-1;

                mid=(max+min)/2;

                if(arr[mid]!=key)

                {

                        if(key>arr[mid])

                                min=mid+1;

                        else if(key<arr[mid])

                                max=mid-1;

                        if(min>max)

                                return -1;

                        mid=(max+min)/2;

                }

                return mid;                

        }

        折半的第二种方式:

        public static int halfSerch_2(int[] arr,int key)

        {

                int min=0,max=arr.length-1,mid;

                while(min<=max)

                {

                        mid=(max+min)>>1;//也是除以2的意思

                        if(key>arr[mid])

                               min=mid+1;

                        else if(key<arr[mid])

                                max=mid-1;

                        else

                                return mid;

                }

                return -1;

        }

        练习:有一个有序的数组,想要将一个元素插入到该数组中,还要保证该数组是有序的。如何获取该元素在数组中的位置。

        min就是8最后要插入的位置。

        public static int getIndex_2(int[] arr,int key)

        {

                int min=0,max=arr.length-1,mid;

                while(min<=max)

                {

                        mid=(max+min)>>1;//也是除以2的意思

                        if(key>arr[mid])

                                min=mid+1;

                        else if(key

                                max=mid-1;

                        else

                                return mid;

                }

                return min;//其实和上面代码不同的部分就只是将return -1改成return min。

        }

        这段代码的思想是,在数组中寻找8的位置,如果存在,则将8插入在这个位置;如果不存在,则将8插入min这个位置。

    08-数组(十进制-二进制)

        十进制---->二进制:

        public static void toBin(int num)

        {

                StringBuffer sb=new StringBuffer();//先不要管这是什么数据类型,直到它可以存入数据就对啦

                while(num>0)

                {

                        //System.out.println(num%2);这样打出来是反的

                        sb.append(num%2);//将数据存入sb

                        num=num/2;

                }

                System.out.println(sb.reverse());//reverse为将sb反转,这样就正啦

        }

    09-数组(十进制-十六进制)

        十进制---->十六进制:

        思想:

        接下来用代码来体现:

        那么右移的循环次数应该是多少呢?因为是32位,所以最多右移8次~

        public static void toHex(int num)        

        {

                for(int x=0;x<8;x++)

                {

                        int temp=num&15;

                        if(temp>9)

                                System.out.println((char)(temp-10+'A'));

                        else

                                System.out.println(temp);

                        num=num>>>4;

                }

        }

        但这样输出是反哒,换个方法:

        public static void toHex(int num)

        {

                StringBuffer sb=new StringBuffer();

                for(int x=0;x<8;x++)

                {

                        int temp=num&15;

                        if(temp>9)

                                sb.append((char)(temp-10+'A'));

                        else

                                sb.append(temp);

                        num=num>>>4;

                }

                System.out.println(sb.reverse());

        }

    10-数组(查表法十进制-十六进制)

        什么叫查表法呢?

        即将这种一一对应关系先存到一个表里面去,后面再来查询这个表~

        查表法:将所有的元素临时存储起来,建立对应关系。

        每一次&15后的值作为索引去查建立好的表,就可以找到对应的元素。

        这样比-10+‘a’更方便好用。

        这个表怎么建立呢?

        可以通过数组的形式来定义。

        public static void toHex(int num)

        {

                char[] chs={'0','1','2','3'

                                ,'4','5','6','7'

                                ,'8','9','A','B'

                                ,'C','D','E','F'};

                //定义一个临时容器

                char[] arr=new char[8];//字符数组的默认初始化值是'\u0000',相当于一个空格

                int pos=arr.length;

                while(num!=0)//一旦num为0,说明有效位已经都右移完啦,前面的就都是0不用再取啦

                {

                        int temp=num&15;

                        //System.out.println(chs[temp]);

                        arr[--pos]=chs[temp];

                        num=num>>>4;

                }

                //存储数据的arr数组遍历

                for(int x=pos;x<arr.length;x--)//数据是从数组最后一位开始存的,打印的时候正着打就完全OK~

                {

                        System.out.print(arr[x]+",");

                }

        }

    11-数组(查表法十进制-二进制)

        //定义二进制的表

        char[] chs={'0','1'};

        //定义一个临时存储容器

        char[] arr=new char[32];//32个足够装啦

        //定义一个操作数组的指针

        int pos=arr.length;

        while(num!=0)

        {

                int temp=num&1;

                arr[--pos]=chs[temp];

                num=num>>>1;

        }

        for(int x=pos;x<arr.length;x++)

        {

                System.out.print(arr[x]);

        }

    12-数组(进制转换优化)

        我们发现两种进制转换之间有很多共性的过程,我们把这个过程抽取出来,封装到一个函数中~

        public static void trans(int num,int base,int offset)

        {

                if(num==0)

                {

                        System.out.println(0);

                        return;

                }

                char[] chs={'0','1','2','3'

                                ,'4','5','6','7'

                                ,'8','9','A','B'

                                ,'C','D','E','F'};

                char[] arr=new char[32];

                int pos=arr.length;

                while(num!=0)

                {

                        int temp=num&base;

                        arr[--pos]=chs[temp];

                        num=num>>>offset;

                }

                for(int x=pos;x<arr.length;x++)

                {

                        System.out.print(arr[x]);    

                }

        }

        然后要定义功能函数来调用它~

        /*

        十进制---->二进制

        */

        public static void toBin(int num)

        {

                trans(num,1,1);

        }

        /*

        十进制---->八进制

        */

        public static void toBa(int num)

        {

                trans(num,7,3);

        }

        /*

        十进制---->十六进制

        */

        public static void toHex(int num)

        {

                trans(num,15,4);

        }

    13-数组(二维数组)

        二维数组,可以理解为,数组中的数组。        

        初始化方式:

        int[][] arr=new int[3][4];//定义了名称为arr的二维数组, 二维数组中有3个一维数组,每个一维数组中有四个元素。   

        另一种初始化方式:

        int[][] arr=new int[3][];

        System.out.println(arr[0]);//结果为null        

二维数组的默认初始化值

        对它进行初始化:

        int[][] arr=new int[3][];

        arr[0]=new int[3];

        arr[1]=new int[1];

        arr[2]=new int[2];//对数组中的每一个小数组进行了手动初始化

        System.out.println(arr[0]);//结果为null     

这时在内存中的表示为:

        System.out.println(arr.length);//打印的是二维数组的长度 3;

        System.out.println(arr[0].length);//打印二维数组中第一个一维数组长度

        再一种初始化方式~:

        int[][] arr={{3,5,1,7},{2,3,5,8},{6,1,8,2}};

        int sum=0;

        for(int x=0;x<arr.length;x++)

        {

                for(int y=0;y<arr[x].length;y++)

                {

                        sum=sum+arr[x][y];

                }

                System.out.println("sum="+sum);

        }

    14-数组(二维数组练习)          

        这次课程的容量感觉比以前要小~概念少,代码多~

        所以完成的速度要比以前快一些~但依然成就感满满。继续加油,小楠楠( ˘ ³˘)♥

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容

  • 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔...
    开心的锣鼓阅读 3,318评论 0 9
  • 第四天 数组【悟空教程】 第04天 Java基础 第1章数组 1.1数组概念 软件的基本功能是处理数据,而在处理数...
    Java帮帮阅读 1,598评论 0 9
  • 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一...
    阿里高级软件架构师阅读 3,286评论 0 19
  • 文‖不俗小七 1. 民国二十三年,江南烟雨中,一个山河秀丽村庄,叫玲珑村。 故事也是在那一年开始。 ...
    不俗小七阅读 491评论 10 20
  • 又过了愉快的一天,可是,这个时候坐在这儿,感觉有点小遗憾,因为自己把手机放这儿充电,然后去楼下做吃的,却忽略了儿子...
    绪英阅读 145评论 2 1