> 文档中心 > [JavaSE] 数组的定义和使用(二)

[JavaSE] 数组的定义和使用(二)

目录

数组练习

💬 数组转字符串

💬 数组拷贝

💬 找数组中的最大元素

💬 求数组中元素的平均值

💬 查找数组中指定元素(顺序查找)

💬 查找数组中指定元素(二分查找)

💬 感受二分查找的效率

   

上一篇


   

疫情当前,大家要做好防护哦。

带好口罩了嘛?

那么大家跟着Nick来学习今天的数组知识!

  

数组练习

💬 数组转字符串

   

📝 代码示例

import java.util.Arrays int[] arr = {1,2,3,4,5,6}; String newArr = Arrays.toString(arr); System.out.println(newArr); // 执行结果 [1, 2, 3, 4, 5, 6]

   

🔴 使用这个方法后续打印数组就更方便一些

🔴 Java 中提供了 java.util.Arrays 包, 其中包含了一些操作数组的常用方法

    

⚫ 什么是包?

   

💠 例如做一碗油泼面, 需要先和面, 擀面, 扯出面条, 再烧水, 下锅煮熟, 放调料, 泼油。

   

💠 但是其中的 "和面, 擀面, 扯出面条" 环节难度比较大, 不是所有人都能很容易做好. 于是超市就提供了一些直接 已经扯好的面条, 可以直接买回来下锅煮. 从而降低了做油泼面的难度, 也提高了制作效率。

   

💠 程序开发也不是从零开始, 而是要站在巨人的肩膀上。

   

💠 像我们很多程序写的过程中不必把所有的细节都自己实现, 已经有大量的标准库(JDK提供好的代码)和海量的 第三方库(其他机构组织提供的代码)供我们直接使用. 这些代码就放在一个一个的 "包" 之中. 所谓的包就相当 于卖面条的超市. 只不过, 超市的面条只有寥寥几种, 而我们可以使用的 "包" , 有成千上万

   

📝 代码示例

   

🔴 这是Nick写了两个自己版本的数组转字符串

   

public class MyToString {    public static void main(String[] args) { int[] arr={1,2,4,5,7}; System.out.println(printArray(arr));    }    public static String printArray(int[] arr){ if (arr==null){     return null; } String str="["; for (int i = 0; i < arr.length; i++) {     if(i==arr.length-1){  str+=arr[i];     }else{  str+=arr[i]+",";     } } str+="]"; return str;    }    public static String myToString(int[] arr,boolean flag){ if (arr==null){     return null; } StringBuilder sb = new StringBuilder(); sb.append("["); String str=""; for (int i = 0; i < arr.length; i++) {     if(i==arr.length-1){  sb.append(arr[i]);     }else{  sb.append(arr[i]+",");     } } sb.append("]"); return sb.toString();    }}

    

💬 数组拷贝

   

📝 代码示例

  

🔴 Nick同样写了两个自己版本的拷贝方法(方法2,3,4是java提供的)

  

import java.lang.reflect.Array;import java.util.Arrays;public class 拷贝数组 {    public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; //方法1 自己写 //int[] copy = copyOf(arr); //方法2 Arrays.copyOf(根据长度复制) //int[] ret=Arrays.copyOf(arr,arr.length); //int[] ret=Arrays.copyOf(arr,arr.length*2); //方法3 Arrays.copyOfRange(复制范围) //int[] ret=Arrays.copyOfRange(arr,1,3); //方法4 System.arraycopy  (稍微比其他方法快一些) //int[] copy = new int[arr.length]; //System.arraycopy(arr, 0, copy, 0, arr.length); //源码展示// public static native void arraycopy(Object src,  int  srcPos,// Object dest, int destPos,// int length); //native 所有被native修饰的方法都被C或者C++实现了,速度会比较快 //方法5 (产生一个副本) int[] copy = arr.clone(); System.out.println(Arrays.toString(copy));    }    public static int[] copyOf(int[] arr) { int[] arr01 = new int[arr.length]; for (int i = 0; i < arr.length; i++) {     arr01[i] = arr[i]; } return arr01;    }    public static int[] copyOf(int[] arr, int x, int y) { if (arr == null || x = arr.length) {     return new int[]{-1}; } else {     int length = y - x + 1;     int[] arr01 = new int[length];     for (int i = 0; i < length; i++) {  arr01[i] = arr[x++];     }     return arr01; }    }}

   

🔻注意事项(萌新建议先看上一篇,后面文章会细说)

   

1.如果有人问道:“以上某某方法是什么拷贝(克隆)?”,最好不要回答,要是一定要说,就说是浅克隆或者画图,深克隆是经过人工干预造成的,不是因为某某拷贝方法就能说是深克隆的。

    

2.深克隆的实现取决于你的代码怎么写,之后写完类和接口的文章后,Nick会具体介绍深克隆和浅克隆的区别与原理。

   

3.简单形容一下,深克隆数组(引用类型),就说要将数组中储存的引用类型数据的对象全部备份一波,而不是单纯的拷贝引用数据,浅克隆的话,拷贝的对象引用指向依旧是原来的地址,即多引用指向同一对象。

      

    

💬 找数组中的最大元素

   

🔴 给定一个整型数组, 找到其中的最大元素 (找最小元素同理)

  

📝 代码示例

  

    public static void main(String[] args) { int[] arr = {1,2,3,4,5,6}; System.out.println(max(arr));    }    public static int max(int[] arr) { int max = arr[0]; for (int i = 1; i  max) {  max = arr[i];     } } return max;    }// 执行结果6

     

