一:数组的介绍
数组是一种数据结构,它可以存储多个数据,一个数据就是一个元素,通常可以通过元素的下标来访问元素和为元素赋值!
一个数组中,只能存储一种数据类型的数据
二:数组的创建方式
2.1:静态初始化:由程序员显示的指定每个元素的初始值,由系统决定长度
int[] arr = new int[]{1,2,3};
int[] arr = {1,2,3}; //简化形式: 推荐
2.2:动态初始化:由程序员指定长度,由系统为数组元素分配初始值
byte,short, int, long: 0
float,double: 0.0
char: '\u0000'
boolean: false
引用类型(类,接口,数组): null
int[] arr = new int[3];
注:动态初始化和静态初始化不能同时使用!
三:遍历数组
3.1:普通for
public class Demo7 {
public static void main(String[] args) {
String[] ss = {"hello","world","java"};
for(int i=0; i<ss.length; i++) {
ss[i] = "test";
}
System.out.println(Arrays.toString(ss));//[test, test, test]
}
}
3.2:增强for(foreach并不能改变数组元素的值)
public class Demo {
public static void main(String[] args) {
for (String s : ss) {
s = "test";
}
System.out.println(Arrays.toString(ss));//[hello, world, java]
}
}
四:数组的内存图解
4.1:基本类型数组的初始化
public class Demo {
public static void main(String[] args) {
//定义一个int[]类型的引用变量
int[] arr; //①
//初始化数组,长度为3
arr = new int[3];//②
//为数组元素赋值
for(int i=0; i<arr.length; i++) { //③
arr[i] = i+10;
}
}
}
解释:
①步骤的时候,只是定义了一个引用变量,该变量没有指向任何有效的内存!
②步骤的时候,new关键字出现了,这时系统为数组开辟了空间,并给了默认值(因为数组的元素类型是int,所以默认值为0)
③步骤的时候,为数组中每一个元素赋完值后的效果图
4.2:引用类型数组的初始化
public class Demo{
public static void main(String[] args) {
//定义一个Person[]类型的引用变量ps
Person[] ps;
//为这个数组动态初始化,长度为2
ps = new Person[2];
//创建Person实例
Person p1 = new Person("wzj",22);
Person p2 = new Person("sbt",30);
ps[0] = p1;
ps[1] = p2;
//下面两句执行效果一样!
System.out.println(p1.MySelfIntroduce());;
System.out.println(ps[0].MySelfIntroduce());;
}
}
class Person{
String name;
int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String MySelfIntroduce() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
为什么最后两句输出的内容相同呢?原因是p1和ps[0]指向的是同一个对象!
五:没有多维数组:
int[][],你可以看成就是一个一维数组,只不过里面的元素是int[]类型的罢了
int[][] arr = new int[3][2];
public class Demo {
public static void main(String[] args) {
//静态初始化,可以看出来数组的长度为2,元素是一个一维数组长度也是2
int[][] arr = new int[][] {
{1,2},
{3,4}
};
//动态初始化
//方式一: 同时初始化两个维数
int[][] arr = new int[3][2];
//方式二: 先初始化数组的长度
int[][] arr = new int[3][];
}
}
注:int[][] arr = new int[x][]; 如果是动态初始化第一个[]必须写明长度
六:数组的工具类 Arrays
查找,复制,填充,排序等等
public class Demo7 {
public static void main(String[] args) {
int[] arr = {4,2,5,8,1,7};
int[] arr2 = {4,2,5,8,1,7};
int[] arr3 = {4,2,5,8,1,9};
int[] arr4 = {1,2,3};
int[] arr5 = {1,2,3,4};
// System.out.println(binarySearch(arr,23));
System.out.println(equals(arr,arr2));//为了不影响效果,应该把上一行注释掉!
System.out.println(file(arr3, 1));
int[] copy = copy(arr4,6); //大于原数组的长度--> copy:{1,2,3,0,0,0}
System.out.println(Arrays.toString(copy));//[1, 2, 3, 0, 0, 0]
int[] copyOfRange = copyOfRange(arr5,0,2);
System.out.println(Arrays.toString(copyOfRange));
}
/**
* 只复制: 数组中from...to的索引,包左不包右,不会发生数组越界异常!
* @param arr5
* @param from
* @param to
* @return
*/
private static int[] copyOfRange(int[] arr5, int from, int to) {
return Arrays.copyOfRange(arr5, from, to);
}
/**
* 将原数组复制成一个新数组,参数i是新数组的长度
* 如果i>原数组的长度,那么多出来的就根据原数组的类型补默认值
* 如果i<原数组的长度, 那就只复制这么长!
* @param arr4
* @param i
* @return
*/
private static int[] copy(int[] arr4, int i) {
return Arrays.copyOf(arr4, i);
}
/**
* 将数组中所以元素都填充成 i
* 注:也可以在数组中指定范围填充
* @param arr3
* @param i
* @return
*/
private static String file(int[] arr3, int i) {
Arrays.fill(arr3, i);
return Arrays.toString(arr3);
}
/**
* 比较两个数组的长度和元素是否相同
* 相同:返回true, 否则返回false
* @param arr
* @param arr2
* @return
*/
private static boolean equals(int[] arr, int[] arr2) {
return Arrays.equals(arr, arr2);
}
/**
* binarySearch(byte[], byte key):
* 查询key在byte[]中的索引,前提是该数组是排完顺序的
* 否则返回负数:怎么判断负数:(变量 & 1) != 0
* 注:也可以在数组中指定范围查找key
*/
private static int binarySearch(int[] arr, int i) {
Arrays.sort(arr);
// System.out.println(Arrays.toString(arr));//[1, 2, 4, 5, 7, 8]
return Arrays.binarySearch(arr,i);
}
}
七:数组的应用:一般是装一些固定的值:比如一年中的月份