Java SE(五)之 数组(静态初始化,动态初始化,数组操作,Arrays类)

0.前言

数组是一个固定长度的,包含了相同类型数据的容器

1.声明数组

数据类型[ ] 数组名;   // 声明一个数组

例如:

int[] array1; // 声明数组array1

2.数组的初始化(创建数组)

初始化,就是在内存中为数组开辟空间,并将数据存入容器的过程

(1)静态初始化

完整格式:

数据类型[ ] 数组名 = new 数组名[ ]{ value1,value2,……};
eg. int[ ] arr = new arr[ ] {1,2,3};

日常使用中,更倾向于简化格式

数据类型[ ] 数组名 = { value1,value2,……};
eg. int[ ] arr = {1,2,3};

更多例子:

double[] arr1 = {1.2,2.3,4.5 };
String arr2  = {"hello","world"};

(2)动态初始化

初始化时只指定数组长度,由系统为数组分配初始值。

数据类型[ ] 数组名 = new 数据类型[ 数组长度 ]
eg. int[ ] array = new int[10];

例如:

public class HelloWorld {
    public static void main(String[] args) {
       double[] array = new double[10] // 创建一个长度为10的数组
       array[0] = 3.4; 
       array[1] = 5.8; 
       System.out.println(array[0]);  // 3.4
       System.out.println(array[1]);  // 5.8
       // 没有手动赋值,系统自动为其赋值(默认)
       System.out.println(array[2]);  // 0.0
    }
}

(3)静态和动态初始化的区别

在这里插入图片描述

3.数组的操作

用for循环基本可以搞定大部分操作;

增强for循环(for-each):

for(type element: array)
{
System.out.println(element);
}

(1)读取元素

说到读取元素,不得不提数组在计算机中的内存。

对于数组而言,计算机会在内存中为其申请一段连续的空间,并且会记下索引为 0 处的内存地址。以数组 [“C”, “O”, “D”, “E”, “R”] 为例,它的各元素对应的索引及内存地址如下图所示:

在这里插入图片描述

一旦知道了内存地址就可以立即访问到该元素,因此它的时间复杂度是常数级别O(1)

总之:

  • 数组下标都是从0开始的
  • 数组内存空间的地址是连续的

(2)查找元素

这里就是我们经常说的暴力搜索,从头开始搜索;当然最典型的改进就是二分查找。

(3)插入元素

正是因为数组的在内存空间的地址是连续的,所以在插入元素的时候,就很大可能要 移动 其他元素的地址。

如果是在数组的结尾插入元素,那比较方便。即计算机通过数组的长度和位置计算出即将插入元素的内存地址,然后将该元素插入到指定位置即可。

但如果是想在将该元素插入到数组中的其他位置,这时首先需要为该元素所要插入的位置腾出空间,然后进行插入操作。

(4)删除元素

删除元素与插入元素的操作类似

当删除掉数组中的某个元素后,数组中会留下 空缺 的位置,而数组中的元素在内存中是连续的,这就使得后面的元素需对该位置进行 填补 操作;

数组的元素是不能删的,只能覆盖。

4.数组作为函数参数

只要记住:

方法在传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实参的值

方法在传递引用数据类型时,传递的是地址值,形参的改变,影响实参的值

所以数组作为引用类型,在作为形参时,要注意它是否被改变

public static void printArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
    System.out.print(array[i] + " ");
  }
}

printArray(new int[]{3, 1, 2, 6, 4, 2})

总之:

当两个数组指向同一个空间时,其中一个数组对小空间中的值发生了改变,那么其他数组再次访问的时候都是修改后的结果了

5.二维数组

(1)内存分析

二维数组的本质上仍然是一个一维数组,只是将数组中的每个元素变成了一维数组。

内部的一维数组仍然从索引 0 开始。

在这里插入图片描述

与一维数组一样,二维数组同样会在内存中申请一段 连续 的空间,并记录第一行数组的索引位置,即 A[0][0] 的内存地址,如图:

在这里插入图片描述

(2)声明&初始化

定义:

int[][] a=new int[5][5];
String[][] b=new String[3][4];

初始化:

//静态初始化
int[][] a={{1,2,3},{4,5,6,7},{8,9,10,11}};

//动态初始化
String[][] b=new String[10][10];
b[0]=new String[]{"zahngsan","lisi","wangwu"};
b[1]=new String[]{"java","python","c++"};

(3)遍历

