Java自学随笔 - 关于数组概念理解

Part - 1

一堆数组:
特点:
1.数组是一种引用数据类型,不属于基本类型,父类是object
2.数组实际上是一个容器,可以同时容纳多个元素。
3.数组当中可以存储基本类型的数据,也可以存储引用数据类型的数据
4.数组因为是引用类型,所以数组对象是堆内存当中。
5.数组在内存方面,如图
在这里插入图片描述

对于数组当中如果存储的是java对象的话,实际存储的是对象的引用"内存地址"

6.在java中,数组被创立后便不可更改
7.数组的分类:一堆数组,二维数组,多维数组
8.所有的数组对象都有length属性(java自带),用来获取数组中的元素的个数。
9.java中的数组要求元素的数据类型统一,只能放同类型的数组
10.数组在内存方面存储的时候,数组中的元素的的内存地址是连续的
11.所有的数组都是以第一个元素的内存地址,作为整个数组对象的内存地址
12.数组中每一个元素都是有下标的,下标从0开始,以1底层,最后一个元素的下标是length-1

优点:
查询效率高,为什么高呢?
第一,每一个元素的内存地址是连续的
第二,每一个元素的类型相同,所以占用空间大小一样
第三,知晓第一个元素内存地址,又知道每一个元素占用空间的大小,又知道下标,所以通过数学表达式就可以计算某个下标元素的内存地址,直接通过内存地址定位元素
,所以数组的检索效率是最高的

缺点:
第一,不能存储大的数据量
第二,由于为了保证数组中每个元素的内存地址连续,所以在数组上随机操作或者增加元素的时候,效率较低,因为随机增删元素会涉及到后面元素同一向前或者向后唯一的操作。
PS:但是如果是对末尾元素增加,或者删除则不影响效率

Part - 2

数组定义方式:

  1. int [] arr = new int[5]
  2. char [] arr2 = {‘a’,‘b’,‘c’,};
  3. String [] arr3 = new String[]{“嘻嘻”,“哈哈”,“呵呵”};
    其中第三种命名方式比较特殊,这种命名方式可以用于无引用,匿名数组。
    不需要事先声明一个数组,而是直接在调用的时候直接传入,注意此时的
    方法()中的数组是没有指向某个内存地址的,直接常量输入的,如下:
public class Demo5 {
    public static void main(String []args){
         
   		ForPrint(new int []{3,5,6});
    }
    public static void ForPrint(int [] arr){
    	for(int i = 0; i < arr.length; i++){
    		System.out.println(arr[i]);
    	}
    }
}

PS:
数组是应用数据类型,数组的数据是储存在堆中,而在int [] arr所开辟
的内存空间中储存的是堆中的地址,也叫引用。如果当栈中储存的内存地址
丢失了,则会出现空指向的异常。
当 int [] arr = null;时,则意味着没有任何引用和指向;而对于基本数
据类型来说,是不会发生空指向问题的,因为他们的实际值时存放在栈中,
而不是存放在堆中。

Part - 3

将遍历数组的代码块变成一个可复用的方法.

public class Demo5 {
    public static void main(String []args){
        int i =10; //定义一个变量
        //定义一个整数类型的数组:
        //定义格式:数据类型[]数组名 = new 数据类型[];
        int [] arr = new int[4];
        arr[0] = 32;
        arr[1] = 32;
        arr[2] = 32;
        arr[3] = 32;
   		ForPrint(arr);
    }
    /*
    由于数组是引用的数据类型,所以在ForPrint方法中的形参
    应该写成int [] arr这种形式。
     */
    public static void ForPrint(int [] arr){
    	for(int i = 0; i < arr.length; i++){
    		System.out.println(arr[i]);
    	}
    }
}

Part - 4

数组的求极值:

public class Demo5 {
    public static void main(String []args){
        int [] arr = {12,4,5,78,94,24};
        int Result = GetMaxValue(arr)
    }
    public static int  GetMaxValue(int [] arr){
    	int MaxValue = -1;	//定义一个最大值的结果变量
    	//为了防止数组传递过来会有0长度,或者引用为空的情况
    	//一般先做判断
    	if(arr != null && arr.length != 0){
    		for(int i =0; i < arr.length; i++){
    			if(arr[i] > MaxValue){
    				MaxValue = arr[i];
    			}
    		}
    	}
    	return MaxVaue;
    }
}

