• 【java进阶06:数组】使用一维数组模拟栈数据结构 使用二维数组模拟酒店,酒店管理系统 Arrays工具类 冒泡排序算法、选择排序算法、二分法


    目录

    数组

    二维数组

    总结

    作业

    Arrays工具类


    数组

    1. 数组总结 及 静态初始化一维数组

      在这里插入图片描述

      1. /*
      2. Array:
      3. 1、java语言中的数组是一种引用数据类型,不属于基本数据类型,数组的父类是Object
      4. 2、数组实际上是一个容器,可以同时容纳多个元素(数组是一个数据的集合)
      5. 数组:字面意思是“一组数据”
      6. 3、数组当中可以存储“基本数据类型”的数据,也可以存储“引用数据类型”的数据
      7. 4、数组因为是引用类型,所以数组对象存储在 堆内存 中
      8. 5、数组当中如果存储的是“java对象”的话,实际上存储的是对象的“引用(内存地址)”
      9. 数组中不能直接存储“java对象”
      10. 6、数组一旦创建,在java中规定,长度不可变。(数组长度不可变)
      11. 7、数组的分类:一维数组、二维数组、三维数组、多维数组。(一维数组较多,二维数组偶尔使用)
      12. 8、所有的数组对象都有length属性(java自带的),用来获取数组中元素的个数
      13. 9、java中的数组要求数组中元素的类型统一,如:int类型的数组只能存储int类型,Person类型数组只能存储Person类型
      14. 例如:超市购物,购物袋中装了苹果,就只能装苹果,不能再装橘子。(数组中存储的元素类型统一)
      15. 10、数组在内存方面存储的时候,数组元中元素的内存地址是连续的(存储的每一个元素都是有规则的挨着排列的)
      16. 内存地址连续
      17. 11、所有的数组都是拿“第一个方框中的内存地址”作为整个数组对象的内存地址。
      18. (数组中首元素的内存地址作为整个数组对象的内存地址)
      19. 12、数组中每一个元素都是有下标的,下标从0开始,以1递增,最后一个元素下标是length-1.
      20. 下标非常重要,因为我们对数组中元素进行“存取”的时候,都需要通过下标来进行。
      21. 13、数组这种数据结构的优点和缺点是什么?
      22. 优点:查询/查找/检索某个下标上的元素时效率极高。可以说是查询效率最高的一个数据结构
      23. 为什么效率高?
      24. 1、每一个元素的内存地址在空间存储上是连续的
      25. 2、每一个元素类型相同,所以占用空间大小一样
      26. 3、知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址,直接通过内存地址定位元素,所以数组的检索率是最高的。
      27. 数组中存储100个元素,或存储100万个元素,在元素查询/检索方面,效率是相同的。因为数组中元素查找的时候不会一个一个找,是通过数学表达式计算出来的(算出一个内存地址,直接定位的)
      28. 缺点:
      29. 1、由于为了保证数组中每个元素的内存地址连续,所以在数组上随机增加/删除元素时,效率较低,
      30. 因为随机增删会涉及到后面元素统一向前或向后位移的操作。
      31. 2、数组不能存储大数据
      32. 因为很难在内存空间上找到一块特别大的连续的内存空间。
      33. 注意:对于数组中最后一个元素的增删,是没有效率影响的。
      34. 14、怎么声明/定义一个一维数组
      35. 语法格式:
      36. int[] array1;
      37. double[] array2;
      38. boolean[] array3;
      39. String[] array4;
      40. Object[] array5;
      41. 15、怎么初始化一个一维数组?
      42. 包括两种方式:静态初始化一维数组,动态初始化一维数组。
      43. 静态初始化语法格式:
      44. int[] array = {100,2100,200,30};
      45. 动态初始化语法格式:
      46. //初始化一个5长度的int类型数组,每个元素默认值:0
      47. int[] array = new int[5]; //这里的5表示数组的元素个数。
      48. //初始化一个6个长度的String类型数组,每个元素默认值:null
      49. String [] names = new String[6]
      50. */
      51. public class ArrayText01 {
      52. public static void main(String[] args){
      53. //声明一个int类型的数据,使用静态初始化的方式
      54. int[] ii = {1,100,200,30,49,500};
      55. //这是C++风格,虽然可以运行,但不建议在java中使用。
      56. //int i[] = {1,100,200,30,49,500};
      57. //所有的数组对象都有length属性
      58. System.out.println("数组i中元素的个数:"+ii.length);
      59. //数组中每一个元素都有下标,通过下标堆数组中的元素进行存和取。
      60. //取(读)
      61. System.out.println("i数组中 第一个元素"+ii[0]);
      62. System.out.println("i数组中 最后一个元素"+ii[5]);
      63. System.out.println("i数组中 最后一个元素"+ii[ii.length-1]);
      64. //存(改)
      65. ii[0] = 111;
      66. ii[ii.length-1] = 888;
      67. System.out.println("i数组中 第一个元素"+ii[0]);
      68. System.out.println("i数组中 最后一个元素"+ii[5]);
      69. //一维数组 取遍历
      70. for(int i = 0;i < ii.length;i++){//i<6,取到5就停止了。
      71. System.out.println("ii数组中第"+(i+1)+"个元素:"+ii[i]);// i是从 0 到 5,是下标
      72. }
      73. //下标为6表示第七个元素,第七个元素没有,下标越界了,会出现什么异常呢?
      74. //System.out.println(ii[6]);//ArrayIndexOutOfBoundsException 下标越界异常
      75. //从最后一个元素遍历到第一个元素。
      76. for(int i =ii.length-1 ; i>=0 ;i--){
      77. System.out.println("ii数组中第"+(i+1)+"个元素:"+ii[i]);
      78. }
      79. }
      80. }
    2. 动态初始化一维数组,以及何时使用静态/动态初始化数组的方式。

      在这里插入图片描述

      1. /*
      2. 关于每个类型的默认值
      3. 数据类型 默认值
      4. ------------------------------------
      5. byte 0
      6. short 0
      7. int 0
      8. long 0L
      9. float 0.0F
      10. double 0.0
      11. boolean false
      12. char \u0000
      13. 引用数据类型 null
      14. 什么时候采用静态初始化方式,什么时候采用动态初始化方式?
      15. 当创建一个数组时:
      16. 确定数组中存储哪些具体的元素时,采用静态初始化的方式。
      17. 不确定将来数组中存储哪些数据,可以采用静态初始化的方式,预先分配空间。
      18. */
      19. public class ArrayText02 {
      20. public static void main(String[] args){
      21. //声明/定义一个数组,采用动态初始化的方式创建
      22. int[] ii = new int[4]; //创建一个长度为4的int数组,数组中每个元素的默认值是0
      23. //遍历数组
      24. for (int i = 0 ; i < ii.length ; i++) {
      25. System.out.println("ii数组中下标为"+i+"的元素是:"+ii[i]);
      26. }
      27. //后期赋值
      28. ii[0] = 111;
      29. ii[1] = 222;
      30. ii[2] = 333;
      31. ii[3] = 444;//注意下标不要越界
      32. for (int i = 0 ; i < ii.length ; i++) {
      33. System.out.println("ii数组中下标为"+i+"的元素是:"+ii[i]);
      34. }
      35. //初始化一个Object类型的数组,采用动态初始化方式
      36. Object[] objs = new Object[3]; //3个长度,动态初始化,所以每个元素默认值是null
      37. for (int i = 0 ; i < objs.length ; i++) {
      38. System.out.println("objs数组中下标为"+i+"的元素是:"+objs[i]);
      39. }
      40. System.out.println("====================");
      41. //
      42. String[] strS = new String[3];
      43. for (int i = 0 ; i < strS.length ; i++) {
      44. System.out.println("strS数组中下标为"+i+"的元素是:"+strS[i]);
      45. }
      46. //采用静态初始化的方式
      47. String[] strS2 = {"abc","def","xyz"};
      48. for (int i = 0 ; i < strS2.length ; i++) {
      49. System.out.println("strS2数组中下标为"+i+"的元素是:"+strS2[i]);
      50. }
      51. //存储Object ,采用静态初始化呢?
      52. /*
      53. Object o1 = new Object();
      54. Object o2 = new Object();
      55. Object o3 = new Object();
      56. Object[] objects = {o1,o2,o3};
      57. */
      58. //以上还可以简化为:
      59. Object[] objects = {new Object(),new Object(),new Object()};
      60. for (int i = 0 ; i < objects.length ; i++) {
      61. System.out.println("objects数组中下标为"+i+"的元素是:"+objects[i]);
      62. /*
      63. 相当于: Object o = objects[i];
      64. System.out.println(o);
      65. */
      66. /*
      67. 输出结果:objects数组中下标为0的元素是:java.lang.Object@1b6d3586
      68. objects数组中下标为1的元素是:java.lang.Object@4554617c
      69. objects数组中下标为2的元素是:java.lang.Object@74a14482
      70. object[i] 输出的是此数组中存储的对象,即o1、o2、o3。输出引用会出输出这个对象的内存地址
      71. 而数组刚好就是存储内存地址的。
      72. */
      73. }
      74. }
      75. }
    3. 当一个方法的参数类型为数组时,如何传参数

      1. //当一个方法上,参数的类型是数组时,我们应该如何传递参数。
      2. public class ArrayText03 {
      3. //java的main方法编写方式
      4. //public static void main(String[] args) {}
      5. //还可以采用C++的语法格式!
      6. public static void main(String args[]) {
      7. //java风格
      8. int[] ii = {1,2,3};
      9. for (int i = 0; i
      10. System.out.println(ii[i]);
      11. }
      12. //C++风格
      13. int ii2[] = {4,5,6};
      14. for (int i = 0; i
      15. System.out.println(ii2[i]);
      16. }
      17. System.out.println("=====================");
      18. //调用方法时传一个数组进去
      19. int[] x = {11,22,33,44,55,66};
      20. printArray(x);
      21. String[] strS = {"hehe","haha","dudu","jiji"};
      22. printArray(strS);
      23. String[] strArray = new String[2];
      24. printArray(strArray);
      25. //也可以直接new 一个数组进去
      26. printArray(new String[4]);
      27. printArray(new int[3]);
      28. }
      29. public static void printArray(int[] array){
      30. for (int i = 0; i
      31. System.out.println(array[i]);
      32. }
      33. }
      34. public static void printArray(String[] args){
      35. for (int i = 0; i
      36. System.out.println("String数组中的元素"+args[i]);
      37. }
      38. }
      39. }
    4. 当一个方法的参数是一个数组时,我们还可以采用这种方式传输

      1. //当一个方法的参数是一个数组时,我们还可以采用这种方式传输
      2. public class ArrayText04 {
      3. public static void main(String[] args){
      4. //静态初始化一维数组
      5. int[] ii = {1,2,3};
      6. printArray(ii);
      7. //动态初始化一维数组
      8. int[] ii2 = new int[2];
      9. printArray(ii2);
      10. printArray(new int[3]);
      11. System.out.println("=================");
      12. //没有这种语法
      13. //printArray({1,2,3,4});
      14. //如果直接传递一个静态数组的话,必须这样写:
      15. printArray(new int[]{1,2,3,4});
      16. }
      17. //这里为什么用静态方法?
      18. //方便,不需要new对象。
      19. public static void printArray(int[] array){
      20. for (int i = 0; i
      21. System.out.println(array[i]);
      22. }
      23. }
      24. }
    5. main方法中的String[] args 作用:接收用户输入参数

      1. /*
      2. main方法上面的String[] args 有什么用?
      3. 分析一下:谁负责调用main方法——JVM
      4. JVM调用main方法时,会自动传一个String数组过来
      5. */
      6. public class ArrayText05 {
      7. //这个方法是程序员负责写出来,JVM负责调用,JVM调用的时候,一定会传一个String数组过来
      8. public static void main(String[] args){
      9. //JVM默认传过来的这个数组对象的长度:默认0
      10. //通过测试得出:args不为null
      11. System.out.println("JVM给传递过来的String数组参数,它这个数组长度是:"+ args.length);
      12. //以下这一行代码表示的含义:数组对象创建了,但是数组中没有任何数据。
      13. String[] strS = new String[0];
      14. String[] strS2 = {}; //静态初始化数组,里面没有传东西
      15. printLength(strS); //0
      16. printLength(strS2); //0
      17. /*
      18. 这个数组什么时候里面会有值呢?
      19. 其实这个数组是留给用户的,用户在控制台上输入参数,这个参数会自动被转换为“String[] args”
      20. 例如在cmd中这样运行程序:java ArrayText05 abc def xyz
      21. 那么这个时候JVM会自动将“abc def xyz” 通过空格的方式进行分离,分离完之后,自动放到“String[] args”数组当中
      22. 所以main方法上面的String[] args 数组主要是用来接收用户输入参数的
      23. 把abc def xyz 转换成字符串数组:{"abc","def","xyz"}
      24. */
      25. //遍历数组
      26. for (int i = 0; i
      27. System.out.println(args[i]);
      28. }
      29. }
      30. public static void printLength(String[] array){
      31. System.out.println("数组长度为:"+array.length);
      32. }
      33. }
    6. 模拟一个系统,假设这个要使用必须输入用户名和密码

      1. //模拟一个系统,假设这个系统要使用,必须输入用户名和密码
      2. public class ArrayText06 {
      3. //用户名和密码输入到String[] args数组当中
      4. public static void main(String[] args){
      5. if(args.length != 2){
      6. System.out.println("使用该系统时请输入程序参数,参数中包括用户名和密码信息,例如:zhangsan 123");
      7. }
      8. //程序执行到这里说明用户确实提供了用户名和密码,接下来应该判断用户名和密码是否正确
      9. //取出用户名
      10. String useName =args[0];
      11. //取出密码
      12. String password =args[1];
      13. //假设用户名是admin,密码是123的时候表示登录成功,其他一律失败。
      14. //判断两个字符串是否相等,需要使用equals方法
      15. //(useName.equals("admin")与(password.equals("123")
      16. //以下这样编写可以避免空指针异常
      17. //采用以下编码风格,即使userName和password都是null,也不会出现空指针异常。
      18. if("admin".equals(useName)){
      19. if("123".equals(password)){
      20. System.out.println("登录成功");
      21. }else {
      22. System.out.println("密码输入有误,请确认后重新输入");
      23. }
      24. }else {
      25. System.out.println("用户名输入错误");
      26. }
      27. }
      28. }
    7. 数组中存储的类型为:引用数据类型

      1. //一维数组的深入,数组中存储的类型为:引用数据类型。
      2. //对于数组来说,实际上只能存储java对象的“内存地址”,数组中存储的每个元素都是“引用”
      3. public class ArrayText07 {
      4. public static void main(String[] args){
      5. //创建一个Animal类型的数组
      6. Animal a1 = new Animal();
      7. Animal a2 = new Animal();
      8. Animal[] animals = {a1,a2};
      9. //对Animal数组进行遍历
      10. for (int i = 0; i
      11. /*Animal a = animals[i];
      12. a.move();*/
      13. //代码合并
      14. animals[i].move();
      15. //animals[i]取出下标为i的数据,因为这个数组是Animal类型的,所以可以调用Animal类中的move()方法
      16. //这个move方法不是数组的,而是数组中存储的Animal对象的move方法
      17. }
      18. //上与下原理相同
      19. // int[] array = {1,2,3};
      20. // for (int i = 0; i
      21. // /*int temp =array[i];
      22. // System.out.println(temp); */
      23. // //合并:
      24. // System.out.println(array[i]);
      25. // }
      26. //动态初始化要给长度为2的Animal类型数组
      27. Animal[] animals1 = new Animal[2];
      28. //创建一个Animal对象,放在数组的第一个盒子中
      29. animals1[0] = new Animal();
      30. //animals1[1] = new Product(); //Error: 不兼容的类型: Product无法转换为Animal
      31. //Animal数组中只能存放Animal类型,不能存放Product类型。
      32. animals1[1] = new Cat();
      33. animals1[1].move();
      34. //创建一个Animal类型的数组,数组中存储Cat和Bird
      35. Animal[] animals2 ={new Cat(),new Bird()}; //该数组中存储了两个对象的内存地址
      36. for(int i = 0 ; i
      37. //如果调用的方法是父类中存在的方法不需要向下转型,直接使用父类型引用调用即可
      38. animals2[i].move();
      39. //Cat c = animals2[i];
      40. //Error: Animal无法转换为Cat 编译器只知道这个数组中存储的是Animal类型的对象,向下转型需要加强制类型转换
      41. //Cat c = (Cat)animals2[i];
      42. //Exception in thread "main" java.lang.ClassCastException: Bird cannot be cast to Cat
      43. //强制类型转换后报错,因为:Bird也是Animal类型的,也存储在Animal类型的数组中,需要动态判断
      44. //当要调用子类中的特有方法时,需要向下转型,并加动态判断。
      45. if(animals2[i] instanceof Cat){
      46. Cat c = (Cat)animals2[i];
      47. c.catchMouse();
      48. }else if(animals2[i] instanceof Bird){
      49. Bird b =(Bird)animals2[i];
      50. b.sing();
      51. }
      52. //animals2[i].sing();
      53. //Error:(57, 28) java: 找不到符号符号: 方法 sing() 位置: 类 Animal
      54. }
      55. }
      56. }
      57. class Animal{
      58. public void move(){
      59. System.out.println("Animal move......");
      60. }
      61. }
      62. //商品类
      63. class Product{
      64. }
      65. //Cat是Animal的子类
      66. class Cat extends Animal{
      67. @Override
      68. public void move() {
      69. System.out.println("猫走猫步!");
      70. }
      71. public void catchMouse(){
      72. System.out.println("猫抓老鼠");
      73. }
      74. }
      75. class Bird extends Animal{
      76. @Override
      77. public void move() {
      78. System.out.println("Bird Fei Fei Fei!");
      79. }
      80. public void sing(){
      81. System.out.println("鸟儿在唱歌!!");
      82. }
      83. }
    8. 数组的扩容,数组的拷贝

      在这里插入图片描述

      在这里插入图片描述

      1. /*
      2. 关于一维数组的扩容
      3. 在java开发中,数组长度一旦确定后不可再改变,那么数组满了之后怎么办?
      4. 数组满了,需要扩容
      5. java中对数组的扩容:
      6. 先新建一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到大数组当中。
      7. 结论:数组扩容效率较低,因为涉及到了拷贝的问题,所以在以后的开发中请注意:尽可能少的进行数据的拷贝。
      8. 可以在创建数组对象的时候预估计一下多长合适,最好预估准确,这样可以减少数组的扩容次数。提高效率。
      9. */
      10. public class ArrayText08 {
      11. public static void main(String[] args){
      12. //java中数组扩容时使用System.arraycopy()方法进行拷贝
      13. // System.arraycopy(5个参数);
      14. // public static native void arraycopy(
      15. // Object src, //拷贝源,需要扩容的小容量数组
      16. // int srcPos, //从哪个位置开始,起始元素下标
      17. // Object dest, //拷贝目标:要拷贝到的那个大容量数组中
      18. // int destPos, //从哪个位置开始存放
      19. // int length); //要拷贝的长度
      20. //拷贝源(从这个数组中拷贝,需要扩容的数组)
      21. int[] src = {1,22,33,4,5};
      22. //拷贝目标(拷贝到这个目标数组中)
      23. int[] dest = new int[10]; //初始化一个长度为10的数组,每一个元素默认值为0
      24. //调用JDK中System类中的arraycopy方法,来完成数组的拷贝
      25. System.arraycopy(src,1,dest,3,2);
      26. //遍历目标数组
      27. for(int i = 0; i
      28. System.out.println(dest[i]); //0 0 0 22 33 ......
      29. }
      30. //如要拷贝整个数组:
      31. System.arraycopy(src,0,dest,0,src.length);
      32. for (int i = 0; i
      33. System.out.println(dest[i]);
      34. }
      35. //数组中如果存储的元素是 引用 ,可以拷贝吗?当然可以
      36. String[] strings = {"hello","world","study","java","oracle","mysql","jdbc"};
      37. String[] strings1 = new String[10];
      38. System.arraycopy(strings,0,strings1,0,strings.length);
      39. for (int i = 0; i
      40. System.out.println(strings1[i]);
      41. }
      42. //Object类型的数组拷贝
      43. Object[] objects = {new Object(),new Object(),new Object()};
      44. Object[] objects1 = new Object[5];
      45. //这里拷贝的时候不是拷贝对象,而是拷贝对象的内存地址。因为数组里存储引用数据类型时,存储的就是对象的内存地址。
      46. System.arraycopy(objects,0,objects1,0,objects.length);
      47. for (int i = 0; i
      48. System.out.println(objects1[i]);
      49. }
      50. }
      51. }

    二维数组

    1. 二维数组的初始化

      1. /*
      2. 关于java中的二维数组
      3. 1、二维数组其实是一个特殊的一维数组,特殊在这个一维数组当中的每一个元素是一个一维数组。
      4. 2、三维数组是什么?
      5. 三维数组是一个特殊的二维数组,特殊在这个二维数组中每一个元素是一个一维数组。
      6. 实际的开发中使用最多的就是一维数组。二维数组也很少使用。三维数组几乎不用。
      7. 3、二维数组静态初始化
      8. int[][] array = {{1,1,1},{10,20,30},{4,3,65,12,3,3}}
      9. */
      10. public class ArrayText09 {
      11. public static void main(String[] args){
      12. //一维数组
      13. int[] array = {100,200,300};
      14. System.out.println(array.length);//3
      15. //二维数组
      16. //里面的是四个一维数组,可以有n多个一维数组。
      17. int[][] a = {
      18. {100,200,300},
      19. {10,30,50},
      20. {99,44,66,75,23},
      21. {0}
      22. };
      23. System.out.println("------------------");
      24. System.out.println(a.length);//4
      25. System.out.println(a[0].length);//3 这是a这个二维数组中下标为0的元素的那个一维数组的长度
      26. System.out.println(a[1].length);//3
      27. System.out.println(a[2].length);//5
      28. System.out.println(a[3].length);//1
      29. int[][] a2 = {
      30. {100,200,300},
      31. {10,30,50},
      32. {99,44,66,75,23},
      33. {0},
      34. {93,234,2938,493},
      35. {102,3948,2}
      36. };
      37. System.out.println(a2.length);//6
      38. }
      39. }
    2. 二维数组中元素的读和改

      1. /*
      2. 关于二维数组中元素的:读和改
      3. a[二维数组中一维数组的下标][二维数组中的一维数组中的元素下标]
      4. a[0][0]:表示第一个一维数组中的第一个元素。
      5. a[3][100]:表示第四个一维数组中的第101个元素。
      6. 对于a[3][100]来说,其中a[3]是一个整体,[100]是前面a[3]直接结束的结果然后再下标100,
      7. */
      8. public class ArrayText10 {
      9. public static void main(String[] args){
      10. //二维数组
      11. int[][] a = {
      12. {102,192,394},
      13. {123,293,49},
      14. {10,203,30}
      15. };
      16. //请取出以上二维数组中的第一个一维数组,以及第一个一维数组中的第一个元素
      17. int[] a1 = a[0];
      18. System.out.println(a1[0]);//第一个元素
      19. //合并:
      20. System.out.println(a[0][0]);
      21. //取出第二个一维数组中的第三个元素
      22. System.out.println("第二个一维数组中的第三个元素:"+a[1][2]);
      23. //取出第3个一维数组中的第1个元素
      24. System.out.println("第3个一维数组中的第1个元素:"+a[2][0]);
      25. //改
      26. a[2][0] = 1111111;
      27. //修改数组3中的第一个元素后再次取出
      28. System.out.println("修改后的第3个一维数组中的第1个元素:"+a[2][0]);
      29. //注意下标不能越界
      30. }
      31. }
    3. 二维数组的遍历

      1. //二维数组的遍历
      2. public class ArrayText11 {
      3. public static void main(String[] args) {
      4. String[][] strings ={
      5. {"java","oracle","c++","python","C#"},
      6. {"张三","李四","王五","赵七"},
      7. {"lucy","ben","jack"},
      8. };
      9. //遍历二维数组
      10. for (int i = 0; i //二维数组中有几个一维数组循环几次,负责纵向
      11. //负责遍历一维数组中的二维数组
      12. for (int j = 0; j //每个一维数组中有几个元素循环几次,string[i]表示二维数组中的一维数组
      13. System.out.print(strings[i][j]+" ");//strings[i][j]表示二维数组中每个一维数组的元素
      14. }
      15. //输出换行
      16. System.out.println();
      17. }
      18. }
      19. }
    4. 动态初始化二维数组

      1. //动态初始化二维数组
      2. public class ArrayText12 {
      3. public static void main(String[] args){
      4. //3行四列
      5. //三个一维数组,每一个一维数组中有四个元素
      6. int[][] ints = new int[3][4];
      7. printArray(ints);
      8. //二维数组的遍历
      9. // for (int i = 0; i
      10. // for (int j = 0; j
      11. // System.out.print(ints[i][j]+" ");
      12. // }
      13. // System.out.println();
      14. // }
      15. //静态初始化
      16. int[][] ints1 = {
      17. {1,1,1,1},
      18. {2,2,2},
      19. {3,3},
      20. {4}
      21. };
      22. printArray(ints1);
      23. //不能直接传这个进去,没有这种语法
      24. //printArray({{1,1,1,1}, {2,2,2}, {3,3}, {4}});
      25. //可以这样写
      26. printArray(new int[][]{{1,1,1,1}, {2,2,2}, {3,3}, {4}});
      27. }
      28. public static void printArray(int[][] array){
      29. //遍历二维数组
      30. for (int i = 0; i
      31. for (int j = 0; j
      32. System.out.print(array[i][j]+" ");
      33. }
      34. System.out.println();
      35. }
      36. }
      37. }

    总结

    1. 数组总结:
    2. 1、数组的优点和缺点,并且要理解为什么。
    3. 空间存储上,内存地址是连续的
    4. 每个元素占用的空间大小相同
    5. 知道首元素的内存储地址
    6. 通过下标可以计算出偏移量
    7. 通过一个数学表达式,就可以快速计算出某个下标位置上元素的内存地址,直接通过内存地址定位,效率非常高
    8. 优点:检索效率高
    9. 缺点:随机增删效率低,数组无法存储大数据量
    10. 注意:数组最后一个元素的增删效率不受影响。
    11. 2、一维数组的静态初始化和动态初始化
    12. 静态初始化:
    13. int[] array = {1,2,3,4};
    14. Object[] objs ={new Object(),new Object(),new Object()};
    15. 动态初始化:
    16. int[] array = new int[4]; //四个长度的一维数组,每个元素默认值0
    17. Object[] objs = new Object(4); //四个长度,每个元素默认值null
    18. 3、一维数组的遍历:
    19. for(int i = 0; i< array.length ; i++){
    20. System.out.println(array[i]);
    21. }
    22. 4、二维数组的静态初始化 、动态初始化:
    23. 静态初始化:
    24. int[][] array = {
    25. {1,2,3,4},
    26. {29,293,04,3984,38},
    27. {10,293,84,85,919},
    28. {0,4,3}
    29. }
    30. Object[][] array = {
    31. {new Object(),new Object()},
    32. {new Object(),new Object(),new Object(),new Object()},
    33. {new Object(),new Object(),new Object()},
    34. {new Object(),new Object(),new Object(),new Object(),new Object()}
    35. }
    36. 动态初始化:
    37. int[][] array = new int[3][4];
    38. Object[][] array = new Object[4][4];
    39. //Animal类型数组,里面可以存储Animal类型对象,以及Animal类型的子类型都可以。
    40. Animal[][] array = new Animal[5][2];
    41. 5、二维数组的遍历
    42. for(int i = 0; i < array.length ; i++){ //外层for循环负责遍历二维数组中的元素。
    43. //内层for循环负责遍历一维数组里的元素
    44. for(int j = 0 ; j
    45. System.out.print(array[i][j])
    46. }
    47. //换行
    48. System.out.println();
    49. }
    50. 6、main方法上“String[] args”参数的使用,(非重点,了解即可)
    51. 7、数组的拷贝:System.arraycopy()方法的使用
    52. 数组有一个特点:长度一旦确定,不可变
    53. 所以数组长度不够的时候,需要扩容,扩容的机制是:新建一个大数组。
    54. 将小数组中的数据拷贝到大数组,然后小数组对象被垃圾回收。
    55. 8、对数组中的数据拷贝到大数组,然后小数组对象被垃圾回收
    56. 9、对数组中存储引用数据类型的情况,要会画他的内存结构图。

    作业

    1. 第一题:使用一维数组,模拟栈数据结构

      自己做的

      1. /*
      2. 第一题:
      3. 编写程序,使用一维数组,模拟栈数据结构。
      4. 要求:
      5. 1、这个栈可以存储java中的任何引用类型的数据。
      6. 2、在栈中提供push方法模拟压栈。(栈满了,要有提示信息。)
      7. 3、在栈中提供pop方法模拟弹栈。(栈空了,也有有提示信息。)
      8. 4、编写测试程序,new栈对象,调用push pop方法来模拟压栈弹栈的动作。
      9. public class MyStack{ // 栈类
      10. // 提供一个数组来存储栈中的元素
      11. Object[] elements;
      12. // 栈帧(永远指向栈顶部的元素)
      13. // 每加1个元素,栈帧+1
      14. // 每减1个元素,栈帧-1
      15. int index;
      16. // 构造方法
      17. // 构造方法是不是应该给一维数组一个初始化容量。
      18. // push方法(push方法压栈)
      19. // 压栈表示栈中多一个元素。
      20. // 但是栈如果已满,压栈失败。
      21. // 这个方法的参数以及返回值类型自己定义。
      22. // pop方法(pop方法弹栈)
      23. // 弹栈表示栈中少一个元素。
      24. // 但是栈如果已空,弹栈失败。
      25. // 这个方法的参数以及返回值类型自己定义。
      26. }
      27. main(){
      28. 测试...
      29. }*/
      30. public class ArrayHomeWork1 {
      31. public static void main(String[] args) {
      32. MyStack ms1 = new MyStack();
      33. System.out.println("压栈————————————————");
      34. //压栈
      35. ms1.push(new Object());
      36. System.out.println(ms1.elements[0]);
      37. System.out.println(ms1.index);
      38. ms1.push(new Object());
      39. System.out.println(ms1.elements[1]);
      40. System.out.println(ms1.index);
      41. System.out.println(ms1.elements[ms1.index-1]);
      42. ms1.push(new Object());
      43. ms1.push(new Object());
      44. ms1.push(new Object());
      45. ms1.push(new Object());
      46. ms1.push(new Object());
      47. ms1.push(new Object());
      48. ms1.push(new Object());
      49. ms1.push(new Object());
      50. System.out.println(ms1.elements[9]);
      51. ms1.push(new Object());
      52. System.out.println(ms1.elements[ms1.index-1]);
      53. System.out.println("-------------------------------------------");
      54. MyStack ms2 = new MyStack(2);
      55. System.out.println(ms2.elements.length);
      56. ms2.push(new Object());
      57. ms2.push(new Object());
      58. ms2.pop();
      59. ms2.pop();
      60. }
      61. }
      62. //每创建一个栈对象,
      63. class MyStack{ //栈类
      64. //因为要求java中所有的数据类型都可以存储,所以数组类型要定义为Object类型的数组
      65. Object[] elements ;
      66. //栈帧,指向最顶部的元素。
      67. int index;
      68. //默认创建一个长度为10的一维数组
      69. public MyStack(){
      70. this.elements =new Object[10];
      71. }
      72. //创建栈对象时,传进来一个数,把这个数作为栈的容量
      73. public MyStack(int i){
      74. //默认创建一个一位数组
      75. this.elements = new Object[i];
      76. }
      77. //压栈方法:push,表示在数组中增加一个元素
      78. public void push(Object object){
      79. if(this.index ==this.elements.length){
      80. System.out.println("栈满了,压栈失败");
      81. }else{
      82. //压栈时,栈帧每次+1,此时传递一个元素进去,用下标接收,下标=栈帧-1,
      83. elements[index] = object;
      84. this.index += 1;
      85. System.out.println("压栈成功");
      86. }
      87. }
      88. //弹栈方法 :pop,表示在数组中删除一个元素
      89. public void pop(){
      90. //弹栈时,帧里有东西才会弹,如果没有,则弹栈失败。即:index大于0时才会弹栈,如果index为0,则说明栈中没有元素了
      91. //所以大于0才会弹栈,弹栈后,栈里的元素-1,
      92. if(this.index > 0){
      93. this.index -= 1;
      94. elements[index] = null;
      95. System.out.println("弹栈成功");
      96. if(index == 0){
      97. System.out.println("栈干净了");
      98. }
      99. }else {
      100. System.out.println("栈已空,弹栈失败");
      101. }
      102. }
      103. }

      根据视频做出来的

      1. /*
      2. 编写程序,使用一维数组,模拟栈数据结构。
      3. 要求:
      4. 1、这个栈可以存储java中的任何引用类型的数据。
      5. 2、在栈中提供push方法模拟压栈。(栈满了,要有提示信息。)
      6. 3、在栈中提供pop方法模拟弹栈。(栈空了,也有有提示信息。)
      7. 4、编写测试程序,new栈对象,调用push pop方法来模拟压栈弹栈的动作。
      8. 5、假设栈的默认初始化容量是10,(请注意无参构造方法的编写方式)
      9. */
      10. public class MyStack {
      11. //向栈中存储元素,我们这里使用一维数组模拟。存到栈中,就表示存储到数组中。因为数组是我们学习java的第一个容器
      12. //为什么选择Object类型数组?因为这个栈可以存储java中的任何引用数据类型的数据。
      13. //new Animal() 对象可以放进去,new Person()对象也可以放进去,因为Animal和Person的超级父类就是Object。
      14. //包括String也可以放进去,因为String父类也是Object。
      15. //注意:“abc”这是一个字符串对象,字符串在java中有优待,不需要new也是一个对象。“abc”字符串也是java对象,属于String类型。
      16. private Object[] elements ;//private Object[] elements = new Object[10]; 也可以在这里直接赋值。
      17. //栈帧,永远指向栈顶部元素 赋值-1,与下标同步增加。
      18. private int index = -1;
      19. //无参构造方法
      20. public MyStack() {
      21. //一维数组动态初始化,默认初始化为10。
      22. this.elements = new Object[10];
      23. }
      24. public MyStack(int i) {
      25. this.elements = new Object[i];
      26. }
      27. //set和get也许用不上,但你必须写上,这是规矩。使用IDEA生成就可以。
      28. //封装第一步:属性私有化,第二步:对外提供set和get方法。
      29. public Object[] getElements() {
      30. return elements;
      31. }
      32. public void setElements(Object[] elements) {
      33. this.elements = elements;
      34. }
      35. //压栈的方法,object:被压入的元素
      36. public void push(Object object){
      37. if(this.index >= this.elements.length-1){
      38. System.out.println("栈已满,压栈失败");
      39. return;
      40. }
      41. //程序执行到这里,说明栈里还有空间,可以继续加元素
      42. //this.index++ ;
      43. //elements[index] = object;
      44. //可合并为: ++index ,表示先加1再赋值,默认index为-1,压入后index为0,与压入元素的下标相同
      45. elements[++index] = object;
      46. //所有的System.out.println()方法执行时,如果输出引用的话,自动调用引用的toString()方法。
      47. System.out.println("元素 "+object+" 压栈成功,栈帧此时指向"+index);
      48. }
      49. //弹栈方法
      50. public void pop(){
      51. if(index <= -1){
      52. System.out.println("栈已空,弹栈失败");
      53. return;
      54. }
      55. //程序执行到这里说明栈还没空,
      56. System.out.println("元素 " + elements[index] +" 弹栈成功,此时栈帧指向:"+ --index);
      57. }
      58. }

      测试

      1. public class MyStackText {
      2. public static void main(String[] args){
      3. //创建一个栈对象
      4. MyStack stack = new MyStack();
      5. //调用方法压栈
      6. stack.push(new Object());stack.push(new Object());stack.push(new Object());stack.push(new Object());stack.push(new Object());
      7. stack.push(new Object());stack.push(new Object());stack.push(new Object());stack.push(new Object());stack.push(new Object());
      8. //压满之后
      9. stack.push(new Object()); //栈已满,压栈失败
      10. //弹栈
      11. stack.pop();stack.pop();stack.pop();stack.pop();stack.pop();
      12. stack.pop();stack.pop();stack.pop();stack.pop();stack.pop();
      13. //栈空后
      14. stack.pop();//栈已空,弹栈失败
      15. //调用有参构造创建一个栈对象
      16. MyStack stack2 = new MyStack(3);
      17. //压栈
      18. stack2.push(new Object());stack2.push(new Object());stack2.push(new Object());
      19. //栈满
      20. stack2.push(new Object());//栈已满,压栈失败
      21. //弹栈
      22. stack2.pop();stack2.pop();stack2.pop();
      23. //栈空
      24. stack2.pop();//栈已空,弹栈失败
      25. }
      26. }
    2. 第二题:酒店管理系统

      自己做没什么思路,根据老师说的做出来的

      房间类

      1. // 酒店房间
      2. public class Room {
      3. /*
      4. * 房间编号:
      5. * 1楼:101 102 103 104 105.....
      6. * 2楼:201 202 203 204 205......
      7. * 3楼:......
      8. * ......
      9. * */
      10. private int no;
      11. //房间类型:单人间 双人间 总统套房
      12. private String type;
      13. /*
      14. * 房间状态:
      15. * true:表示空闲,房间可以被预定
      16. * flase:表示房间已被使用,不能再被订
      17. * */
      18. private boolean status;
      19. //构造方法
      20. public Room() {
      21. }
      22. public Room(int no, String type, boolean status) {
      23. this.no = no;
      24. this.type = type;
      25. this.status = status;
      26. }
      27. //set和get方法
      28. public int getNo() {
      29. return no;
      30. }
      31. public void setNo(int no) {
      32. this.no = no;
      33. }
      34. public String getType() {
      35. return type;
      36. }
      37. public void setType(String type) {
      38. this.type = type;
      39. }
      40. //idea工具类型的boolean类型的变量,生成的get方法的方法名:isXxx()
      41. //public boolean isStatus() { return status; }
      42. //如果你不喜欢,可以修改为:getXxx()
      43. public boolean getStatus() {
      44. return status;
      45. }
      46. public void setStatus(boolean status) {
      47. this.status = status;
      48. }
      49. /**
      50. * 自己做的时候没想到这里,不知道如何打印房间状态。
      51. */
      52. //equals方法重写
      53. //equals是用来比较两个对象是否相等的
      54. //如何比较,自己定。你认为两个房间编号相同,就表示同一个房间,那么你写代码编写比较房间编号就可以。
      55. public boolean equals(Object obj) {
      56. if (obj == null ||!(obj instanceof Room)) return false;
      57. if (this ==obj) return true;
      58. Room room =(Room)obj;
      59. //如果两个房间的房间号相同,我们就说他们是同一个房间
      60. return this.getNo() == room.getNo() ;
      61. }
      62. //toString方法重写
      63. //toString方法的目的是将java对象转换成字符串形式。
      64. //如何转,转成什么格式,自己定。目的:简单,清晰明了。
      65. //如:这里不要看对象的内存地址。要看具体的信息
      66. public String toString() {
      67. //return "[101,单人间,使用中]";
      68. //return "[102,双人间,空闲]";
      69. //动态打印出房间状态信息(把一个变量塞到一个字符串当中,口诀:加一个双引号,双引号中间加 + ,两个加号中间加变量名 【"+name+"】)
      70. //return "["+no+","+type+","+status+"]";
      71. //status这里true时输出:空闲,false时输出:使用中,所以使用三目运算符
      72. return "["+no+","+type+","+(status ? "空闲":"使用中")+"]";
      73. //语法规则:布尔表达式?表达式1:表达式2
      74. //当布尔表达式的结果是true时,选择表达式1作为整个表达式的执行结果。
      75. //当布尔表达式的结果是false时,选择表达式2作为整个表达式的执行结果。
      76. }
      77. //编写一个临时程序测试一下,测试完删除
      78. /* public static void main(String[] args) {
      79. Room room = new Room(101,"单人间",true);
      80. Room room1 = new Room(102,"豪华VIP套间",false);
      81. System.out.println(room.toString());
      82. System.out.println(room1);//room1是一个引用,输出引用时,会自动调用引用的toString()方法。
      83. System.out.println(room.equals(room1));
      84. //查看一个类中的所有的属性和方法快捷键:ctrl +F12
      85. }*/
      86. }

      酒店类

      1. import java.util.Scanner;
      2. //酒店对象,酒店中有二维数组,二维数组模拟大厦
      3. public class Hotel {
      4. //二维数组,模拟大厦的房间
      5. private Room[][] rooms;
      6. //盖楼通过构造方法来盖
      7. public Hotel(){
      8. //一共有几层,每层的房间是什么,每个房间的编号是什么。
      9. //我们可以先写死,一共三层,一层是单人间,二层是双人间,三层是总统套房。每层有10个房间
      10. rooms = new Room[3][10];
      11. //创建30个对象,放到数组当中。
      12. //怎么放?二维数组遍历
      13. for(int i = 0; i //i是下标,i+1是楼层
      14. //自己写的,还可以简化
      15. // for(int j = 0 ; j
      16. // rooms[i][j] = new Room();
      17. // //初始化房间编号
      18. // rooms[i][j].setNo((i+1)*100+j+1);
      19. // //每个房间初始时是空闲的
      20. // rooms[i][j].setStatus(true);
      21. // //初始化房间类型
      22. // if(i+1 ==1){
      23. // rooms[i][j].setType("单人间");
      24. // }else if(i+1 == 2){
      25. // rooms[i][j].setType("双人间");
      26. // }else if(i+1 == 3){
      27. // rooms[i][j].setType("总统套间");
      28. // }
      29. // }
      30. for (int j = 0; j
      31. if(i == 0){//一层
      32. rooms[i][j] = new Room((i+1)*100+j+1,"单人间",true);
      33. }else if(i == 1){//二层
      34. rooms[i][j] = new Room((i+1)*100+j+1,"双人间",true);
      35. }else if(i == 2){//三层
      36. rooms[i][j] = new Room((i+1)*100+j+1,"总统套房",true);
      37. }
      38. }
      39. }
      40. }
      41. //想盖几层盖基层的有参构造,类型初始化尚待写入,无思路,以后再写
      42. /* public Hotel(int a,int b){
      43. System.out.println("已将酒店盖好,酒店共"+a+"层,每层有"+b+"个房间");
      44. //二维数组,模拟大厦
      45. rooms = new Room[a][b];
      46. //使用二维数组遍历初始化房间。每一层房间的类型相同。
      47. Scanner s = new Scanner(System.in);
      48. for (int i = 0; i
      49. for (int j = 0; j
      50. //在这里为每一层楼的每一个房间初始化
      51. rooms[i][j] = new Room();
      52. //初始化房间编号
      53. //每一层的房间编号=这一层的层数*100+这个房间的房间号。
      54. //因为数组下标都是从0开始,层数=i+1,房间号=j+1
      55. rooms[i][j].setNo((i+1)*100+j+1);
      56. //所有的房间状态为:空闲
      57. rooms[i][j].setStatus(true);
      58. }
      59. }
      60. }*/
      61. //打印酒店房间状态的方法
      62. public void printStatus(){
      63. for(int i = 0; i
      64. for(int j = 0 ; j
      65. System.out.print(rooms[i][j]+" ");
      66. }
      67. System.out.println();
      68. }
      69. }
      70. //查看正在使用中的房间:
      71. public void printFalse(){
      72. for(int i = 0; i
      73. for(int j = 0 ; j
      74. if(rooms[i][j].getStatus() == false) System.out.print(rooms[i][j]+" ");
      75. }
      76. System.out.println();
      77. }
      78. }
      79. /*
      80. 订房退房方法,调用时需要传递一个房间编号进来,这个编号是酒店前台输入的.
      81. 订房就是将房间状态false,退房是将房间状态true。
      82. 假设房间编号101,下标:rooms[0][0]
      83. 通过房间编号推出下标,获取房间对象
      84. */
      85. //订房方法
      86. public void order(int roomNo){
      87. Room r = rooms[roomNo/100-1][roomNo%10-1];
      88. if(r.getStatus() == true){
      89. r.setStatus(false);
      90. System.out.println(r);
      91. }else{
      92. System.out.println("该房间已被使用,请确认要订的房间后重新输入");
      93. }
      94. }
      95. //退房方法
      96. public void out(int roomNo){
      97. Room r = rooms[roomNo/100-1][roomNo%10-1];
      98. if( r.getStatus()== false){
      99. r.setStatus(true);
      100. System.out.println(r);
      101. }else {
      102. System.out.println("该房间已为空,请不要重复退房");
      103. }
      104. }
      105. }

      测试类

      1. import java.lang.reflect.Parameter;
      2. import java.util.Scanner;
      3. /*
      4. 第二题:(java软件工程师人生路上第一个小型项目。锻炼一下面向对象。)
      5. 为某个酒店编写程序:酒店管理系统,模拟订房、退房、打印所有房间状态等功能。
      6. 1、该系统的用户是:酒店前台。
      7. 2、酒店使用一个二维数组来模拟。“Room[][] rooms;”
      8. 3、酒店中的每一个房间应该是一个java对象:Room
      9. 4、每一个房间Room应该有:房间编号、房间类型、房间是否空闲.
      10. 5、系统应该对外提供的功能:
      11. 可以预定房间:用户输入房间编号,订房。
      12. 可以退房:用户输入房间编号,退房。
      13. 可以查看所有房间的状态:用户输入某个指令应该可以查看所有房间状态。
      14. */
      15. public class HotelManagementSystem {
      16. public static void main(String[] args) {
      17. Hotel hotel = new Hotel();
      18. // hotel.printStatus();
      19. //
      20. // hotel.order(102);
      21. // System.out.println("=-------------------------------====");
      22. // hotel.printStatus();
      23. //首先输出一个欢迎界面
      24. System.out.println("欢迎使用酒店管理系统,请认真阅读使用说明");
      25. while (true) {
      26. System.out.println("编号对应相应功能:【1】表示查看房间列表、【2】订房、【3】退房、【4】打印正在使用中的房间、【0】退出系统");
      27. Scanner s = new Scanner(System.in);
      28. int i = s.nextInt();
      29. if(i == 1){
      30. hotel.printStatus();
      31. }else if(i == 2){
      32. System.out.println("请输入所要订的房间号");
      33. Scanner roomNo = new Scanner(System.in);
      34. hotel.order(roomNo.nextInt());
      35. }else if(i == 3){
      36. System.out.println("请输入要退的房间号");
      37. Scanner roomNo = new Scanner(System.in);
      38. hotel.out(roomNo.nextInt());
      39. }else if(i == 0){
      40. System.out.println("谢谢使用本系统,欢迎下次再来");
      41. return;
      42. }else if(i == 4){
      43. System.out.println("正在使用中的房间:");
      44. hotel.printFalse();
      45. }else{
      46. System.out.println("输入有误,请重新输入");
      47. }
      48. }
      49. }
      50. }

    Arrays工具类

    1. 常见的算法:
    2. 排序算法:
    3. 冒泡排序算法
    4. 选择排序算法
    5. 查找算法:
    6. 二分法查找
    7. 以上算法在以后的java实际开发中我们不需要使用的。因为java已经封装好了,直接调用就可以。以后面试时可能会碰到。
    8. 算法实际上在java中不需要精通,因为java中已经封装好了,要排序就调用方法就行。例如:java中提供了一个数组工具类:
    9. java.util.Arrays
    10. Arrays是一个工具类
    11. 其中有一个sort方法,可以排序。静态方法,直接使用类名调用就可以。
    1. 简单的排序

      1. import java.util.Arrays;
      2. //使用一下SUN公司提供的数组工具类:java.util.arrays;
      3. public class ArraysText01 {
      4. public static void main(String[] args){
      5. int[] ints = {2,8,4,6,193,123,39};
      6. //工具类中的方法大部分都是静态的
      7. Arrays.sort(ints);
      8. //遍历输出
      9. for (int i = 0; i
      10. System.out.println(ints[i]);//2 4 6 8 39 123 193
      11. }
      12. }
      13. }
    2. 冒泡排序算法

      1. /*
      2. 冒泡排序算法
      3. 1、每一次循环结束之后,都要找出最大的数据,放到参与比较的这堆数据的最右边。(冒出最大的那个气泡)
      4. 2、核心:
      5. 拿着左边的数字和右边的数字比对,当 左边 > 右边 的时候,交换位置。
      6. 原始数据:
      7. 3,2,7,6,8
      8. 第一次循环:(最大的跑到最右边)
      9. 2,3,7,6,8 3和2比较,2<3,所以2和3交换位置
      10. 2,3,7,6,8 虽然不需要交换位置:但是3和7还是需要比较一次
      11. 2,3,6,7,8 6<7 6和7交换位置
      12. 2,3,6,7,8 虽然不需要交换位置:但是7和8还是需要比较一次
      13. 经过第一次循环,此时剩下参与比较的数据:2,3,6,7
      14. 第二次循环
      15. 2,3,6,7 2和3比较,不需要交换位置
      16. 2,3,6,7 3和6比较,不需要交换位置
      17. 2,3,6,7 6和7比较,不需要交换位置
      18. 经过第二次循环,此时剩下参与比较的数据:2,3,6
      19. 第三次循环
      20. 2,3,6 2和3比较,不需要交换位置
      21. 2,3,6 3和6比较,不需要交换位置
      22. 经过第三次循环,此时剩下参与比较的数据:2,3
      23. 第四次循环
      24. 2,3 2和3比较,不需要交换位置
      25. 原始数据:9 8 10 7 6 0 11
      26. 第一次循环:
      27. 8 9 10 7 6 0 11 第1次比较后:交换
      28. 8 9 10 7 6 0 11 第2次比较后:不交换
      29. 8 9 7 10 6 0 11 第3次比较后:交换
      30. 8 9 7 6 10 0 11 第4次比较后:交换
      31. 8 9 7 6 0 10 11 第5次比较后:交换
      32. 8 9 7 6 0 10 11 第6次比较后:不交换
      33. 最终冒出的最大数据在右边:11
      34. 经过第一次循环,此时剩下参与比较的数据: 8 9 7 6 0 10
      35. 第二次循环
      36. 8 9 7 6 0 10 第1次比较后:不交换
      37. 8 7 9 6 0 10 第2次比较后:交换
      38. 8 7 6 9 0 10 第3次比较后:交换
      39. 8 7 6 0 9 10 第4次比较后:交换
      40. 8 7 6 0 9 10 第5次比较后:不交换
      41. 最终冒出的最大数据在右边:10
      42. 经过第二次循环,此时剩下参与比较的数据: 8 7 6 0 9
      43. 第三次循环
      44. 7 8 6 0 9 第1次比较后:交换
      45. 7 6 8 0 9 第2次比较后:交换
      46. 7 6 0 8 9 第3次比较后:交换
      47. 7 6 0 8 9 第4次比较后:不交换
      48. 最后冒出的最大数据在右边:9
      49. 经过第三次循环,此时剩下参与比较的数据:7 6 0 8
      50. 第四次循环
      51. 6 7 0 8 第1次比较后:交换
      52. 6 0 7 8 第2次比较后:交换
      53. 6 0 7 8 第3次比较后:不交换
      54. 最后冒出的最大数据在右边:8
      55. 经过第四次循环,此时剩下参与比较的数据:6 0 7
      56. 第五次循环
      57. 0 6 7 第1次比较后:交换
      58. 0 6 7 第2次比较后:不交换
      59. 最后冒出的最大数据在右边:7
      60. 经过第五次循环,此时剩下参与比较的数据:0 6
      61. 第六次循环
      62. 0 6 第1次比较后:不交换
      63. //7条数据比6次
      64. //6条数据比5次
      65. //5条数据比4次
      66. //4条数据比3次
      67. //3条数据比2次
      68. //2条数据比1次
      69. */
      70. public class BubbleSort {
      71. public static void main(String[] args){
      72. //这是int类型的数组对象
      73. // int[] arr = {3,2,7,6,8};
      74. int[] arr = {9,8,10,7,6,0,11};
      75. //经过冒泡排序算法对以上数组中元素进行排序
      76. //冒泡排序算法的核心是什么?
      77. //对arr数组中的七条数据进行冒泡排序
      78. /*
      79. 数组中有七条数据,第一次循环7条数据要比较6次,第二次循环6条数据要比较5次,第三次循环5条数据要比较4次...第6次循环2条数据要比较1次
      80. 意思是:最外层循环要循环6次,内层循环每经过一次循环要根据所要比较的数据相应减少一次。
      81. 外层的是要控制需要进行6次循环比较,内层控制的是数组中数据的比较。
      82. */
      83. //查看循环几次
      84. int count = 0;
      85. for (int i = arr.length-1; i >0 ; i--) {
      86. //i刚开始是6,循环到1,刚好是循环了6次
      87. for (int j =0 ; j < i ; j++) {
      88. //不管是否交换,只要循环一次,就加1;
      89. count++;
      90. //内层循环里,j < i,就是几条数据循环几条-1次,如有5条数据,就循环四次
      91. //交换位置
      92. if(arr[j] >arr[j+1]){
      93. int temp ;
      94. temp = arr[j];
      95. arr[j] =arr[j+1];
      96. arr[j+1] =temp;
      97. }
      98. }
      99. }
      100. for (int i = 0; i
      101. System.out.println(arr[i]);
      102. }
      103. System.out.println("共比较了"+count+"次");
      104. }
      105. }
    3. 选择排序:

      ​ 选择排序比冒泡排序的效率高,高在交换位置的次数上。选择排序的交换位置是有意义的

      ​ 循环一次,然后找出参加比较的这堆数据中最小的,拿着这个最小的值和最前面的数据交换位置。

      1. /*
      2. 选择排序:每一次从 这堆参与比较的数据 当中找出 最小值
      3. 拿着这个 最小值 和 参与比较的这堆数据中最前面的元素 交换位置
      4. 选择排序比冒泡排序好在:每一次的交换位置都是有意义的。
      5. 参与比较的数据:3 1 6 2 5 (这一堆参加比较的数据中最左边的元素下标是0)
      6. 第一次循环之后的结果是:1 3 6 2 5
      7. 参与比较的数据: 3 6 2 5 (这一堆参加比较的数据中最左边的元素下标是1)
      8. 第二次循环之后的结果是:2 6 3 5
      9. 参与比较的数据是: 6 3 5 (这一堆参加比较的数据中最左边的元素下标是2)
      10. 第三次循环之后的结果是:3 6 5
      11. 参与比较的数据是:6 5 (这一堆参加比较的数据中最左边的元素下标是3)
      12. 第四次循环之后的结果是:5 6
      13. 注意:5条数据,循环4次。
      14. 关键点:选择排序中的关键在于:怎么找出一堆数据中最小的
      15. 3 1 6 2 5
      16. 假设:
      17. 第一个3是最小的
      18. 3和2比较,发现2更小,所以此时最小的是2
      19. 继续拿着2往下比对,2和6比较,2仍是最小的
      20. 继续拿着2往下比对,2和1比较,发现1更小,所以此时最小的是1
      21. 继续拿着1往下比对,1和5比较,1仍是最下的。
      22. 拿着1和最左边的3交换位置
      23. 2 6 3 5
      24. 假设:
      25. 第一个2是最小的
      26. 。。。
      27. 6 3 5
      28. 假设6是最小的:
      29. 6和3比对,发现3更小,所以此时最小的是3
      30. */
      31. public class SelectSort {
      32. public static void main(String[] args){
      33. //int[] arr = {3,1,6,2,5};
      34. int[] arr = {9,8,10,7,6,0,11};
      35. //选择排序算法 5条数据循环4次
      36. //每次循环取出最小的值与第一个值交换(外层循环4次)
      37. //设置个变量,查看比较次数
      38. int count =0;
      39. //查看交换次数
      40. int count2 = 0;
      41. for (int i = 0; i 1 ; i++) {
      42. //i的值是 0 1 2 3 ,正好是参加比较的这堆数据中 最左边那个元素的下标
      43. //假设起点i下标位置上的元素是最小的,把这个与所有的作比较,最后取出比这个小的
      44. int min = i;
      45. //比较的时候,把第一个值与所有的值比较一遍后取出最小的与第一个值交换
      46. for(int j = i+1 ; j < arr.length ;j++){//内层循环是:第一个值与所有的值相比较
      47. count++;
      48. if(arr[j] < arr[min]){
      49. //假设i是最小的值后,如果j的比最下的还小,则把j设为最小
      50. min = j;
      51. }
      52. }
      53. //当i和min相等时,表示猜测是对的,
      54. //当i和min不相等时,表示猜测是错的,有比这个元素更小的元素,需要拿着这个更小的元素和最左边的元素交换位置
      55. if(min != i){
      56. count2++;
      57. //当最小的不是i时,最小的为min,
      58. int middle = arr[i]; //第左手给中间
      59. arr[i] = arr[min]; //把右手给左手
      60. arr[min] = middle; //中间(存放了左手)给右手
      61. }
      62. }
      63. for (int i = 0; i
      64. System.out.println(arr[i]); //1 2 3 5 6 //0 6 7 8 9 10 11
      65. }
      66. //冒泡排序和选择排序实际上比较的次数没有变,交换位置的次数变少了
      67. System.out.println("比较次数:"+count);
      68. System.out.println("交换次数:"+count2);
      69. }
      70. }

      结论:

      冒泡排序和选择排序实际上比较的次数没有变,但选择排序的交换位置的次数变少了
      
    4. 数组元素的查找

      挨着找:效率低

      1. /*
      2. 数组的元素查找
      3. 数组元素查找有两种方式:
      4. 第一种方式:一个一个挨着找
      5. 第二种方式:二分法查找法(算法),这个效率比较高。
      6. */
      7. public class ArraySearch {
      8. public static void main(String[] args) {
      9. //这个例子演示一下第一种方式
      10. int[] arr ={4,5,5,6,87,8};
      11. //如果有两个相同的元素,则返回的是第一个。因为是挨着找,找到后就结束了,不会再去找剩下的。
      12. /* //找出87的下标,如果没有返回-1。
      13. //一个一个挨着找
      14. for(int i = 0; i < arr.length;i++){
      15. if(arr[i] == 87){
      16. System.out.println("87的元素的下标为:"+i);
      17. return;
      18. }
      19. }
      20. //程序执行到这里,表示没有87
      21. System.out.println("数组中不存在87这个元素");*/
      22. /*
      23. 最好以上的程序封装一个方法,思考:传什么参数?返回什么值?
      24. 传递的参数:第一个参数是数组,第二个参数是需要查找的元素。
      25. 返回值:返回被查找的这个元素的下标。如果找不到返回-1。
      26. */
      27. int index = arraySearch(arr,5);
      28. System.out.println(index == -1 ?"该元素不存在":"该元素的下标是:"+index);
      29. }
      30. /**
      31. * 从数组中检索某个元素
      32. * @param arr 被检索的数组
      33. * @param element 被检索的元素
      34. * @return 返回大于等于0的数表示元素的下标,-1表示该元素不存在
      35. */
      36. public static int arraySearch(int[] arr, int element) {
      37. for(int i = 0 ; i < arr.length;i++){
      38. if(arr[i] == element){
      39. return i;
      40. }
      41. }
      42. return -1;
      43. }
      44. }
    5. 二分法查找:

      1. 第一:二分法查找建立在排序的基础之上。
      2. 第二:二分法查找效率要高于“一个挨着一个”的这种查找方式
      3. 第三:二分法查找原理
      4. 10(下标0) 23 56 89 100 111 222 235 500 600(下标9) arr数组
      5. 目标:找出600的下标
      6. (0+9)/2 --------->4 (中间元素的下标)
      7. arr[4] 这个元素就是中间元素:arr[4]是100.
      8. 100 < 600
      9. 说明被查找的元素在100的右边。那么此时开始下标变成:4+1.
      10. (5+9) / 2 ---> 7(中间元素的下标)
      11. arr[7]对应的是:235
      12. 235 < 600
      13. 说明被查找的元素在235的右边
      14. 开始下标又进行了转变:7 + 1
      15. ( 8 + 9 ) /2 ---> 8
      16. arr[8] ---> 500
      17. 500 < 600
      18. 开始元素的下标又发生了变化:8+1
      19. (9 + 9) / 2 --->9
      20. arr[9] 是600,正好和600相等,此时找到了。

      使用二分法进行查找

      1. /*
      2. 1、数组工具类:自己写的,不是SUN的。
      3. 2、二分法查找算法是基于排序的基础上的(没有排序的数据是无法查找的。)
      4. 3、关于查找算法中的:二分法查找
      5. 10(下标0) 11 12 13 14 15 16 17 18 19 20(下标10) arr数组
      6. 通过二分法查找,找18这个元素的下标:
      7. (0 + 10)/2 ------> 中间元素的下标:5
      8. 拿着中间这个元素和目标要查找的元素进行对比:
      9. 中间元素是:arr[5]--> 15
      10. 15 < 18(被查找的元素)
      11. 被查找的元素18在目前中间元素15的右边。
      12. 所以开始元素的下标从0变成5+1
      13. 再重新计算一个中间元素的下标:
      14. 开始下标: 5+1
      15. 结束下标:10
      16. (6 + 10)/2 --> 8
      17. 8下标对应的元素arr[8] 是18
      18. 找到的中间元素正好和被查找的元素18相等,表示找到了:下标为8
      19. 二分法查找的终止条件:一面折半,直到中间的按个元素恰好是被查找的元素。
      20. 第一:二分法查找建立在排序的基础之上。
      21. 第二:二分法查找效率要高于“一个挨着一个”的这种查找方式
      22. 第三:二分法查找原理
      23. 10(下标0) 23 56 89 100 111 222 235 500 600(下标9) arr数组
      24. 目标:找出600的下标
      25. (0+9)/2 --------->4 (中间元素的下标)
      26. arr[4] 这个元素就是中间元素:arr[4]是100.
      27. 100 < 600
      28. 说明被查找的元素在100的右边。那么此时开始下标变成:4+1.
      29. (5+9) / 2 ---> 7(中间元素的下标)
      30. arr[7]对应的是:235
      31. 235 < 600
      32. 说明被查找的元素在235的右边
      33. 开始下标又进行了转变:7 + 1
      34. ( 8 + 9 ) /2 ---> 8
      35. arr[8] ---> 500
      36. 500 < 600
      37. 开始元素的下标又发生了变化:8+1
      38. (9 + 9) / 2 --->9
      39. arr[9] 是600,正好和600相等,此时找到了。
      40. 如果是在前半个里面,则元素下标-1,这个作为终止下标,起始下标不变。
      41. */
      42. public class ArrayUtil {
      43. public static void main(String[] args){
      44. int[] arr = {100,200,230,235,600,1000,2000,9999};
      45. //找出arr这个数组中200所在的下标
      46. //调用方法
      47. int index = binarySearch(arr,200);
      48. System.out.println(index == -1 ? "该元素不存在":"该元素的下标:"+index);
      49. }
      50. /**
      51. * 使用二分法从数组中查找元素的下标
      52. * @param arr 被查找的数组(这个必须是已经排序的)
      53. * @param dest 目标元素
      54. * @return
      55. */
      56. public static int binarySearch(int[] arr, int dest) {
      57. //开始下标
      58. int begin = 0;
      59. //结束下标
      60. int end =arr.length-1;
      61. //开始元素下标只要在结束元素下标的左边,就一直循环
      62. while(begin <= end){
      63. //中间元素下标
      64. int mid = (begin+end) / 2;
      65. if(arr[mid] == dest){
      66. return mid;
      67. }else if(arr[mid] < dest){
      68. //目标在中间元素的右边
      69. //起始元素下标 = 中间元素+1
      70. begin = mid + 1 ;//增
      71. }else{
      72. //arr[mid] > dest
      73. //目标在“中间”的左边,修改结束元素的下标
      74. end = mid - 1 ;//减
      75. }
      76. }
      77. return -1;
      78. }
      79. }
    6. java.util.Arrays 工具类

      所有的方法都是静态的,直接使用类名调用。使用时要文档,不要死记硬背。

      主要使用的是两个方法:排序、二分法查找

      1. import java.util.Arrays;
      2. /*
      3. SUN公司已经为我们程序员写好了一个数组工具类
      4. java.util.Arrays
      5. */
      6. public class ArraysText02 {
      7. public static void main(String[] args) {
      8. //java.util.Arrays; 工具类中有哪些方法,我们开发的时候要参考API帮助文档
      9. int[] arr = {3,6,4,7,12,1,2,32,5,5};
      10. //排序
      11. Arrays.sort(arr);
      12. //输出
      13. for (int i = 0; i
      14. System.out.println(arr[i]);
      15. }
      16. //二分法查找(建立在排序的基础上)
      17. int index = Arrays.binarySearch(arr,511);
      18. //输出的index如果是大于等于0的,就存在这个元素,如果小于0,则表示不存在
      19. System.out.println(index < 0 ? "该元素不存在":"该元素下标为:" + index);
      20. //如果有两个值是相同的,则碰到哪个就输出哪个元素的下标,跟原理有关。
      21. }
      22. }
  • 相关阅读:
    vue中使用h5 video标签实现弹窗播放本地视频
    Games101作业0(vscode连接VB虚拟机)
    TypeScript 笔记:String 字符串
    XiaoZaiMultiAutoAiDevices-多进程多设备自动化测试框架
    10_上传漏洞_代码审计&文件命名
    实例060:字符串长度
    Nacos的注册和使用
    MIPI CSI-2笔记(22) -- CSI-2实现案例
    Kotlin学习(一)
    mindspore1.5版本下能正常运行到了1.6‘_check_version.py’报错
  • 原文地址:https://blog.csdn.net/m0_69066786/article/details/127983971