6_Java数组

2022/3/26 9:22:53

本文主要是介绍6_Java数组,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

数组可以理解为 固定大小的、用来存储 相同类型 数据元素的数据容器,是一种数据类型(引用类型)。

数组起步

数组创建

  • 静态初始化

预先知道数组内容,创建数组时即指定数组元素的值。

/*
	数据类型[] 数组变量名 = {元素1,元素2,...,元素n};
	数据类型[] 数组变量名 = new 数据类型[]{元素1,元素2,...,元素n};
*/
int[] arr1 = {1,2,3,4};
int[] arr2 = new int[]{1,2,3,4};
  • 动态初始化

预先不知道数组内容,创建数组时指定数组长度,数组元素初始化为默认值(参考数据类型)。

/*
	数据类型[] 数组变量名 = new 数据类型[数组长度];
*/
String[] arrStr = new String[3]; // String 默认值 null

数组访问与操作

image

可以通过下标索引访问数组中的元素,索引从 0 开始,最大值 = 数组长度 - 1,可通过 数组.length 属性获得数组长度。

  • 如果访问时索引超过最大值,会报 java.lang.ArrayIndexOutOfBoundsException (数组下标越界异常)。

  • 如果数组变量的引用为 null ,会报 java.lang.NullPointerException(空指针异常)。

int[] arr1 = {1,2,3};
int ele = arr1[0];
arr1[1] = 12;
System.out.println(arr1.length);

数组遍历

  • 普通循环遍历
int[] datas = {1, 2, 4, 545, 11, 32, 13131, 4444};

for(int i = 0; i < datas.length; i++) {
  System.out.println(datas[i]);
}
  • 增强 for

JDK1.5 引进了一种新的循环类型,被称为 For-Each 循环或者加强型循环。

int[] datas = {1, 2, 4, 545, 11, 32, 13131, 4444};

for(int ele: datas) {
  System.out.println(ele);
}

多维数组

多维数组可以看成数组的数组,比如二维数组就是一个特殊的一维数组,每个元素都是一个一维数组。

二维数组本质上是行列集合,要确定某一个元素需要行索引和列索引来进行定位。

int[][] arr1 = {{1,2},{3,4,5},{6}}; // 静态初始化
int[][] arr2 = new int[3][4]; // 动态初始化

System.out.println(arr1[1][1]); // 4
/*
	打印一个 10 行的杨辉三角
*/

int[][] yangHui = new int[10][];

for(int i = 0;i < yangHui.length; i++){
	yangHui[i] = new int[i+1];
	for(int j = 0; j < yangHui[i].length; j++){
		if(j == 0 || j == yangHui[i].length - 1) {
			yangHui[i][j] = 1;
		} else {
			yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
		}
		System.out.print(yangHui[i][j] + " ");
	}
	System.out.println("");
}

内存分析

int[] arr1 = {1,2,3,4}; // arr1 实际指向数组空间的首地址

image

Arrays 常用方法

Arrays 位于 java.util 包中,包含操纵数组的各种静态方法。

  • toString 数组转字符串

对于多维数组,使用 Arrays.deepToString。

// 基本类型,此处例举 int
public static String toString(int[] arr)

public static String toString(Object[] arr)
import java.util.Arrays;

public class ArrayDemo {

    public static void main(String[] args) {
        int[] arr1 = {3,1,5,4,2,8,9};
        System.out.println(arr1);
        System.out.println(Arrays.toString(arr1));

        Human[] arr2 = {new Human("齐贝林",33)};
        System.out.println(arr2); // [Lcom.hello.base.Human;@1b6d3586
        System.out.println(Arrays.toString(arr2));
    }

}

class Human {
    public String name;
    public int age;

