JavaSE-7-数组的定义及使用

1. 数组的基本用法

1.1 什么是数组

数组其实是一种简单数据结构。是一块连续的内存,存储的是一组相同类型的数据集合。
数据结构:数据 + 结构 即组织和描述数据的方式

1.2 创建数组

基本语法:
// 动态初始化
数据类型[ ] 数组名称 = new 数据类型 [] { 初始化数据 };
// 静态初始化
数据类型[ ] 数组名称 = { 初始化数据 };

//代码示例:
int[] array1 = {1,2,3,4,5};//这个就是数组   整型数组
int[] array2 = new int[]{1,2,3,4,5,6,7,8,9};

1.3 数组的使用

代码示例1:读取数据&获取长度&修改数据

public static void main2(String[] args) {
    int a = 10;
    System.out.println(a);
    int[] array1 = {1,2,3,4,5};
    System.out.println(array1);//输出[I@1b6d3586  这是一个地址
    //存地址的变量叫做引用
    System.out.println(array1[0]);//输出:1
    System.out.println("数组的长度为:" + array1.length);//获取数组的长度
    array1[0]= 10;//修改数据
    System.out.println(array1[0]);//输出:10

    String str = "wangzhifeng";//str存的就是地址,
    //只不过打印的时候,打印函数做了底层转换,自动去找这个地址里面存的数据了。
    //但是打印数组的时候,不会去找地址里面的数据
    System.out.println(str);
    //引用指向的就是一个对象。
}

代码示例2:遍历数组

/**
 * 数组的遍历方式
 * @param args
 */
public static void main4(String[] args) {
    int[] array1 = {1,2,3,4,5};
    //第一个方法:for循环。
    for (int i = 0; i < array1.length; i++) {
        System.out.print(array1[i]+" ");
    }
    System.out.println();
    //第二个方法:增强for循环(foreach)
    //面试问题:for循环和foreach有什么区别?   有下标的区别
    for (int a :array1) {//冒号的左边:写数组里面每一个元素的数据类型   冒号右边:数组的名字
        System.out.print(a + " ");
    }
    System.out.println();
    //第三个方法:将数组以字符串的形式打印
    //Arrays: 操作数组的工具类
    String ret = Arrays.toString(array1);
    System.out.println(ret);//[1, 2, 3, 4, 5]
}

2. 数组作为方法的参数

代码示例1:数组的传参

/**
 * 数组的传参
 * @param args
 */
public static void main(String[] args) {
    System.out.println(add(10, 20));
    System.out.println("===================");
    int[] array = {1,2,3,4,5};
    func2(array);
    printArray(array);//1,2,3,4,5
    func(array);
    printArray(array);//2,4,6,8,10
}
public static void func2(int[] array2) {
    array2 = new int[] {1,2,3,4,5};//定义了新的对象
    for (int i = 0; i < array2.length; i++) {
        array2[i] *= 2;
    }
    System.out.println();
}
public static void func(int[] array) {
    for (int i = 0; i < array.length; i++) {
        array [i] *= 2;
    }
    System.out.println();
}
public static void printArray(int[] array) {
    for (int i = 0; i < array.length; i++) {
        System.out.print(array[i] + " ");
    }
    System.out.println();
}
public static int add(int a,int b) {
    return a + b;
}

3. 数组作为方法的返回值

代码示例1:写一个方法, 将数组中的每个元素都 * 2

/**
 * 实现一个方法 transform,以数组为参数,循环将数组中的每个元素乘以2,并设置到对应的数组元素上.如原数组为 {1,2,3},修改之后为{2,4,6}
 * @param args
 */
public static void main3(String[] args) {
    int[] arr = {1, 2, 3};
    transform(arr);
    printArray(arr);
}
public static void printArray(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        System.out.println(arr[i] + " ");
    }
}
public static void transform(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        arr[i] = arr[i] * 2;
    }
}

这种方法写出额代码会更改原有数组。因此,若 new 一个数组,就既能达到输出“原数组2倍的要求”,也能保证原来数组不被改变
代码示例2

/*
这样不会破坏原有数组了
 */
