Java中数组的定义和使用(第二篇)

✅作者简介:大家好我是@每天都要敲代码,一位材料转码农的选手,希望一起努力,一起进步!
📃个人主页:@每天都要敲代码的个人主页
💬在我们学习的过程中,肯定需要刷题,巩固所学知识点;给大家推荐一款模拟面试、刷题神器,从基础到大厂面试题👉点击跳转刷题网站

🥅二维数组

    1、二维数组其实是一个特殊的一维数组,特殊在这个一维数组当中的每一个元素是一个一维数组。
    2、三维数组是什么?
        三维数组是一个特殊的二维数组,特殊在这个二维数组中每一个元素是一个一维数组。
        实际的开发中使用最多的就是一维数组。二维数组也很少使用。三维数组几乎不用。
    3、二维数组静态初始化
        int[][] array = {{1,1,1},{2,3,4,5},{2,3,4,5}};

package com.bjpowernode.javase.array; public class ArrayTest1 { public static void main(String[] args) { //对于一维数组 int[] array = {100,200,300};
        System.out.println(array.length); //3 //二维数组初始化 int[][] arr = {{1,2,3},{4,5,6},{6,7},{0}};
        System.out.println(arr.length); //4,看里面有几个一维数组 System.out.println(arr[0].length);// 3,第一个一维数组元素的个数 //取出二维数组的第一个一维数组,所以用一个一维数组进行接收 int[] a0 = arr[0]; //遍历这个一维数组 for (int i = 0; i < a0.length; i++) { //System.out.println(a0[i]); System.out.println(arr[0][i]); //与上面是等价的 }

    }
}

❤️二维数组的遍历

package com.bjpowernode.javase.array; public class ArrayTest2 { public static void main(String[] args) {
        String[][] array = {
                {"java", "oracle", "c++", "python", "c#"},
                {"张三", "李四", "王五"},
                {"lucy", "jack", "rose"}
        }; //二维数组的遍历 for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]+" ");
            }
            System.out.println();
        }
    }
}

❤️动态初始化二维数组

package com.bjpowernode.javase.array; public class ArrayTest3 { public static void main(String[] args) { // 1.动态初始化 int[][] arr = new int[3][4]; // 2.遍历 for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        } // 3.利用printArray方法遍历整个二维数组 int[][] a = {{1,2,3,44},{23,45,8},{55,99}}; //静态初始化 printArray(a); //第一种传参方法 printArray(new int[][]{{1,2,3,44},{23,45,8},{55,99}});//第二种传参方法 } //静态方法 public static void printArray(int[][] arr){ for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }

    }
}

🥅数组知识点总结

   1.1、数组的优点和缺点,并且要理解为什么。
        第一:空间存储上,内存地址是连续的。
        第二:每个元素占用的空间大小相同。
        第三:知道首元素的内存地址;通过下标可以计算出偏移量。
        通过一个数学表达式,就可以快速计算出某个下标位置上元素的内存地址,
        直接通过内存地址定位,效率非常高。

        优点:检索效率高。
        缺点:随机增删效率较低,数组无法存储大数据量。
        注意:数组最后一个元素的增删效率不受影响。

    1.2、一维数组的静态初始化和动态初始化
        静态初始化:       

 int[] arr = {1,2,3,4};
  Object[] objs = {new Object(), new Object(), new Object()};
动态初始化:    
    int[] arr = new int[4]; // 4个长度,每个元素默认值0     Object[] objs = new Object[4]; // 4个长度,每个元素默认值null
一维数组的遍历
 for(int i = 0; i < arr.length; i++){
            System.out.println(arr[i]);
        }
二维数组的静态初始化和动态初始化
        静态初始化:
    int[][] arr = {
                       {1,2,34},
                       {54,4,34,3},
                       {2,34,4,5}
                   };

     Object[][] arr = {
                          {new Object(),new Object()},
                          {new Object(),new Object()},
                          {new Object(),new Object(),new Object()}
                       };

        动态初始化:   

int[][] arr = new int[3][4];
Object[][] arr = new Object[4][4];
Animal[][] arr = new Animal[3][4]; //Person类型数组,里面可以存储Person类型对象,以及Person类型的子类型都可以 Person[][] arr = new Person[2][2];
....
二维数组的遍历   
 for(int i = 0; i < arr.length; i++){ // 外层for循环负责遍历外面的一维数组。             // 里面这个for循环负责遍历二维数组里面的一维数组。             for(int j = 0; j < arr[i].length; j++){
                System.out.print(arr[i][j]);
            }
            System.out.println();
        }
