JavaSE自学笔记(6)

本文详细介绍了Java中数组的定义、初始化、赋值以及两种遍历方法。同时,深入探讨了Arrays工具类的常用方法,包括二分查找、数组相等判断、填充、排序和拷贝。此外,还提供了自定义实现toString、copyOf和copyOfRange以及冒泡排序和二分查找的示例代码,帮助读者更好地理解和运用Java数组操作。

数组:元素的线性集合
1.定义方式一:
(1)int[] a = {1,2,3,4};定义时初始化。
(2)int[] a; a = {1,2,3,4};不可以先定义,再初始化。
2.定义方式二:
(1)int[] a = new int[]{1,2,3,4};可以定义初始化
(2)a = new int[]{5,6,7,8};也可以赋值
(2)int[] a = new int[5];定义一个长度为5 的数组,元素的默认值是0对应的各种类型

1.数组的定义初始化与赋值

import java.util.Arrays;

public class 定义int类型数组的变量 {
    public static void main(String[] args) {
        int[] a;
        System.out.println(a);//数组只定义了,没有初始化
        int[] a={1,2,3,4};
        System.out.println(a);//可以运行,但不打印数组
        int[] a;
        a={1,2,3,4};
        System.out.println(a);//不可以先定义再赋值

        String[] a = new String[]{"hello","world"};//初始化
        a = new String[]{"go","come","yes","no"};//赋值

        int[] a = new int[5];//定义一个数组,元素类型是int,长度是5
                             //其中每个元素的值都是int类型的默认值-0;
        int[] b = method();//可以直接调用方法返回一个数组
    }

    private static int[] method() {
        return new int[]{9,8,7,6};
    }

}

2.数组的两种遍历方法

public class 定义int类型数组的变量 {
    public static void main(String[] args) {
        int[] a =new int[]{1,2,3,4};
        int b=a.length;
        System.out.println(b);
        System.out.println(Arrays.toString(a));
		
		//数组下标遍历
        for(int i=0;i<a.length;i++){
            int j=a[i];
            System.out.printf("%d ",j);
        }
        System.out.println();
		
		//数组全体遍历
        for(int i:a){
            System.out.println(i);
        }
    }
}

3.使用Arrays中的常用方法

import java.util.Arrays;

public class 使用Arrays中的方法 {
    public static void main(String[] args) {
        testBinarySearch();//测试二分查找
        testEquals();//测试数组相等
        testFill();//数组填充
        testSort();//数组排序
        testCopy();//数组拷贝
        testCopyRange();//数组范围拷贝
    }

    private static void testCopyRange() {
        long[] a = { 1, 2, 3, 4, 5 };

        // [from, to)
        //long[] copy = Arrays.copyOfRange(a, 3, 4);
        //long[] copy = Arrays.copyOfRange(a, 3, a.length);
        long[] copy = Arrays.copyOfRange(a, 3, 10);//拷贝a数组从3到10
        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(copy));
    }

    private static void testCopy() {
        long[] a = { 1, 2, 3, 4, 5 };
        System.out.println(Arrays.toString(a));

        long[] copy = Arrays.copyOf(a, 3);// 新数组长度小于源长度
        long[] copy = Arrays.copyOf(a, 5);// 新数组长度等于源长度
        long[] copy = Arrays.copyOf(a, 10);// 新数组长度大于源长度

        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(copy));

        Arrays.fill(a, 100);//数组填充,填充100
        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(copy));
    }

    private static void testSort() {
        long[] a = { 9, 5, 2, 7, 1, 6, 8, 3, 0, 4 };
        System.out.println(Arrays.toString(a));
        Arrays.sort(a); // In-place Sort 原地排序
        System.out.println(Arrays.toString(a));
    }

    private static void testFill() {
        long[] a = new long[10];
        System.out.println(Arrays.toString(a));
        Arrays.fill(a, 1, 8, 100);//a数组从1到8填充100
        System.out.println(Arrays.toString(a));
    }

    private static void testEquals() {
        long[] a = { 1, 2, 3, 4 };
        long[] b = { 1, 2, 3, 0 };

        b[3] = 4;
        System.out.println(Arrays.equals(a, b));//true
    }

    private static void testBinarySearch() {
        long[] a = { 9, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9 };
        System.out.println(Arrays.binarySearch(a, 1));  // 由于数组无序,返回什么都是合理的

//        System.out.println(Arrays.binarySearch(a, 3));  // 2
//        System.out.println(Arrays.binarySearch(a, 4));  // 3 OR 4
//        System.out.println(Arrays.binarySearch(a, -1)); // -1
//        System.out.println(Arrays.binarySearch(a, 10)); // -11
    }
}

4.自写toString,copyOf,copyOfRange,冒泡排序,二分查找