🔴 类似于 "打擂台" 这样的过程. 其中 max 变量作为 擂台, 比擂台上的元素大, 就替换上去, 否则就下一个对手

       

💬 求数组中元素的平均值

   

🔴 给定一个整型数组, 求平均值

   

📝 代码示例

public class 数组平均值 {    //实现一个方法 avg, 以数组为参数, 求数组中所有元素的平均值(注意方法的返回值类型).    public static void main(String[] args) { int[] arr ={1,2,3,4,5,6,7,8,9}; System.out.println(avg(arr));    }    public static double avg(int[] arr){ if(arr==null){     System.out.println("null"); }else{     double sum=0.0;     for (int i = 0; i < arr.length; i++) {  sum+=arr[i];     }     return sum/arr.length; } return -1;    }}

          

     

🔴 类似于 "打擂台" 这样的过程. 其中 max 变量作为 擂台, 比擂台上的元素大, 就替换上去, 否则就下一个对手

   

🔻 注意事项

结果要用 double 来表示

     

       

💬 查找数组中指定元素(顺序查找)

   

🔴 给定一个数组, 再给定一个元素, 找出该元素在数组中的位置

  

📝 代码示例

public static void main(String[] args) {     int[] arr = {1,2,3,10,5,6};     System.out.println(getIndex01(arr, 3));   }public static int getIndex01(int[] arr,int a){ for (int i = 0; i < arr.length;i++) {     if(arr[i]==a){  return i;     } } return -1;    }//执行结果2

             

💬 查找数组中指定元素(二分查找)

     

针对有序数组, 可以使用更高效的二分查找

  

啥叫有序数组?

  • 有序分为 "升序" 和 "降序
  • 如 1 2 3 4 , 依次递增即为升序
  • 如 4 3 2 1 , 依次递减即为降序

🔴 以升序数组为例, 二分查找的思路是先取中间位置的元素, 看要找的值比中间元素大还是小. 如果小, 就去左边找; 否 则就去右边找

   

📝 代码示例

import java.util.Arrays;import java.util.Scanner;//二分查找public class 数组索引二分 {    public static void main(String[] args) { int[] arr = {1,2,5,6,7,8,6}; Scanner src=new Scanner(System.in); int a=src.nextInt(); //System.out.println(getIndex02(arr,a)); //这个是java自带查找索引的方法 //System.out.println(Arrays.binarySearch(arr,a));    }    public static int getIndex02(int[] arr,int a){ int left=0; int right=arr.length-1; while(left arr[mid]){  left=mid+1;     }else if(a < arr[mid]){  right=mid-1;     }else if(a==arr[mid]){  return mid;     } } return -1;    }}

          

💬 感受二分查找的效率

class Test {    static int count = 0; // 创建一个成员变量, 记录二分查找循环次数    public static void main(String[] args) { int[] arr = makeBigArray(); int ret = binarySearch(arr, 9999); System.out.println("ret = " + ret + " count = " + count);    }    public static int[] makeBigArray() { int[] arr = new int[10000]; for (int i = 0; i < 10000; i++) {     arr[i] = i; } return arr;    }    public static int binarySearch(int[] arr, int toFind) { int left = 0; int right = arr.length - 1; while (left <= right) {     count++; // 使用一个变量记录循环执行次数     int mid = (left + right) / 2;     if (toFind  arr[mid]) {     // 去右侧区间找  left = mid + 1;     } else {     // 相等, 说明找到了  return mid;     } }     // 循环结束, 说明没找到 return -1;    }}     // 执行结果     ret = 9999 count = 14

      

🔴 可以看到, 针对一个长度为 10000 个元素的数组查找, 二分查找只需要循环 14 次就能完成查找. 随着数组元素个数 越多, 二分的优势就越大.

       

未完待续