数组的拷贝:System.arraycopy()方法的使用
        数组有一个特点:长度一旦确定,不可变
        所以数组长度不够的时候,需要扩容,扩容的机制是:新建一个大数组,
        将小数组中的数据拷贝到大数组,然后小数组对象被垃圾回收。

🥅习题练习

❤️用数组模拟栈

编写程序,使用一维数组,模拟栈数据结构。要求:
        1、这个栈可以存储java中的任何引用类型的数据。
        2、在栈中提供push方法模拟压栈。(栈满了,要有提示信息。)
        3、在栈中提供pop方法模拟弹栈。(栈空了,也有有提示信息。)
        4、编写测试程序,new栈对象,调用push pop方法来模拟压栈弹栈的动作。
        5、假设栈的默认初始化容量是10.(请注意无参数构造方法的编写方式。)

栈可以存储java中的任何引用类型的数据该怎样定义?我们来通过下面这个简单例题来了解一下!

//一个栈可以存储java中的任何引用类型的数据=====>这个数组类型是Object // Object[] 这是一个万能的口袋,这个口袋中可以装任何引用数据类型的数据。 public class HomeworkStack { public static void main(String[] args) { // 注意:"abc" 这是一个字符串对象,字符串在java中有优待,不需要new也是一个对象。 // "abc" 字符串也是java对象,属于String类型。也可以new出来,例如: //String s = new String("abc"); String s = "abc"; //与上面是等价的 //--------定义为一个Object类型的数组进行村相互数据 Object[] obj = {new Husband(),new Wife(),"abc"}; for (int i = 0; i < obj.length; i++) {
            System.out.println(obj[i]);
        }
    }

} class Husband{

} class Wife{

}

具体代码实现:

//--------模拟栈的实现,具体代码 package com.bjpowernode.javase.array.homework; public class MyStack { // 为什么选择Object类型数组?因为这个栈可以存储java中的任何引用类型的数据 // new Animal()对象可以放进去,new Person()对象也可以放进去。因为Animal和Person的超级父类就是Object。 // 包括String也可以存储进去。因为String父类也是Object。 private Object[] object; // 栈帧,永远指向栈顶部元素 // 那么这个默认初始值应该是多少。注意:最初的栈是空的,一个元素都没有。 //private int sz = 0; // 如果index采用0,表示栈帧指向了顶部元素的上方。 //private int sz = -1; // 如果index采用-1,表示栈帧指向了顶部元素。 private int sz; //无参构造方法 public MyStack() { this.object = new Object[10]; this.sz= -1;
    } //push方法模拟压栈。(栈满了,要有提示信息。) public void push(Object obj){ //传过来是一个对象的地址 if(sz >= object.length-1){
            System.out.println("栈已满,压栈失败"); return;
        } //因为是从-1开始,要先sz++在压栈 sz++;
        object[sz] = obj; //也可以合并object[++sz] = obj System.out.println("压栈"+obj+"元素成功,栈帧指向"+sz);
    } //pop方法模拟弹栈。(栈空了,也有有提示信息。) public void pop(){ if(sz < 0){
            System.out.println("栈已空,弹栈失败"); return;
        }
        System.out.println("弹栈"+object[sz]+"元素成功");
        sz--;
        System.out.println("栈帧指向"+sz);
    } //set和get方法----这里实际上没有什么用处,也要写 public Object[] getObject() { return object;
    } public void setObject(Object[] object) { this.object = object;
    } public int getIndex() { return sz;
    } public void setIndex(int index) { this.sz = index;
    }

}
//测试程序 package com.bjpowernode.javase.array.homework; public class MyStackTest { public static void main(String[] args) { MyStack m = new MyStack(); //压栈 m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object());
        m.push(new Object()); //结束 m.push(new Object()); //弹栈 m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop();
        m.pop(); //结束 m.pop();

    }
}

❤️模拟酒店的订房退房功能

