数组的定义与使用

一、数组的基本用法

1、什么是数组
数组本质上就是让我们能“批量”创建相同类型的变量
如果我们需要创建一个数据,int a;
需要创建两个数据,int a,int b;
需要创建三个数据,int a,int b,int c;
那如果要创建100万个数据,就不能创建一百万个变量,这时候就需要使用数组,帮我们批量创建。
注意:在java中,数组中包含的变量必须是相同类型
2、创建数组

//动态初始化
数据类型[] 数组名称 = new 数据类型[长度]{初始化数据};
int[] arr = new int[3]{1,2,3};

//静态初始化
数据类型[] 数组名称 = {初始化数据};
int[] arr = {1,2,3};
//静态初始化,数组元素个数和初始化数据的格式是一致的

3、数组的使用

int[] arr = {1,2,3};
//获取数组长度
System.out.println("length:"+arr.length);//3
System.out.println(arr[1]);//2
System.out.println(arr[0]);//1
arr[2] = 100;
System.out.println(arr[2]);//100

注意:

  • 获取数组长度arr.length
  • 数组的下标从0开始计数,下标的合法范围为[0,length-1],超出范围,会出现下标越界异常
  • 数组不能被整体赋值
//遍历数组
int[] arr = {1,2,3};
for(int i = 0; i < arr.length;i++){
    System.out.println(arr[i]);
}
//1
//2
//3

//使用for-each遍历
//for-each是for循环的另外一种使用方式,可避免循环条件和更新语句出错
int[] arr = {1,2,3};
for(int x : arr){
    System.out.println(x);
}
//执行结果同上

二、数组作为方法的参数

1、基本用法

public static void main(String[] args){
    int[] arr = {1,2,3};
    printArray(arr);//函数的调用,传的是实参
}
public static void printArray(int[] a){
    for(int x : a){
        System.out.println(x);
    }
}
//1
//2
//3

2、理解引用类型(重点/难点)

public static void main(String[] args){
    int num = 0;
    func(num);
        System.out.println("num = " + num);
}
public static void func(int x){
    x = 10;
    System.out.println("x = " + x);
}
//执行结果  x = 10  num = 0
//我们可以看到,改变形参的值实参的值并没有改变,因为我们这个是值传递,
//形参只是一个临时变量,执行完func之后形参释放,自然也就没修改实参的值
//那么,要怎么通过调用函数改变实参的值

public static void main(String[] args){
    int[] arr = {1,2,3};
    func(arr);
        System.out.println("arr[0] = " + arr[0]);
}
public static void func(int[] a){
    a[0] = 10;
    System.out.println("a[0] = " + a[0]);
}
//执行结果 a[0] = 10   arr[0] = 10
//我们可以看到,此时改变形参的值,实参的值也随之改变
//此时数组名arr是一个引用,不再是简单的实参拷贝

什么是引用?

学过C语言,引用我们可以理解为指针
创建一个引用只是相当于创建了一个很小的变量,这个变量保存了一个整数,这个整数表示内存中的一个地址。
在这里插入图片描述
我们都知道,数组的内存空间是连续的,所以传arr相当于传了地址,数组的首地址,得到了数组的首地址,也就得到了整个数组,所以改变形参的值实参的值也随之改变,或者按图示理解,引用相当于一个线索,指向同一个内存空间,改变一个值就相当于改变了原有的数据的值,函数调用结束后,a的这个引用释放,但是值已经改变了。
3、认识null
null在java中表示一个“空引用”,也就是一个无效的引用

int[] arr = null;
System.out.println(arr[0]);
//执行结果
//Exception in thread "main" java.lang.NullPointerException
//at Test.main(Test.java:6)

虽然arr引用指向的是一个空引用,但是arr这个引用是存在的,不过由于他指向的是空引用,所以对他进行处理就会有空指针异常

三、数组作为方法的返回值

public class Test {
    //数组作为方法的返回值
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        transform(arr);
        printArray(arr);
    }

    private static void printArray(int[] arr) {
        for(int i = 0;i <arr.length;i++){
            System.out.println(arr[i]);
        }
    }

    private static void transform(int[] arr) {
        for(int i = 0;i < arr.length;i++){
            arr[i]*=2;
        }
    }
}
//执行结果 2 4 6 8 10
//但是这个改变了原有数组,为了不破坏原有数组,提出以下改进方案
public class Test {
    //数组作为方法的返回值
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        int[] ret = transform(arr);
        printArray(ret);
    }

    private static void printArray(int[] arr) {
        for(int i = 0;i <arr.length;i++){
            System.out.println(arr[i]);
        }
    }
    private static int[] transform(int[] arr) {
        for(int i = 0;i < arr.length;i++){
            arr[i]*=2;
        }
        return arr;
    }
}
//执行结果 2 4 6 8 10   创建了一个新的数组,将新数组返回,不破坏原有数组
//由于数组是引用类型,返回的时候只将新数组的地址传了回去,并没有拷贝新数组的内容,从而比较高效

四、有关数组的练习

1、数组转字符串

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包,其中包含了一些操作数的常用方法

什么是包?

例如做一碗饺子,要先准备饺子馅,饺子皮,包饺子,烧水,下锅煮熟,盛出来,蘸汁,但是为了方便,有时候我们会在超市买速冻饺子,即已经包好的饺子,再回去煮,这样省了很多步骤,降低了做饺子的难度。
同样,程序开发也不是所有的程序都是我们从最开始写的,这样当要做一个大工程时,效率大大降低,所以java中提供了大量的标准库(JDK提供的代码)和海量的第三方库(其他机构组织提供的代码)供我们使用,这些代码就放在一个一个的包中,所谓的包就相当于卖饺子的超市。

