Javase | 数组、数组工具类

1.数组

  1. 数组是一种引用数据类型不属于基本数据类型,因而数组对象是存储在堆内存中。 数组的父类Object
  2. 数组实际上是一个容器,可以同时存储 (引用数据类型) 多个数据/元素。或者 也可同时存储 (基本数据类型) 多个数据/元素。(数组是“一组数据”的集合。)
  3. 数组当中如果存储是“Java对象”的话,实际上存储的是对象的引用 / 对象的内存地址
  4. 数组一旦创建长度不可变
  5. 所有数组对象都有length属性 (Java自带的),用来获取数组中元素的个数
  6. 数组的分类:一维数组、二维数组、三维数组、多维数组。

2.数组的 “存储结构”

  1. 数组在内存中进行存储时,数组元素的内存地址是连续/相连 的。
    (存储中的元素都是有规则的挨着排列的,内存地址连续 )
  2. 数组中第一个元素的“内存地址” 就是这个数组对象内存地址
  3. 数组中每一个元素都是有下标的,以1递增,最后一个元素的下标是length-1

3.数组的优缺点:

3.1 数组的优点

  1. 查询/查找/检索某个下标的元素时效率极高,是查询效率最高的一个数据结构。
  2. 数组的检索效率高

3.2 为什么数组的检索效率高?

  • 每一个元素的内存地址在空间存储上是连续的,数组中每一个元素类型相同、占用空间大小一样。
  • 如果知道第一个元素的内存地址,可通过下标 + 数学表达式计算出某个下标元素的内存地址,直接通过内存地址定位元素,所以数组的检索效率最高。
    (数组中存储100个元素,或者存储100万个元素,在元素查询/检索方面,效率是相同的,因为数组中元素查找时不会一个一个找,是通过数学表达式算出来的)

3.3 数组的缺点

  1. 由于为了保证数组每个元素的的内存地址连续,所以在数组随机删除或增加元素时,效率较低,因为随机删除元素会涉及到后面元素统一向前或向后位移的操作。
  2. 数据不能存储大数据量,因为很难在内存空间上找到一块特别大的且连续的内存空间。
  3. 注意:
    对于数组中最后一个元素的增删,是没有效率影响的。

4.一维数组

4.1 一维数组的“存储结构”

在这里插入图片描述

4.2 一维数组的“静态初始化”

 //声明一个int类型的数组,使用静态初始化的方式
    int[] a = {1, 100, 200, 300, 400, 500};
   //所有数组对象都有length属性
    System.out.println("数组中元素个数为: "+a.length);
    //数组中每一个元素都有下标,通过下标对数组中的元素进行存和取
    //取(读)
    System.out.println("数组中第一个元素: "+a[0]); // 1
    System.out.println("数组中最后一个元素: "+a[a.length-1]); // 500

    //存(改)
    //把第一个元素改为123
    a[0] = 123;
    //把最后一个元素改为111
    a[a.length - 1] = 111;		

4.3 一维数组的“动态初始化”

  • int [ ] arr =new int[5] ; //这里的5表示元素个数。 初始化一个5个长度的int类型数组,每个元素默认值为0。
  • String [ ] names = new String[6] ; //初始化6个长度的String类型数组,每个元素默认值为null。
  • 例子如:
        /**
         * 数据类型     默认值
         * ----------------
         * byte        0
         * short       0
         * int         0
         * long        0L
         * float       0.0F
         * double      0.0
         * boolean     false
         * char        \u0000
         * 引用数据类型   null
         */
         //动态创建一维数组
   int [] a = new int[4];  //创建一个长度为4的int数组,数组中的默认值为0
   //遍历数组
   for (int i = 0; i < a.length;i++) {
    System.out.println(a[i]);
}

4.4 一维数组的“遍历”

   //声明一个int类型的数组, “静态初始化” 一维数组
        int[] a = {1, 100, 200, 300, 400, 500}; //下标0-5

        //一维数组的遍历
        // a.length =6 (数组长度/数组元素 : 6) , 下标最大为5
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]); //i是下标,从0到5
        }


        /**
         *  从最后一个元素遍历到第一个元素
         *  数组长度为: a.length : 6 (6个元素)
         *  下标最大长度为: a.length-1 : 5 (因为下标是从0开始的,0 1 2 3 4 5 : 此时就已有6个元素,所以下标最大长度为5)
         */

        for (int i=a.length-1; i>=0; i--) {
            System.out.println("颠倒顺序输出:"+ a[i]); //i是下标,从0到5
        }


        /**
         * 这段代码会报错
         *
         * 下标为6表示第7个元素,a[]数组中下标只能到5(只有6个元素)
         */
        System.out.println(a[6]);  //“数组下标越界” 异常