为某个酒店编写程序:酒店管理系统,模拟订房、退房、打印所有房间状态等功能。
    1、该系统的用户是:酒店前台。
    2、酒店使用一个二维数组来模拟。“Room[][] rooms;”
    3、酒店中的每一个房间应该是一个java对象:Room
    4、每一个房间Room应该有:房间编号、房间类型、房间是否空闲.
    5、系统应该对外提供的功能:
        可以预定房间:用户输入房间编号,订房。
        可以退房:用户输入房间编号,退房。
        可以查看所有房间的状态:用户输入某个指令应该可以查看所有房间状态。

⭐第一步:先抽出Room类

package com.bjpowernode.javase.array.homework.hotle; //酒店的房间 public class Room { private int id; // 房间号 private String type; // 房间的类型 private boolean status; // 房间的状态 //构造方法 public Room() {
    } public Room(int id, String type, boolean status) { this.id = id; this.type = type; this.status = status;
    } //setter and getter public int getId() { return id;
    } public void setId(int id) { this.id = id;
    } public String getType() { return type;
    } public void setType(String type) { this.type = type;
    } public boolean isStatus() { return status;
    } public void setStatus(boolean status) { this.status = status;
    } //重写toString方法 public String toString() { return "["+id+","+type+","+(status?"空闲":"占用")+"]";
    } //重写equals方法 public boolean equals(Object obj) { if(obj == null || !(obj instanceof Room)){ return false;
        } if(this == obj){ return true;
        } Room room = (Room)obj; return this.getId() == room.getId();
    }
}

⭐第二步:基于房间类写出酒店类

package com.bjpowernode.javase.array.homework.hotle; //酒店对象,酒店中有二维数组,二维数组模拟大厦 //假设一共有三层,一层单人间、二层标准间、三层总统套房,每层10个房间 public class Hotel { //酒店的房间是以二维数组的形式展现的 private Room[][] rooms; //构造方法 public Hotel() { //利用无参构造方法进行初始化 rooms = new Room[3][10]; //进行盖楼 //进行创建房间 for (int i = 0; i < rooms.length; i++) { for (int j = 0; j < rooms[i].length; j++) { if (i == 0) {
                    rooms[i][j] = new Room((i + 1) * 100 + (j + 1), "单人间", true);
                } else if (i == 1) {
                    rooms[i][j] = new Room((i + 1) * 100 + (j + 1), "标准间", true);
                } else if (i == 2) {
                    rooms[i][j] = new Room((i + 1) * 100 + (j + 1), "豪华间", true);
                }
            }
        }

    } //打印房间状态 public void print(){ for (int i = 0; i < rooms.length; i++) { for (int j = 0; j < rooms[i].length; j++) {
                System.out.print(rooms[i][j]); //默认调用toString()方法 }
            System.out.println();
        }
    } //订房 public void order(int roomId){ //通过房间号,转换成对应的二维数组 //rooms[roomId/10+1][roomId%10+1].setStatus(false); Room room = rooms[roomId/100-1][roomId%100-1]; if(room.isStatus()){
            room.setStatus(false);
            System.out.println("已成功订房");
        }else{
            System.out.println("房间已被占用,订房失败");
        }
    } //退房 public void exit(int roomId){ Room room = rooms[roomId/100-1][roomId%100-1];
        room.setStatus(true);
        System.out.println("已成功退房");
    }
}

⭐第三步:测试程序

package com.bjpowernode.javase.array.homework.hotle; //----学会进行拆分:从一个单房间---》到整个酒店---》测试程序 import java.util.Scanner; public class SystemHotels { public static void main(String[] args) { /*Room room = new Room(101,"单人间",true);
        Room room1 = new Room(102,"单人间",true);
        System.out.println(room.equals(room1));
        System.out.println(room);*/ //创建酒店对象 Hotel hotel = new Hotel(); //界面处理 System.out.println("欢迎使用酒店管理系统,请认真阅读使用说明");
        System.out.println("请输入对应的功能标号:[1]看到房间状态,[2]订房,[3]退房,[0]退出系统"); Scanner s = new Scanner(System.in); while(true){
            System.out.print("请输入功能编号:"); int i = s.nextInt(); if(i == 1){ //查看房间状态 hotel.print();
            }else if(i == 2){ //订房 System.out.print("请输入住房房间编号:"); int roomId = s.nextInt();
                hotel.order(roomId);
            }else if(i == 3){ //退房 System.out.print("请输入退房房间编号:"); int roomId = s.nextInt();
                ho***it(roomId);
            }else if(i == 0){ //退出系统 System.out.println("退出程序"); break;
            }else{ //选择错误 System.out.println("选择错误,请重新选择");
            }
        }
    }

}