Part - 5

冒泡排序:
通过画图来理解冒泡的排序的原理和过程如图:
在这里插入图片描述
可以发现当,前一个数<后面一个数时,则会进行交换
也就是Array[i]<Array[i+1], 两个数的值在数组位置中进行互换
当第一次比较完毕之后,第二次比较时,会去比较后面一个数和更后面的
的数,也就是比较的位置整体往后移一位,也就是Array[i+1] ,Array[i+2]
注意此时的Array[i+1]的值已经发生了改变,不在是第一次比较之前的值,而
是已经互换的值。由图中发现,当两两排序到最后末端元素时,第一波的两两比较
就完成了。但是可以看出数组的排序依然不对,所以进行第二波两两比较,在第二波两两比较前,我们发现数组中最小的值已经在最末尾,也就意味着
次末尾端的元素已经不需要在和它比较了。所以在这第二波比较次数可以减1
知道最后一波需要比较的次数为0了,则排序结束。

code如下:

public class Demo7 {
    public static void main(String []args){
        int [] ss = {4,5,6,7,8,10};
        BubbleSort(ss);
        for(int i = 0; i < ss.length;i++){
            System.out.print(ss[i] + "\n");
        }
    }
    public static void BubbleSort(int[] ss){
        if(ss != null && ss.length != 0){
            for(int i = 0; i < ss.length-1; i++){
                for(int j = 0; j < ss.length-i-1;j++){
                    if(ss[j] < ss[j+1]){
                        int tmp = ss[j+1];
                        ss[j+1] = ss[j];
                        ss[j] = tmp;
                    }
                }
            }
        }
    }
}

PS:在分析完排序原来自己写一遍时,自己所遇到的疑问。
1.数组内的元素任意排列,无论如何,第一波的两两比较久一定会将数组内
最小的元素排到最末尾么?自己随后任意定义了几个数组模拟了画图中的步骤
进行了排序,发现无论怎么打乱数组位置,最后的结果都是第一波比较后最小
的数会被排序到最末端。
2.交换元素位置,是优先是将大数复制给临时变量还是,小数复制给临时变量
通过已经跑通的代码
int tmp = ss[j+1]; int tmp = ss[j];
ss[j+1] = ss[j]; 修改后 ss[j] = ss[j+1];
ss[j] = tmp; ss[j+1] = tmp;
发现结果并没有变化,想了一想,可以从内存结构的角度来考虑
当int tmp = ss[j+1]时,是将ss[j+1]的值赋给的tmp,这个值是从
堆中取得,也就是说j+1位上的此时为默认值。然后ss[j+1] = ss[j],将j位的值赋了j+1位,此时j位上的值为默认值,然后通过开始已经
做好赋值的tmp,将其值赋给j位,由此达到值的交换。

Part - 6

数组的倒置:
倒置的关键点就是,对称交换。
第一次:Array[i] , Array[Array.length-1-0]
第二次:Array[i+1] , Array[Array.length-1-1]
第三次:Array[i+1+1] , Array[Array.length-1-2]
可以发现交换次数 和 最右端元素向对称中心靠近单位相关
那么可以理解为:
第一次:Array[0] , Array[Array.length-1-0]
第二次:Array[1] , Array[Array.length-1-1]
第三次:Array[2] , Array[Array.length-1-2]

然后使用临时变量进行位置调换即可实现

public class Demo8 {
    public static void main(String []args){
        int [] arr = {5,4,3,2,1};
        InvertArray(arr);
        for(int i = 0; i < arr.length; i++){
            System.out.println(arr[i]);
        }
    }
    public static void 	InvertArray(int [] arr){
        for(int i = 0; i <= arr.length/2-1; i++){
            //定义一个临时变量
            int tmp = arr[i];
            arr[i] = arr[arr.length-i-1];
            arr[arr.length-i-1] = tmp;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值