    public Human(String name,int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Human{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • sort 数组排序

sort 方法默认是从小到大排序,如果希望按照从大到小排序,可以通过 Comparable 接口或者 Comparator 外部比较器接口的比较方法实现。

// 基本类型,此处例举 int
public static void sort(int[] a)

// 对象类要实现 Comparable 接口
public static void sort(Object[] a)

// 通过 Comparator 外部比较器接口比较
public static <T> void sort(T[] var0, Comparator<? super T> var1)
import java.util.Arrays;
import java.util.Comparator;

public class ArrayDemo {

    public static void main(String[] args) {
        int[] nums = {2,5,0,4,6,-10};
        Arrays.sort(nums);
        System.out.println(Arrays.toString(nums));

        Human[] arrHuman1 = {new Human("龟仙人",100),
                new Human("齐贝林",33),
                new Human("雄霸",66)};
        System.out.println(Arrays.toString(arrHuman1));

		// 按年龄从小到大
        Arrays.sort(arrHuman1, new Comparator<Human>() {
            @Override
            public int compare(Human t1, Human t2) {
				// 返回 -1 表示 t1 小于 t2,0 表示 t1 等于 t2,1 表示 t1 大于 t2
                return t1.age - t2.age;
            }
        });
        System.out.println(Arrays.toString(arrHuman1));

		// 按年龄从大到小
        Arrays.sort(arrHuman1, new Comparator<Human>() {
            @Override
            public int compare(Human t1, Human t2) {
                return t2.age - t1.age;
            }
        });
        System.out.println(Arrays.toString(arrHuman1));
    }

}

class Human {
    public String name;
    public int age;

    public Human(String name,int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Human{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • binarySearch 二分查找指定元素

数组必须有序。

如果元素存在,返回第一次找到的元素下标,如果不存在,返回 -(插入点下标 + 1)

/*
	基本类型,此处例举 int
	var0 数组
	var1 目标元素
*/
public static int binarySearch(int[] var0, int var1) {
	return binarySearch0((int[])var0, 0, var0.length, (int)var1);
}

private static int binarySearch0(int[] var0, int var1, int var2, int var3) {
	int var4 = var1; // 起始位置
	int var5 = var2 - 1; // 结束位置

	while(var4 <= var5) {
		int var6 = var4 + var5 >>> 1;  // 中间位置
		int var7 = var0[var6];
		if (var7 < var3) { // 大于中间位置的值
			var4 = var6 + 1;
		} else {
			if (var7 <= var3) { // 等于中间位置的值
				return var6;
			}
			// 大于中间位置的值
			var5 = var6 - 1;
		}
	}

	return -(var4 + 1);
}
int[] arr = {0,2,3,4,10};
System.out.println(Arrays.binarySearch(arr,2)); // 1
System.out.println(Arrays.binarySearch(arr,5)); // -5
  • copyOf & copyOfRange 数组拷贝

基于原数组,复制一个新数组,实际是调用 System.arraycopy 方法进行拷贝。

/*
	src - 源数组。 
	srcPos - 源数组中的起始位置。 
	dest - 目标数组。 
	destPos - 目标数组中的起始位置。 
	length - 要复制的数组元素的数量。 
*/
public static void arraycopy(Object src,int srcPos,Object dest, int destPos,int length)
/*
	基本类型,此处例举 int
	var0 - 源数组
	var1 - 拷贝长度
*/
public static int[] copyOf(int[] var0, int var1) {
	int[] var2 = new int[var1];
	System.arraycopy(var0, 0, var2, 0, Math.min(var0.length, var1));
	return var2;
}

/*
	var0 - 源数组
	var1 - 拷贝起始位置
	var2 - 拷贝终点位置(不抱含)
*/
public static int[] copyOfRange(int[] var0, int var1, int var2) {
	int var3 = var2 - var1;
	if (var3 < 0) {
		throw new IllegalArgumentException(var1 + " > " + var2);
	} else {
		int[] var4 = new int[var3];
		System.arraycopy(var0, var1, var4, 0, Math.min(var0.length - var1, var3));
		return var4;
	}
}
int[] arrA = {3,11,5,7,2,1,9,6,12,1};
int[] arrB = Arrays.copyOf(arrA,arrA.length);
int[] arrC = Arrays.copyOfRange(arrB,1,3);
System.out.println(Arrays.toString(arrB));
System.out.println(Arrays.toString(arrC));
  • hashCode 哈希值

对于多维数组,使用 Arrays.deepHashCode。

public static int hashCode(int[] var0) {
	if (var0 == null) {
		return 0;
	} else {
		int var1 = 1;
		int[] var2 = var0;
		int var3 = var0.length;

		for(int var4 = 0; var4 < var3; ++var4) {
			int var5 = var2[var4];
			var1 = 31 * var1 + var5;
		}

		return var1;
	}
}
  • equals 数组比较

数组长度和数组元素都相等时才相等。

对于多维数组,使用 Arrays.deepEquals。

public static boolean equals(int[] var0, int[] var1) {
	if (var0 == var1) {
		return true;
	} else if (var0 != null && var1 != null) {
		int var2 = var0.length;
		if (var1.length != var2) {
			return false;
		} else {
			for(int var3 = 0; var3 < var2; ++var3) {
				if (var0[var3] != var1[var3]) {
					return false;
				}
			}

			return true;
		}
	} else {
		return false;
	}
}
  • asList 转集合
import java.util.AbstractList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class ArrayDemo {

    public static void main(String[] args) {
        int[] arr1 = {1,2,3};
        String[] arr2 = {"1","2","3"};
		// List<Object> list1 = Arrays.asList(arr1);
        List<Object> list1 = Demo.asList(arr1);
        List<Object> list2 = Demo.asList(arr2);
        for (Object obj1:list1) {
            System.out.println(obj1.toString());
        }
        for (Object obj2: list2) {
            System.out.println(obj2.toString());
        }
    }

}

/**
	仿写 Arrays 的 asList 方法
*/
class Demo{
	/*
		T...args,可以理解为数组,T 泛型,因此只能是引用类型数组
		基本类型会将整个数组作为 args 的元素
	*/
    public static <T> List<T> asList(T...args){
        return new Demo.DemoList(args);
    }

    public static class DemoList<E> extends AbstractList<E> {
        private final E[] a;

        DemoList(E[] var1) {
            this.a = Objects.requireNonNull(var1);
        }

        @Override
        public E get(int var1) {
            return this.a[var1];
        }

        @Override
        public int size() {
            return this.a.length;
        }
    }
}


这篇关于6_Java数组的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程