//自己实现的一个数组转字符串
public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        System.out.println(toString(arr));
    }

    private static String toString(int[] arr) {
        String ret = "[";
        for(int i = 0;i < arr.length;i++){
            ret +=arr[i];
            if(i!=arr.length-1){
                ret+=",";
            }
        }
        ret+="]";
        return  ret;
    }
}

2、数组拷贝

int[] arr = {1,2,3,4,5,6};
int[] newArr = Arrays.copyOf(arr,arr.length);
System.out.println("newArr:" + Arrays.toString(newArr));
arr[0] = 10;
System.out.println("arr:" + Arrays.toString(arr));
System.out.println("newArr:" + Arrays.toString(newArr));
//执行结果
 newArr:[1, 2, 3, 4, 5, 6]
 arr:[10, 2, 3, 4, 5, 6]
newArr:[1, 2, 3, 4, 5, 6]
//拷贝是重新申请了一片空间,当再改变arr数组中的值时newArr不变
//如下图所示

在这里插入图片描述

//自己实现的拷贝
import java.util.Arrays;
public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        int[] newArr = copyOfArr(arr);
        System.out.println(Arrays.toString(newArr));
    }
    public static int[] copyOfArr(int[] arr){
         int[] newArr = new int[arr.length];
        for(int i = 0;i <newArr.length;i++){
            newArr[i] = arr[i];
        }
        return newArr;
    }
}
//运行结果   [1,2,3,4,5,6]

3、找数组中最大的元素

public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        System.out.println(max(arr));//6
    }
    public static int max(int[] arr){
        //先让第一个数是最大的
        int max = arr[0];
        for(int i = 1;i < arr.length;i++){
            if(max<arr[i]){
                max = arr[i];
            }
        }
        return max;
    }

4、求数组中元素的平均值

public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        System.out.println(average(arr));
    }

    private static double average(int[] arr) {
        int sum = 0;
        for(int x : arr){
            sum+=x;
        }
        return (double) sum/arr.length;
    }
}
//注意,return的时候不能写成 return (double) (sum/arr.length);
//sum为整型,arr.length也是整型,除了之后也是整型,在转为double,有精度丢失

5、查找数组中指定元素

class Test{
    public static void main(String[] args){
        int[] arr = {1,2,3,4,5,6};
        System.out.println(Find(arr,4));
    }
    public static int Find(int[] arr,int num){
        for(int i = 0;i < arr.length;i++){
            if(arr[i]==num){
                return i;
            }
        }
        return -1;//没有找到
    }
}
//运行结果  3

//二分查找法(有序)
二分查找的思想:取中间位置的元素,如果相等返回,
如果比中间值大,在有半区间以相同的方式查找。
如果比中间值小,在左半区间以相同方法查找
class Test{
    public static void main(String[] args){
        int[] arr = {1,2,3,4,5,6};
        System.out.println(binarySearch(arr,6));
    }
    public static int binarySearch(int[] arr,int num){
        int left = 0;
        int right = arr.length - 1;
        while(left<=right){
            int mid = (left + right)/2;
            if(a[mid]==num){
                return mid;//第一次就找到了
            }else if(a[mid] < num){
                left = mid +1;//右侧区间查找
            }else{
                right = mid - 1;//左侧区间查找
            }
        }
        return -1;//没找到
    }
}

6、检查数组的有序性

//给定一个整型数组,判断该数组是否有序
class Test{
    public static void main(String[] args){
        int[] arr = {1,2,3,10,5,6};
        System.out.println(isSorted(arr));
    }
    public static boolean isSorted(int[] arr){
        for(int i = 0;i < arr.length - 1;i++){
            if(arr[i] > arr[i+1]){
                return false;
            }
        }
        return true;
    }
}

7、冒泡排序

//思想:每次找到待排区间最大(小)的数,放到数组的最后面(前面)
//性能较低
import java.util.Arrays;
class Test{
    public static void main(String[] args){
        int[] arr = {9,5,2,7};
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void bubbleSort(int[] arr){
        for(int i = 0;i < arr.length;i++){
            for(int j = 0;j < arr.length-i;j++){
                if(arr[j] > arr[j+1]){
                    int tmp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = tmp;
                }
            }
        }
    }
}
//运行结果 [2,5,7,9]

8、数组逆序

有多种方法,现在看一下比较高效的

import java.util.Arrays;
class Test{
    public static void main(String[] args){
        int[] arr = {1,2,3,4};
        reverse(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void reverse(int[] arr){
        int left = 0;
        int right = arr.length - 1;
        while(left<right){
            int tmp = arr[left];
            arr[left] = arr[right];
            arr[right] = tmp;
            left++;
            right--;
        }
    }
}

9、数组数字排列

//给定一个数组,将所有偶数放到前面,奇数放到后面
//从数组的两头走,把前面遇到的奇数和后面遇到的偶数交换
public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6};
        transform(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void transform(int[] arr){
        int left = 0;
        int right = arr.length - 1;
        while(left < right){
            while(left<right&&arr[left]%2==0){
                left++;
            }
            while(left<right&&arr[right]%2!=0){
                right--;
            }
            int tmp = arr[left];
            arr[left] = arr[right];
            arr[right] = tmp;
        }
    }
}
//运行结果 [6, 2, 4, 3, 5, 1]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值