JavaSE之数组复习

一维数组

介绍

  • 数组是一种引用类型
  • 数组是一种简单的数据结果,线性的结构
  • 数组是一种容器,可以来存储其他元素,数组是可以存储任意数据类型的元素。
  • 数组可以分为:一维数组、二维数组、三维数组
  • 数组中存储的元素类型必须是统一的
  • 数组一旦创建,长度是固定的,如果想要增加元素,需要扩容,但是也是新的数组,不是原有的数组

静态初始化数组

静态初始化的相关图解

动态初始化数组

int[] a1 = new int[4];
//初始化数组长度为4,里面的数据默认是0,做修改就直接a[1] = 2
//注意:如果定义完对象类型的数组后,要输出用println,这样底层会有一个三目运算,当为空的时候返回null,而不会报空指针异常,如果直接toString输出的话,会报空指针异常

总结:

  • 栈中,a1保存的是堆中数组的首元素地址
  • 数组的排列顺序是有规律的,造成的优点就是查找很快,因为查找时计算的就是首元素到偏移量的,但是这样造成的就是增删的效率就慢了(缺点),因为增删会影响原有的数组有序,修改的效率也很快。
  • 如果数组中存储的是对象,那么在堆中的这个数组,保存的就是对象的地址。
  • 取出数组中最后一个元素就是使用a[a.length-1]
  • 由于数组中存储的类型是一致的,所以每一个元素中在数组中存储所占的空间大小是一样的。

什么时候使用动态初始化?什么时候使用静态初始化?

其实没有本质区别,无论是动态初始化还是静态初始化,最终的内存分布都是一样的。

如果在创建数组的时候,知道数组中存的数据,这个时候当然采用静态的。当不知道的时候,先去开辟空间。

instanceof关键字

class Animal {
 
}

public class Cat extends Animal{
     void eat(){
         System.out.println("小猫吃~");
     }
}

public class Dog extends Animal{
     void move(){
         System.out.println("小狗跑~");
     }
}

题目:如果把cat和Dog的对象放在数组中,怎么判断是用eat还是move?

//创建一个数组
Animal[] as = new Animal[4];

//给每个元素赋值
Dog d1 = new Dog();
Dog d2 = new Dog();
Cat c1 = new Cat();
Cat c2 = new Cat();

as[0] = d1;
as[1] = d2;
as[2] = c1;
as[3] = c2;
//需求,遍历数组,如果是dog执行move,如果是cat执行eat
for(int i = 0;i<as.length;i++){
    Animal a = as[i];
    if(a instanceof Cat){
        //强制类型转换
        Cat c = (Cat)a;
        c.eat;
    }else{
        Dog d = (Dog)a;
        d.move();
    }
}

关于main方法中的数组的参数args

public class Test{
    public static void main(String[] args){
        
    }
}

//这个String[] args就是在java运行的时候,可以提供参数
//参数格式: java Test szw 123456
//这个就是代表数组中存放了szw和123456,中间用空格空开

关于数组的拷贝,这个也可以用到扩容

静态方法进行初始化拷贝
public class Test{
    public static void main(String[] args){
        //System.arrayCopy(原数组,原数组的开始下标,目标数组,目标数组的开始下标,拷贝的长度);
        int[] src = {1,2,3,4};
        int[] target = {9,9,3,9,9,9};
        //把src数组从下标0开始的4长度拷贝到target数组中从三开始
        System.arrayCopy(src,0,target,2,4);
    }
}

二维数组

特点

  • 二维数组是一个特殊的一维数组
  • 特殊的一维数组,特殊在一个一维数组中的每一个元素都是一个一维数组
public class Test{
    public static void main(String[] args){
        //静态初始化一个二维数组
        int[][] a = {
            {1,2,3},
            {11,22,33},
            {0,3,4},
            {11,32}
        };
       //所以如果输出a.length,就是4
        //需求,不管二维数组的定义,请输出最后一个32
        System,out.println(a[a.length-1],[a[a.length-1].length-1]);
       
    }
}

冒泡排序

思路分析

冒泡排序分析

注意:就是每一趟排序的时候,次数都会减一,第一趟排序时数组的长度减一!

代码实现