public static void main(String[] args) {
    int[] arr = {1, 2, 3};
    int[] output = transform1(arr);
    printArray(output);
}
public static void printArray(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        System.out.println(arr[i] + " ");
    }
}

public static int[] transform1(int[] arr) {
    int[] ret = new int[arr.length];
    for (int i = 0; i < arr.length; i++) {
        ret[i] = arr[i] * 2;
    }
    return ret;
}

4. 数组的练习

4.1 数组转字符串

不同于数组的遍历方式,我们可以利用字符串的拼接,使得数组转为字符串

public static String outPut(int[] array) {
        String ret = "[";
        for (int i = 0; i < array.length; i++) {
            ret = ret + array[i];
            if (i != array.length-1) {
                ret += ",";
            }
        }
        ret = ret + "]";
        return ret;
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7};
        System.out.println(outPut(array));//输出为[1,2,3,4,5,6,7]
    }

4.2 数组的克隆

数组的克隆总共有四种方法:

  • 1.for循环
//1.for 循环
public static void main19(String[] args) {
        int[] array = {1,2,3,4,5};
        int[] tmp = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            tmp[i] = array[i];
        }
        System.out.println(Arrays.toString(tmp));
    }
  • 2.Arrays.copyOf
/*
    2.Arrays.copyOf(int[] original, int newLength)
                     original:要拷贝的数组,newLength:拷贝后新的长度
     */
    public static void main18(String[] args) {
        int[] array = {1,3,5,7,9};
        int[] ret = Arrays.copyOf(array,array.length);
        System.out.println(Arrays.toString(ret));
    }
  • 3.arraycopy函数
/*
    3.public static native void arraycopy(Object src,  int  srcPos,
                                             Object dest, int destPos,
                                            int length);
     src:原来的数组
     srcPos:从原来的数组开始拷贝的位置
     dest:拷贝后的数组位置(目的地)
     destPos:拷贝后数组的开始位置
     length:拷贝的长度
     */
    public static void main17(String[] args) {
        int[] array = {2,4,6,8,10};
        int[] copy = new int[array.length];
        System.arraycopy(array,0,copy,0,array.length);
        System.out.println(Arrays.toString(copy));
    }
  • 4.Objec 中的 clone 方法
/*
    4.clone  该方法是Object的方法
     */
    public static void main16(String[] args) {
        int[] array = {1,2,3};
        int[] ret = array.clone();//clone会产生当前对象的一个副本
        System.out.println(Arrays.toString(ret));
    }

拷贝数组的一段范围(Java当中,一般遇到from…to,则是左闭右开区间)

/**
     * 拷贝一段数组的范围
     * @param args
     */
    public static void main15(String[] args) {
        int[] array = {1,2,3,4,5};
        //这这种拷贝的区间[1,3)   java当中,遇到from...to,他的区间都是[)。
        int[] ret =Arrays.copyOfRange(array,1,3);
        System.out.println(Arrays.toString(ret));
    }

4.3 找出数组中的极值元素

给定一个数组,找出其中的最大值。
思路:设定最大值为第一个,然后遍历完数组,依次比较。

  • 1.函数方法
public static int maxArray(int[] array) {
        int max = array[0];
        for (int i = 0; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        return max;
    }
    public static void main(String[] args) {
        int[] array = {1,23,45,2,45,78,86,65,67};
        System.out.println(maxArray(array));
    }
  • 2.for循环的方法
public static void main8(String[] args) {
        int[] array = {1,23,45,2,45,78,86,65,67};
        int max = array[0];
        for (int i = 1; i <array.length; i++) {
            if(array[i] > max) {
                max = array[i];
            }
        }
        System.out.println(max);
    }

4.4 求数组中的平均值

给定一个数组,求其平均值。
思路:数组的各元素之和除以数组的长度

/*
    实现一个方法 avg, 以数组为参数, 求数组中所有元素的平均值(注意方法的返回值类型).
     */
    public static void avg(int[] array) {
        int sum = 0;
        double average;
        for (int i = 0; i < array.length; i++) {
            sum += array[i];
        }
        average = (double)sum/(double)array.length;//这里注意类型转换,否则会精度丢失
        System.out.println(average);
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7,8,9,10};
        avg(array);
    }