5.数组的“扩容”

  • Java中 数组的扩容:先新建一个大容量数组,然后将小容量的数组中的数据一个一个拷贝大数组中。

  • 数组扩容效率较低,因为涉及到 数组的拷贝

    例子如:

    	    //数组的扩容/数组的拷贝
            //拷贝源 (从这个数组进行拷贝)
            int[] src = {1, 2, 3, 4, 5};
    
            //拷贝目标 (拷贝到这个数组上)
            int[] dest = new int[20]; //动态初始化数组
    
            //调用JDK  System中的 arraycopy()方法,完成数组的拷贝
            /**
             * 参数代表的含义分别为:  拷贝源、开始拷贝的下标、拷贝目标、拷贝到的数组的下标、拷		 * 的长度/数量
             */
            System.arraycopy(src, 1, dest, 3, 2);
    
            //拷贝数组中所有数据
            System.arraycopy(src, 0, dest, 0, src.length);
    
            for (int i = 0; i < dest.length; i++) {
                System.out.println(dest[i]);
            }
    

6.二维数组

61. 二维数组

  • 二维数组是是一个“特殊的一维数组”, 二维数组中每一个元素都是“一个一维数组”。
  • a[二维数组中的一维数组的下标][一维数组的下标]
  • a[一维数组的下标][一维数组中元素的下标]
/**
 * 关于二维数组的: 读和改
 *  a[二维数组中的一维数组的下标][一维数组的下标]
 *  a[一维数组的下标][一维数组中的元素的下标]
 *  a[0][0] :表示第一个一维数组中的第一个元素。
 *  a[3][100] :表示第四个一维数组中的第101个元素。
*/
public class ArrayTest3 {
 public static void main(String[] args) {
     //二维数组
     int [][] a ={ {34,4,65}, {100,200,300},{0}};

     //获得二维数组中的 “第一个一维数组”
     int[] a1 = a[0];

     //获得二维数组中的 “第一个一维数组中的第一个元素”
     int a2 =a[0][0];
     System.out.println(a2);
 }
}

6.2 二维数组的“遍历”

public class ArrayTest3 {
    /**
     *  a[一维数组的下标][一维数组中的元素的下标]
     *  第一个[]:负责遍历二维数组
     *  第二个[]:负责遍历一维数组
     */
    public static void main(String[] args) {
        //二维数组
        String[][] array ={
                {"张三","李四","王五"},
                {"Java","python","php","C++"},
                {"Jack","roe","jack"}
        };

        //遍历二维数组
        for (int i = 0; i < array.length; i++) {
            //负责遍历一维数组
            //a[二维数组中的一维数组的下标][一维数组中的元素的下标]
            for (int j = 0; j < array[i].length;j++) {
                //遍历一维数组中的具体的元素
                //输出二维数组中的每一个一维数组中的每一个元素
                System.out.println(array[i][j]); 
            }
        }
    }
}

7.Arrays工具类:

String toString( T [ ] array )

  • String toString( T [ ] array )数组转换为字符串

  • 该方法将数组的内容字符串的形式返回,这个字符串中元素用逗号分隔,最外层用[ ]包裹。
    如: [“123”,“12345”]

  • String toString( T [ ] array )可用于任何类型数组,包括基本数据类型和引用数据类型。

    例子如 :

      Integer[] numbers = { 5, 2, 8, 1, 7 };
      String[] s = {"123", "HelloWorld"};
      char[]c = {'a', 'b', 'c'};
      double[] f = {12.123, 13.14};
    
      System.out.println(Arrays.toString(numbers));   // [5, 2, 8, 1, 7]
      System.out.println(Arrays.toString(s));         // [123, HelloWorld]
      System.out.println(Arrays.toString(c));         // [a, b, c]
      System.out.println(Arrays.toString(f));         // [12.123, 13.14]
    

void sort( T [ ] array )

  • void sort( T [ ] array )
    数组中的数据进行 升序排序

       Integer[] numbers = { 5, 2, 8, 1, 7 };
    
       // [5, 2, 8, 1, 7]
       System.out.println("排序前的数组: " + Arrays.toString(numbers)); 
    
       //升序排列
       Arrays.sort(numbers);
       // [1, 2, 5, 7, 8]
       System.out.println("排序后的数组: " + Arrays.toString(numbers)); 
    

void sort( T[ ] a , Comparator<? super T> c) (降序排列)

  • void sort( T[ ] a , Comparator<? super T> c)
    使用自定义比较器对 “数组中数据”进行 降序排序
/**
   * 使用 “自定义比较器” 降序排列
*/
Integer[] numbers = {6, 2, 8, 1, 50}; //静态初始化
Arrays.sort(numbers, new Comparator<Integer>() {
@Override
public int compare(Integer num1, Integer num2) {
return num2 - num1; // 降序排列
}
});

// Arrays.toString() : 将"数组" 转换为 “字符串”
System.out.println(Arrays.toString(numbers)); // [50, 8, 6, 2, 1]