//只有一遍的冒泡排序
@Test
public void BubbleTest(){
    int arr[] = {3,9,11,-1,-2};//先定义数组
    //定义临时变量
    int temp = 0;
    for (int i = 0; i < arr.length -1 ; i++){
        if (arr[i] > arr[i+1]){
            temp = arr[i+1];
            arr[i+1] = arr[i];
            arr[i] = temp;
        }
    }
    System.out.println("第一遍排序后的结果"+ Arrays.toString(arr));
}
//我们在进行第二遍、第三遍往后的排序中,代码的主体不变,只有i<arr.length-1变化了,那么可以更改为以下

@Test
public void BubbleTest(){
    int arr[] = {3,9,11,-1,-2};//先定义数组
    //定义临时变量
    int temp = 0;
    for (int i = 0; i< arr.length - 1; i++){
        for (int j = 0; j < arr.length -1 - i ; j++){
            if (arr[j] > arr[j+1]){
                temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
        System.out.println("第"+(i+1)+"遍排序后的结果"+ Arrays.toString(arr));
    }
}
}

//优化!
//优化的作用就是当两趟的排序一样,没有发生变化,就可以停止排序了,这样节省了一部分时间
@Test
public void BubbleTest(){
    int arr[] = {3,9,11,-2,-1};//先定义数组
    //定义临时变量
    int temp = 0;
    Boolean flag = false;
    for (int i = 0; i< arr.length - 1; i++){
        for (int j = 0; j < arr.length -1 - i ; j++){
            if (arr[j] > arr[j+1]){
                temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = temp;
                flag = true;
            }
        }
        if (!flag){
            break;
        }else{
            flag = false;//重置
        }
        System.out.println("第"+(i+1)+"遍排序后的结果"+ Arrays.toString(arr));
    }
}
}

选择排序

基本思想

在一组数组中,找到最小的一个值,和第一个做交换。然后继续找到第二个最小的值,与第二个值进行一个交换。

选择排序分析

注意:每次排序之后,交换的那个位置不再进行下一次的排序,因为他已经是当前位置最小的数据了。

代码实现

//第一遍选择排序   
@Test
    public void SelectTest(){
        int[] arr = {101,34,119,1};

        int min = arr[0];//假设最小值是数组中的第一个
        int minIndex = 0;//最小的下标就是0

        for (int i = 1; i<arr.length;i++){
            if (min > arr[i]){//如果在第一个数据之后有比假设的最小值要小的话,就把那个值变成最小值存放在min中
                min = arr[i];
                minIndex = i;
            }
        }
        //一遍之后,肯定找到了最小值,把第一个数据与最小值进行一个交换
        arr[minIndex] = arr[0];//把最小值的值与a[0]进行一个交换
        arr[0] = min;//让a[0]成为最小值
        System.out.println("第一次排序后"+ Arrays.toString(arr));
    }
}


//正式代码
@Test
    public void SelectTest(){
        int[] arr = {101,34,119,1};


        for (int i = 0;i<arr.length-1;i++){
            int minIndex = i;
            int min = arr[i];
            //先查找最小值,与一开始定义最小值做比较,注意这里不是交换真正的值,只是把值存入min中
            for (int j = i+1;j<arr.length;j++){
                if (min > arr[j]){//说明假定的最小值,并不是最小值
                    min = arr[j];
                    minIndex = j;
                }
            }
            if (minIndex != i){//这时候才做有用的交换
                arr[minIndex] = arr[i];//minIndex就是当前最小的那个数的原始位置
                arr[i] = min;
            }
            System.out.println("第"+(i+1)+"轮排序后"+Arrays.toString(arr));


        }
    }

二分查找

import org.junit.Test;

public class Test1 {

    @Test
    public void test(){
        int[] a = {10,19,21,33,90};//注意二分查找需要的数组必须是有序的
        int target  = 99;
        int index = twoFind(a, target);
        System.out.println((index == -1)?"元素不存在!":"在数组中的下标是"+index);
    }

    //二分查找
    public static int twoFind(int[] a,int target){
        //形参是传来一个数组还有待查元素,返回待查元素的在数组中的下标
        int index = 0;
        int end = a.length-1;

        //这里就是为了防止数组下标越界
        while (index <= end){
            int middle = (index+end) / 2;

            if (target == a[middle]){
                return middle;
            }else if (target > a[middle]){
                index = middle + 1;//注意这里的加一和下面的减一
            }else if (target < a[middle]){
                end = middle - 1;
            }
        }
        //while循环完了还没有找到,就代表没有找到该元素
       return -1;
    }
}
//关于Arrays中的两个方法

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