目录
数组
数组就是用来存储同一类型若干数据的容器
定义数组
数组需要先定义再使用:
动态初始化:先定义数组,必须指定长度,再给元素赋值
数据类型[] 数组名 = new 数据类型[长度];
静态初始化:定义数组的同时赋值,数组长度由元素个数决定
数据类型[] 数组名 = new 数据类型[] {元素1,元素2......};或者数据类型[] 数组名 = {元素1,元素2......};
1.数据类型就是数组中存储元素的类型
2.[]表示定义数组
3.数组名是标识符
4.new运算符在堆中创建一个数组对象,分配一块连续的存储空间,把引用(地址)赋值给数组名
数组初始化后数组元素有默认值
访问元素
定义后数组会为每个元素制定索引值(下标),数组长度length就是数组中元素的个数,下标为[0,length - 1)
通过索引值访问数组元素实现存取:数组名[索引值],因为通过索引值就可以找到每个数组元素的地址(偏移量)
使用for循环遍历数组的每个元素
for (int i = 0; i < arr1.length; i++) {
System.out.print( arr[i] + " ");
}
使用增强的for循环,也称为foreach循环,格式为:
for( int i : arr ){
System.out.println(i);
}
数据类型就是数组元素的类型,程序在执行时会把数组中每个元素依次赋值给局部变量,再执行循环体
for循环可以访问数组元素,也可以修改,foreach只能访问
数组是一种引用数据类型
定义数组int[] arr = new int[10];arr就是引用类型的变量,数据类型是int[],arr存储的是数组的引用(地址)
赋值:int[] arr1 = arr;把arr变量的值赋给arr1,也就是arr1和arr存放了同一个地址,指向堆中同一个数组
方法是用来完成某个功能编写的代码,方法可以返回数组,返回值类型就是数组类型,数组也可以作为方法的参数
变长参数
变长参数用于接收任意个数据
定义变长参数的语法
方法返回值类型 方法名([参数类型 参数名,]参数类型 ... 变长参数名){}
1.方法的参数列表使用变长参数,可以接收任意多个数据
2.一个方法的参数列表中只能编写一个变长参数
3.变长参数只能写在参数列表末尾
4.在方法体中当作数组使用
数组扩容
定义数组时给定了长度,也就是存储数据的最大数量(容量),想再存储数据,必须对数组扩容
数组扩容就是定义一个更大的数组,把原数组中的元素复制到新数组,让原数组名指向新数组
//System.arraycopy(src源数组,scrPos,dest目标数组,destPos,复制个数);
//把src数组中从srcPos下标开始的length个元素复制到dest数组中从destPos下标开始的位置上
//Java提供的System类的静态方法arraycopy使用了native修饰,只有方法声明没有方法体,会调用SDK的本地方法,本地方法是用C语言写的,C语言可以直接操作Windows系统底层的代码,执行效率更高,即在Java中可以使用JNI(Java Native Interface)技术调用其他语言编写的代码
数组特点
优点:通过索引值可以计算出每个数组元素的地址,通过地址直接访问数组元素,效率高
缺点:向数组中插入/删除元素时,可能需要扩容,需要复制/移动大量元素,效率低
应用场景:以访问为主,很少有添加/删除操作时适合使用数组
对象数组
存储引用类型的对象的数组称为对象数组
基础算法
冒泡排序
把数组元素从前向后两两比较,如果前面的数大于后面的数则交换,实现由大到小的排序
for(int i = 1;i < data.length;i++){//外层循环控制比较轮次
for(int j = 0;j < data.length - i;j++){//内层循环控制比较的元素
if(data[i] > data[i + 1]){
//交换
}
}
}
选择排序
从当前数组元素中选择最小的交换到前面
for(int i = 0;min < data.length - 1;min++){//控制比较轮次
int min = i;//保存这轮最小元素的下标
for(int j = min + 1;j < data.length;j++){//
if(data[j] > data[min]){
min = i;
}
}
//把min标识的元素与i元素交换
if(min != i){
int t = data[min];
data[min] = data[i];
data[i] = t;
}
}
二分查找
也叫折半查找,前提数组有序,始终与中间元素比较,相等表示找到,比中间元素小范围缩小到左一半,比中间元素大范围缩小为右一半,继续与该范围的中间元素比较
Arrays工具类
java.util包中定义的Arrays类提供对数组操作的一组静态方法
Arrays.toString()//将数组输出为字符串
Arrays.sort()//数组排序
Arrays.copyOf()//数组复制,返回新数组
Arrays.binarySearch()// 二分查找
Arrays.fill()//填充
Arrays.copyOfRange()//取子串
//调用Arrays.sort(data)对data数组中员工对象进行排序, 数组元素排序需要对数组元素比较大小, 即比较data数组中存储的Employee员工对象 的大小, 当前Employee员工对象无法比较大小, 所以直接调用sort(data)排序时会产生异常
// Arrays.sort(data);
//给对象数组进行排序时,可以调用sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c) 方法, 第一个参数a就是要排序的对象数组, 第二个参数和第三个参数是指定对a数组中[fromIndex, toIndex)范围内的元素排序, 第四个参数Comparator指定一个比较器,
//Java把比较任意两个对象大小的功能抽象到Comparator接口中,上面sort方法第四个参数是comparator接口,在调用时可以传递实现类对象,也可以传递匿名内部类对象
Arrays.sort(data, 0, size, new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
//在Comparator匿名内部类中需要重写接口的抽象方法compare(o1, o2), compare方法通过参数接收两个比较大小的对象, compare方法返回一个int整数, 对于开发人员来说, 需要记住比较规则
//如果o1大于o1方法返回正数, o1等于o2返回0, o1小于o2返回负数对应升序排序
//如果o1大于o1方法返回负数, o1等于o2返回0, o1小于o2返回正数对应降序排序
//把对象数组中的元素根据工资降序排序, o1工资比o2工资大返回负数
if ( o1.getSalary() > o2.getSalary() ){
return -1;
}else if ( o1.getSalary() == o2.getSalary()) {
return 0;
}else {
return 1;
}
}
});
二维数组
就是数组的数组,二位数组的每个元素是一维数组
数据类型 [][] 二维数组名 = new 数据类型[二维数组长度][ 一维数组长度];
//在定义二维数组时, 一维数组的长度可以省略
int [][] twoInts = new int[8][]; //定义了二维数组twoInts, 有8个元素, 它每个元素是int[]类型, int[]是一种引用类型, 系统会把towInt3数组的8个元素默认初始化为null
//二维数组的静态初始化
int [][] twoInts = { new int[10], {1,2,3,6,4,5}, {} , ints1, ints2};
Arrays.deepToString()把二维数组 元素连接为字符串