public class MyArrays {
    // "[1, 2, 3, 4]"
    public static String toString(long[] array) {
        String ans = "[";

        // 遍历 除了 最后一个元素之外的其余所有元素
        for (int i = 0; i < array.length - 1; i++) {
            long element = array[i];

            // String + long + String
            // String + String.valueOf(long) + String

            // "["
            // "[1, "
            // "[1, 2, "
            // "[1, 2, 3, "
            // "[1, 2, 3, 4, "
            ans = ans + element + ", ";
        }

        // 把最后一个元素添加到字符串 ans 中
        // 数组中最后一个元素的下标是 array.length - 1
        // 思考 array.length 的取值范围是多少 >= 0
        // "[1, 2, 3, 4, 5"
        if (array.length > 0) {
            long lastElement = array[array.length - 1];
            ans = ans + lastElement;
        }

        // "[1, 2, 3, 4, 5]"
        ans = ans + "]";

        return ans;
    }

    public static long[] copyOf(long[] original, int newLength) {
        if (newLength < 0) {
            throw new RuntimeException("newLength 必须 >= 0");
        }

        long[] ans = new long[newLength];

        // 下标(i) 走到哪个位置停下来?
        // original.length 和 ans.length 中小的一个
        int size = Integer.min(original.length, newLength);
        for (int i = 0; i < size; i++) {
            // 需要保证等号两边的下标使用都是合法的!!
            ans[i] = original[i];
        }

        // 如果 newLength > original.length 了
        // ans 中剩余的位置,已经是 long 类型的默认值了(0)
        // 所以我们不需要做什么事情了

        return ans;
    }

    // 0 <= from <= original.length && 0 <= from <= to
    public static long[] copyRangeOf(long[] original, int from, int to) {
        if (from < 0) {
            throw new RuntimeException("from 必须 >= 0");
        }

        if (from > to) {
            throw new RuntimeException("from 必须 <= to");
        }

        if (from > original.length) {
            throw new RuntimeException("from 必须 <= original.length");
        }

        int newLength = to - from;

        long[] ans = new long[newLength];

//        ans[0] = original[from];
//        ans[1] = original[from + 1];
//        ans[2] = original[from + 2];

        // i 假如代表的是 ans 的下标
        // i 的合法取值范围必须满足两个条件
        // 1. i 在 ans 中是合法下标  [0, ans.length)
        // 2. from + i 在 original 中是合法下标 [0, original.length)
        //    i 的取值范围 [-from, original.length - from)
        // 最后,i 的合法范围:[0, ans.length) 和 [-from, original.length - from) 的交集
        // i ~ [0, min(ans.length, original.length - from))
        int size = Integer.min(newLength, original.length - from);
        for (int i = 0; i < size; i++) {
            // 保证两边的下标都合法
            ans[i] = original[from + i];
        }

//        // i 假如代表的是 original 的下标
//        for (int i = from; i < ?; i++) {
//            ans[i - from] = original[i];
//        }

        // 思考过填充默认值的情况,和 copyOf 一样

        return ans;
    }

    public static void bubbleSort(long[] array) {
        // 一共有 array.length 个元素,需要经过 array.length - 1 次 “冒泡” 数组会有序

        for (int i = 0; i < array.length - 1; i++) {
            // 每循环一次,经过一次 “冒泡过程”
            // 把无序区间中的最大的数,冒泡到,无序区间的最后去

            // 数组看作一个整体区间,表示 [0, array.length)
            // 无序区间: [0, array.length - i)

            // 实现具体的冒泡过程
            // j 代表的是黑色下标
            // j ~ [0, array.length - i) 无序区间
            // j + 1 ~ [0, array.length - i) 无序区间 <=> j ~ [-1, array.length - i - 1)
            // j 需要取交集 [max(0, -1), min(array.length - i, array.length - i - 1))
            // j ~ [0, array.length - i - 1)
            for (int j = 0; j < array.length - i - 1; j++) {
                // j 需要保证 array[j] 和 array[j + 1] 的下标都合法
                if (array[j] > array[j + 1]) {
                    long t = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = t;
                }
            }
        }
    }


    // 前提:array 有序
    // 找到 target 所在的下标,如果 target 有多个,不保证找到哪一个
    // 如果没有找到,返回 -1
    public static int binarySearch(long[] array, long target) {
        // 待查找区间表示为: [low, high)
        // 带查找区间内的元素个数: high - low
        // 定义待查找区间的下限
        int lowIndex = 0;
        // 定义待查找区间的上限
        int highIndex = array.length;

        // 只要带查找区间内还有元素,查找过程就得继续
        while (highIndex - lowIndex > 0) {
            int midIndex = (lowIndex + highIndex) / 2;  // 暂时不考虑溢出的情况
            long midElement = array[midIndex];

            if (target == midElement) {
                return midIndex;
            } else if (target < midElement) {
                // 需要扔掉右边 [midIndex, ...)
                // highIndex 是开区间,所以 = midIndex,但区间里没有 midIndex 对应的元素
                highIndex = midIndex;
            } else {
                // 需要扔掉左边 [..., midIndex]
                // lowIndex 是闭区间,所以 = midIndex + 1,区间里没有 midIndex 对应的元素
                lowIndex = midIndex + 1;
            }
        }

        // high - low <= 0 换言之 带查找区间内一个元素都没有了
        // 说明 target 不在 array 中
        return -1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值