4.5 查找数组中指定元素

给定一个有序数组,查找指定的元素
思路:设定一个关键字,然后按照一定的方法,将数组内的元素和关键字比较,找出符合关键字的那个元素

/*
    1.二分查找
     */
    public static int binarySearch(int[] array,int key) {
        int i = 0;
        int j = array.length-1;
        while (i <= j) {
            int mid = (i+j)>>>1;//这里相当于除以2,最后结果取整型
            if (array[mid] > key) {
                j = mid-1;
            }else if (array[mid] < key) {
                i = mid+1;
            }else {
                return key;
            }
        }
        return -1;
    }
    /*
    2.按顺序查找
    */
    public static int findNumber(int[] array,int key) {
        for (int i = 0; i < array.length; i++) {
            if (array[i] == key) {
                return key;
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7,8,11,13,15};
        System.out.println(binarySearch(array, 112));
        System.out.println(findNumber(array, 15));
    }

这两种查找指定元素的方法中,二分查找法比按顺序查找的速度快了很多,尤其一个数组中有大量元素存在的时候,这种优势更明显。

4.6 判断数组是否有序

思路:从头开始,前一个数字和后一个数字比较大小,变化趋势相同,则为有序,变化规律出现不同,则为无序。

/*
   给定一个整型数组, 判定数组是否有序
     */
    public static boolean judgeOrder(int[] array) {
        for (int i = 0; i < array.length-1; i++) {
            if (array[i] > array[i+1]) {//这里默认为升序数组的话,判断条件就是:如果有前面数字比后面数字大的,就输出false
                return false;
            }
        }
        return true;
    }
    public static void main13(String[] args) {
        int[] array = {1,2,3,4,5,6,7,8,9,10};
        int[] array1 = {1,3,4,2,5,6,7};
        System.out.println(judgeOrder(array));//输出 true
        System.out.println(judgeOrder(array1));//输出 false
    }

4.7 冒泡排序

给定一个数组,让数组升序。

  • 1.基本概念
    比较数组中中相邻的两个数字,小的放在前面,大的放在后面。
    在第一趟的时候,第 1 个数字和第 2 个数字比较,小的放在前面,大的放在后面,然后第 2 个数字和第三个数字比较,小的在前,大的在后…直到最后一个数字是最大的,第一趟比较完毕;
    第二趟的时候,还是从第一个数字开始比较,小的在前面,大的放在后面,重复第一趟的步骤,直到倒数第二个数字成为本趟比较后的最大数字,第二趟结束;
    然后重复上面的步骤,直到完成最终的排序。
  • 2.总结:假设一个数组中有 n 个数字,则需要进行 n-1 趟排序,且每一趟排序的次数都在逐趟的在减一。
  • 3.代码示例:
/*
    给定一个整型数组, 实现冒泡排序(升序排序)
     */
    public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1; i++) {//代表总共多少趟
            for (int j = 0; j < array.length-1-i; j++) {//每一趟的次数
                if (array[j] > array[j+1]) {
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                }
            }
        }
    }
    public static void main(String[] args) {
        int[] array = {1,2,5,3,4,9,6,7,8};
        bubbleSort(array);
        System.out.println(Arrays.toString(array));
    }

上述代码还存在这样的弊端:假如给定的代码中,有部分位置本来就是有序的,那么再次进行比较,就浪费了时间,因此,优化后的代码如下所示,优点在于判断该部分是交换,如果没有交换,则排序已经完成,省去了很多不必要的重复步骤。

/**
     * 冒泡排序 将上一个函数优化
     */
    public static void bubbleSort1(int[] array) {
        for (int i = 0; i < array.length-1; i++) {
            boolean flg = false;//默认每一趟都是没有顺序的
            for (int j = 0; j < array.length-1-i; j++) {//j代表每一趟比较的时候的次数
                if (array[j] > array[j+1]) {
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    flg = true;//判断下一趟是否交换过,没有交换的话,已经排序完成了
                }
            }
            if (flg == false) {
                break;
            }
        }
    }
    public static void main(String[] args) {
        int[] array = {1,23,45,3,10,4,8,5};
        System.out.println(Arrays.toString(array));
        bubbleSort1(array);
        System.out.println(Arrays.toString(array));
    }