🥅查找和排序算法

2.1、常见的算法:

        排序算法:冒泡排序算法、选择排序算法

        查找算法:二分法查找
        以上算法在以后的java实际开发中我们不需要使用的。因为java已经封装好了,直接调用就行。但面试可能会考!
2.2、算法实际上在java中不需要精通,因为java中已经封装好了,
       要排序就调用方法就行。例如:java中提供了一个数组工具类:Arrays(java.util)

      Arrays是一个工具类。其中有一个sort()方法,可以排序,例如:Arrays.sort(arr);。静态方法,直接使用类名调用就行。

2.3、怎么查找Arrays工具类?

      双击shift---》输入Arrays--->选择Classes---》找到Arrays(java.util)

编辑

❤️直接调用封装好的工具类来排序

package com.bjpowernode.javase.array; import java.util.Arrays; //使用Sun公司提供的数组工具类:java.util.Arrays; public class ArraysSort01 { public static void main(String[] args) { //数组 int[] arr = {11,5,7,3,9,2}; //排序;工具当中的方法大部分都是静态的,直接调用 Arrays.sort(arr); //打印输出 for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" "); //2 3 5 7 9 11 }
    }
}

❤️冒泡排序算法

冒泡排序对于n个数据总共要循环n-1次,每次需要比较n-1-i个数据

package com.bjpowernode.javase.array; //冒泡排序算法 public class BubbleSort { public static void main(String[] args) { int[] arr = {1,2,3,4,5,6}; //冒泡排序 int count = 0;// 用来统计比较次数 int sum = 0; //用来统计交换次数 //-----------第一种写法 for (int i = 0; i < arr.length-1; i++) { int flag = 1; //如果第二次循环flag还是1说明后面已经有序了 for (int j = 0; j < arr.length-i-1; j++) {
                count++; //统计比较次数 if(arr[j]>arr[j+1]){ int tmp = arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=tmp;
                    sum++; // 统计交换次数 flag = 0;
                }
            } if(flag == 1){ //说明后面就是有序的,就不用在交换了 break;
            }
        }
        System.out.println("比较次数是:"+count);
        System.out.println("交换次数是:"+sum); //-----------第二种写法 /* for (int i = arr.length-1; i >0; i--) {
            for (int j = 0; j < i; j++) {
                if(arr[j]>arr[j+1]){
                    int tmp = arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=tmp;
                }
            }
        }*/ //打印 for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

}

❤️选择排序算法

(1) 每一次从这堆“参与比较的数据当中”找出最小值,拿着这个最小值和“参与比较的这堆最前面的元素”交换位置。

(2)选择排序比冒泡排序好在:每一次的交换位置都是有意义的。

        关键点:选择排序中的关键在于,你怎么找出一堆数据中最小的。
(3)选择排序每次循环结束后都能确定一个元素的位置   

(4)选择排序比冒泡排序的效率高;高在交换位置的次数上;选择排序的交换位置是有意义的;循环一次,然后找出参加比较的这堆数据中最小的,拿着这个最小的值和最前面的数据“交换位置”。

例如:参与比较的数据:3 1 6 2 5 (这一堆参加比较的数据中最左边的元素下标是0)
(1)第1次循环之后的结果是:1 3 6 2 5 

    参与比较的数据:3 6 2 5 (这一堆参加比较的数据中最左边的元素下标是1)

(2)第2次循环之后的结果是:2 6 3 5 

    参与比较的数据:6 3 5 (这一堆参加比较的数据中最左边的元素下标是2)
(3)第3次循环之后的结果是:3 6 5 

    参与比较的数据:6 5 (这一堆参加比较的数据中最左边的元素下标是3)

(4)第4次循环之后的结果是:5 6

注意:5条数据,循环4次。

(5)重要结论:冒泡排序和选择排序最本质的区别是,比较次数没变,交换次数后者更小