public static void main(String[] args) {
        //静态初始化
        int[][] a={{1,2,3,4},{4,5,6,7},{8,9,10,11}};
        //调用print方法
        print(a);
    }
    public static void print(int[][] a){
        //遍历
        // a.length为 3,a[0].length为 4
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a[i].length; j++) {
                System.out.print(a[i][j]+" ");
            }
            System.out.println();
        }
}

6.Arrays类

java.util.Arrays 类能方便地操作数组

直接看方法:

方法含义
String toString(数组)把数组拼接成一个字符串
int [ ] copyOf(原数组,新数组长度)拷贝数组
int [ ] copyOfRange(原数组,起始索引,结束索引)拷贝数组(指定范围),左闭右开
void fill(int[ ] a, int val)填充数组,将指定的 val 值分配给数组a指定范围中的每个元素
boolean equals(long[ ] a, long[ ] a2)如果两个数组以相同顺序包含相同的元素,则两个数组是相等的
void sort(Object[ ] a)对指定对象数组根据其元素的自然顺序进行升序排列
void sort​(类型[] a, Comparator<? super T> c)使用比较器对象自定义排序
int binarySearch(Object[ ] a, Object key)用二分查找算法在给定数组中搜索给定值的对象(Byt(在调用前必须排序好)

看几个示例熟悉用法

e.g.1

  int[] a={1,5,7,2,4,9};
      
  // 将数组转化为字符串输出
  String str=Arrays.toString(a);      
  System.out.println("字符串:"+str);
  
 // 拷贝操作,新数组长度是5,从原数组第一个元素开始
 int[] dp = Arrays.copyOf(a,5);
 System.out.println("拷贝后数组是:"+Arrays.toString(dp)); // 拷贝后数组是:[1, 5, 7, 2, 4]

 // 拷贝操作,拷贝原数组下标从1-5(不含)
  int[] db = Arrays.copyOfRange(a,1,5);
  System.out.println("拷贝后数组是:"+Arrays.toString(db)); // 拷贝后数组是:[5, 7, 2, 4]

  //所有元素都赋值成特定值
  Arrays.fill(a,10);                  
  System.out.println("赋值后:"+Arrays.toString(a));

输出:

字符串:[1, 5, 7, 2, 4, 9]
拷贝后数组是:[1, 5, 7, 2, 4]
拷贝后数组是:[5, 7, 2, 4]
赋值后:[10, 10, 10, 10, 10, 10]

eg2 排序

再说一下排序,分为自然排序和自定义排序

自定义排序 void sort​(类型[] a, Comparator<? super T> c)

设置 Comparator接口 对应的比较器对象,来定制比较规则

  • 如果认为左边数据 大于 右边数据 返回正整数
  • 如果认为左边数据 小于 右边数据 返回负整数
  • 如果认为左边数据 等于 右边数据 返回0
  // 1、默认升序排序
   int[] ages = {34,12,42,23};
   Arrays.sort(ages);
   System.out.println(Arrays.toString(ages));

   // 2、自定义比较器对象,只能支持引用类型的排序!
   Integer[] ages1 = {34,12,42,23};

  /*
  参数一:被排序的数组必须是引用类型的元素
  参数二:匿名内部类对象,代表了一个比较器对象。
  */
  Arrays.sort(ages1,new Comparator<Integer>( ) {
                @Override
                public int compare(Integer o1,Integer o2) {
                      // 降序排列
                        return o2-o1;
                      // 升序排序即 return o1-o2;
                        }
                        });
  System.out.println(Arrays.toString(ages1));

输出:

[12, 23, 34, 42]
[42, 34, 23, 12]

当然,自定义排序还可以对 对象 进行排序,比如按照对象的某一属性

如可以自己定义一个学生类,按照学生的身高排序

	Student[] students = new student[3];
	students[0] = new Student( name: "张三" ,age: 23 , height: 172);
	students[1] = new student( name: "李四",age: 19 , height: 187);
	students[2] = new student( name: "王五",age: 22 ,height:178);
	system.out.println(Arrays.toString(students));
	
    // Arrays.sort(students); 直接排序会报错
    
    Arrays.sort(students, new Comparator<Student>() {
             @0verride
        public int compare(Student o1,Student o2){
             //自己指定比较规则
            return o1.getAge() - o2.getAge(; //按照年龄升序排序!}
        });
            System.out.println(Arrays.toString(students));

参考链接:
https://leetcode.cn/leetbook/read/array-and-string/yjcir/
https://www.runoob.com/java/java-array.html

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值