图示举例理解:
冒泡排序

4.8 将有序数组逆置

给定一个有序数组,将该数组的的所有元素逆序排列。
思路:设定两个下标, 分别指向第一个元素和最后一个元素. 交换两个位置的元素,然后让前一个下标自增, 后一个下标自减, 循环继续即可.

/**
     * 将有序数组逆置
     * @param array
     */
    public static void reverse(int[] array) {
        int i = 0;
        int j = array.length-1;
        while (i<j) {
            int tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
            i++;
            j--;
        }
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6};
        reverse(array);
        System.out.println(Arrays.toString(array));
    }

4.9 创建并设置有序数组

创建一个 int 类型的数组,元素个数为100, 并把每个元素依次设置为 1-100。
思路:先设置一个符合数组长度要求的新数组,然后利用 for 循环遍历并赋值给数组的元素。

/*
    创建一个 int 类型的数组,元素个数为100, 并把每个元素依次设置为 1-100
     */
    public static void putNum(int[] array) {
        for (int i = 0; i < array.length; i++) {
            array[i] = i + 1;//注意这里,容易出现边界溢出
        }
        System.out.println();
    }
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
    public static void main6(String[] args) {
        int[] array = new int[100];
        putNum(array);
        printArray(array);
    }

4.10 数组的数字排列

给定一个整型数组, 将所有的偶数放在前半部分, 将所有的奇数放在数组后半部分
思路:设定两个下标,分别指向第一个元素和最后一个元素,用前面的下标从左往右找奇数,用后面的下标从右往左找偶数,然后交换两个位置的元素,依次循环。

/*
    交换数组里的内容,使得偶数在前,奇数在后
     */
    public static void func(int[] array) {
        int i = 0;
        int j = array.length-1;
        while (i < j) {
            while (i < j && array[i] % 2 == 0){
                i++;
            }
            while (i < j && array[j] % 2 != 0){
                j--;
            }
            int tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
        }
    }
    public static void printArray(int[] array) {
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        int[] array = {1,3,4,5,7,5,8,7,9,4};
        func(array);
        printArray(array);
    }

5. 二维数组

二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组。
基本语法
数据类型[ ][ ] 数组名称 = new 数据类型 [行数][列数] { 初始化数据 };

/**
     * 二维数组命名的三种方式
     */
    public static void main(String[] args) {
        int[][] array = new int[2][3];//代表两行三列的数组

        int[][] array2 = {{1, 2, 3}, {4, 5, 6}};//多一点

        int[][] array3 = new int[][]{{1, 2, 3}, {4, 5, 6}};
    }
  • 打印二维数组
/*
    打印二维数组
     */
    public static void main(String[] args) {
        int[][] array2 = {{1, 2, 3},{4, 5, 6}};
        for (int i = 0; i < array2.length; i++) {//行数
            for (int j = 0; j < array2[i].length; j++) {//列数
                System.out.print(array2[i][j]+ " ");
            }
            System.out.println();
        }
    }
  • 不规则二维数组
/**
     *不规则二维数组
     * @param args
     */
    public static void main(String[] args) {
        int[][] array2 = new int[2][];//2行3列的数组。可以省略列,此时的二维数组,叫做不规则数组
        array2[0] = new int[2];
        array2[1] = new int[5];

        for (int i = 0; i < array2.length; i++) {
            for (int j = 0; j < array2[i].length; j++) {
                System.out.print(array2[i][j]+ " ");
            }
            System.out.println();//输出0 0
            //                        0 0 0 0 0
        }
        System.out.println("==================");
        System.out.println(Arrays.deepToString(array2));//深度打印
    }
  • 图解二维数组
    在这里插入图片描述
  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 19
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赢锋尹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值