int binarySearch( T[ ] array, T key)

  • binarySearch( T[] array, T key)
    有序数组 中使用
    二分查找算法
    来查找 指定元素的索引位置/下标值。 该方法返回为该指定元素的索引值 或 (-(插入点) -1 )。它可以应用于各种基本类型数组对象类型数组

  • 使用该方法的前提是:该数组是有序的,可用 sort(int[ ]) 方法排序。

  • 如果指定元素在数组中,则返回该元素的索引值

  • 如果指定元素 不在数组中,则返回 (-(插入点) -1 )。插入点被定义为:将键插入到数组的那一点,即第一个大于此键的元素索引如果数组中所有元素都小于指定的键,则为 a.length
    (可以理解为当指定元素(key)不在数组中时,有序插入到数组中,如果该key后面有元素时,插入点为: 大于key 的第一个元素的索引值; 如果数组中所有元素都小于key,则插入点为: a.length)

  • 注意:
    这保证了当且仅当此键被找到时,返回的值将>=0

    例子如:

       int[] numbers = {2, 4, 8, 12, 40, 70,90};
       int key = 8;
       int key1 = 1;
       int key2 = 100;
       int key3 = 50;
       int key4 = 70;
       int key5 = 100;
       int key6 = 130;
       int key7 = -1;
    
       /**
       * binarySearch : 在"有序数组"中查找“指定元素”的“索引值/下标值”
       * 返回值为该"指定元素"的索引值 或 “(-(插入点)-1)”
       */
       System.out.println(Arrays.binarySearch(numbers, key));   // 2
       System.out.println(Arrays.binarySearch(numbers, key1));  // -1
       System.out.println(Arrays.binarySearch(numbers, key2));  // -8
       System.out.println(Arrays.binarySearch(numbers, key3));  // -6
       System.out.println(Arrays.binarySearch(numbers, key4));  //  5
       System.out.println(Arrays.binarySearch(numbers, key5));  // -8
       System.out.println(Arrays.binarySearch(numbers, key6));  // -8
       System.out.println(Arrays.binarySearch(numbers, key7));  // -1
    
       // key: 8 ---查找8在“有序数组”中的索引值 :2
       int index = Arrays.binarySearch(numbers, key); 
       if (index >= 0) {
        System.out.println("元素 " + key + " 在数组中的索引位置为 " + index);
       } else {
        System.out.println("元素 " + key + " 不在数组中");
    }
    

int binarySearch( T[ ] array , int fromIndex, int toIndex, T key)

  • 使用二分搜索法来搜索指定的数组的范围,以获得指定的值。
  • 如果它包含在数组的指定范围内,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入数组的那一点:即范围中第一个大于此键的元素索引,如果范围中的所有元素都小于指定的键,则为 toIndex。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。

void fill( T[ ] array, T value)

  • 将数组的所有元素设置为指定的值

       String[] strs = {"hello","HelloWorld","中国"}; //字符串数组
       //将数组的"所有元素"设置为"指定的值"
       Arrays.fill(strs,"123");
    
       //Arrays.toString() : 将数组转换为字符串
       String str = Arrays.toString(strs);//字符串
       System.out.println(str);  //[123, 123, 123]
    

void fill( T[ ] array, int fromIndex, int toIndex, T value)

  • 数组的指定范围内的元素设置为指定的值

  • [fromIndex,toIndex) : 包括fromIndex,不包括toIndex。

例子如:

   //字符串数组
   String[] strs = {"hello","HelloWorld","中国","Java","python","C++"}; 
   //将数组中“指定范围内的元素”设置为“指定的值”
   Arrays.fill(strs,1,4,"123"); //范围为: [1,4) ,不包括4

   //Arrays.toString() : 将数组转换为字符串
   String str = Arrays.toString(strs);//字符串
   System.out.println(str);  // [hello, 123, 123, 123, python, C++]

boolean equals (T[ ] array1, T[ ] array2)

  • boolean equals(T[] array1, T[] array2):比较两个数组是否相等

      String[] strs1 = {"Hello", "HelloWorld"};
      String[] strs2 = {"Hello", "HelloWorld"};
      String[] strs3 = {"Hello", "中国"};
      boolean b1 = Arrays.equals(strs1, strs2);
      boolean b2 = Arrays.equals(strs1, strs3);
    
      System.out.println(b1); //true
      System.out.println(b2); //false
    

T[ ] copyOf( T[ ] original, int newLength)

  • T[ ] copyOf( T[ ] original, int newLength):复制指定长度的数组

       int[] array1 = {1, 2, 3, 4, 5,6,7,8,9,10};
       int[] ints = Arrays.copyOf(array1, 5);
       //将数组转换字符串
       String strs = Arrays.toString(ints);
       System.out.println(strs); //[1, 2, 3, 4, 5]
    

T[ ] copyOfRange( T[ ] original, int fromIndex, int toIndex)

  • T[ ] copyOfRange( T[ ] original, int fromIndex, int toIndex):复制部分数组

  • [fromIndex , toIndex) : 包括初始索引,不包括最后索引。

      int[] array1 = {1, 2, 3, 4, 5,6,7,8,9,10};
      int[] ints = Arrays.copyOfRange(array1, 0, 6); // [0,6)
      //将数组转换字符串
      String strs = Arrays.toString(ints);
      System.out.println(strs); //[1, 2, 3, 4, 5,6]
    
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值