package com.bjpowernode.javase.array; //选择排序 public class SelectSort { public static void main(String[] args) { int[] arr = {9, 8, 10, 7, 6, 0, 11}; int count = 0; // 比较次数 int sum = 0; // 交换次数 //n个数据需要循环n-1次 for (int i = 0; i < arr.length-1; i++) { //每次循环,都能确定一个数据的位置,所以要比较的数据都少1个 //假设每次比较起点i下标位置上的元素是最小的。 int min = i; for (int j = i+1; j < arr.length; j++) {
                count++; if(arr[j]<arr[min]){
                    min = j;
                }
            } // 当i和min相等时,表示最初猜测是对的。 // 当i和min不相等时,表示最初猜测是错的,有比这个元素更小的元素, // 需要拿着这个更小的元素和最左边的元素交换位置。 if(min != i){ int tmp = arr[min];
                arr[min] = arr[i];
                arr[i] = tmp;
                sum++;
            }
        }
        System.out.println("比较次数:"+count); //21 System.out.println("交换次数:"+sum); //5 //遍历 for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }

    }
}

❤️二分查找

1、遍历查找,一个一个找

package com.bjpowernode.javase.array;

public class ArraySearch {
    public static void main(String[] args) {
        int[] arr = {9,4,6,3,2,1};
        //封装成函数
        int index = arraySearch(arr,1);
        System.out.println(index == -1?"该元素不存在":"该元素下标是:"+index);
    }

    public static int arraySearch(int[] arr, int i) {
        for (int j = 0; j < arr.length; j++) {
            if(arr[j] == i){
                return j;
            }
        }
        return -1;
    }


}

2、利用二分查找

第一:二分法查找建立在有序的基础之上。
第二:二分法查找效率要高于“一个挨着一个”的这种查找方式。
第三:二分法查找原理?
       例如: 10(0下标) 23 56 89 100 111 222 235 500 600(下标9) arr数组    
       (1)目标:找出222的下标
            (0 + 9) / 2 --> 4(中间元素的下标)
           arr[4]这个元素就是中间元素:arr[4]是 100;100 < 222
           说明被查找的元素在100的右边;那么此时开始最左边的下标变成:4 + 1

       (2)   (5 + 9) / 2 --> 7(中间元素的下标):arr[7] 对应的是:235;235>222
            说明被查找的元素在235的左边;开始最右边下标进行了转变:7-1
       (3)   (5+6) / 2 --> 5;arr[5] --> 111 ;111<222
              说明被查找的元素在111的右边;那么此时开始最左边的下标变成:5 + 1
         (4)    (6+6) / 2 --> 6
            arr[6]是222,正好和222相等,此时找到了。

package com.bjpowernode.javase.array; //二分查找 public class BinarySearch { public static void main(String[] args) { int[] arr = {13,15,17,23,25,27,28,55}; int index = binarySearch1(arr,27);
        System.out.println(index==-1?"没找到":"找到了,下标是"+index);
    } public static int binarySearch1(int[] arr, int i) { int left = 0; int right = arr.length-1; while(left <=right ){ int mid = (left+right)/2; if(arr[mid]>i){ //说明在mid的左边,right = mid-1 right = mid-1;
            }else if(arr[mid]<i){ //说明在mid的右边,left = mid+1 left = mid+1;
            }else{ return mid;
            }
        } return -1;
    }
}

❤️Arrays工具类的使用

1、怎么查找对应封装好的方法?
   双击shift---》输入Arrays(java.util.Arrays)---》ctr+F12就可以查找到里面对应的方法

2、java.util.Arrays工具类。
    所有方法都是静态的,直接用类名调用;主要使用的是两个方法:二分法查找,排序
    以后要看文档,不要死记硬背!

package com.bjpowernode.javase.array; import java.util.Arrays; public class ArraysTest { public static void main(String[] args) { int[] arr = {3,6,5,12,1,2,32,5,5}; //1.排序 Arrays.sort(arr); //遍历打印 for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println(); //2.二分查找 int index = Arrays.binarySearch(arr,55);
        System.out.println(index==-10?"该元素不存在":"该元素下标是:"+index);

    }
}

结束语

今天的分享就到这里,想要提升编程思维的,快快去注册牛客网开始刷题吧!各种大厂面试真题在等你哦!

 💬刷题神器,从基础到大厂面试题👉点击跳转刷题网站

#java#
全部评论

相关推荐

04-18 00:32
已编辑
中南大学 Java
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务