1、概述
数组即一组相同类型的数;
数组是多个变量的集合。
2、定义数组
2.1 定义变量:
变量的数据类型,变量名,变量的初始值
2.2 数组的定义方法:(一次性定义多个相同类型的变量)
数据类型[] 数组名 = new 数据类型[数组的长度];
2.3 说明:
1.数据类型,表示定义的这一组变量的数据类型.
2.[],就是用来区分定义是数组还是普通的变量.
3.数组名,也是变量名,它的命名方法和命名习惯和变量一致.
4.new,表示的是创建了一个新的数组.
5.数据类型:需要和前面定义的数组的数据类型相同.
6.[数组的长度],表示定义的数组中的变量的个数.
3、获取数组中每一个变量
3.1 数组也有下标,从0开始一直到数组的 (长度-1) 结束.
例:
3.2 获取数组中的每一个元素====> 数组名[下标]
例:
获取下标为0的数值:数组名[0],比如数组名问number,则获取到的值为number[0].
4、数组的初始值
当使用数组来定义变量的时候,JVM会给每一个数组中的元素一个默认的初始值.
int代表的整数类型,初始值是0
double代表的浮点型,初始值是0.0
char类型是''
String类型是null
boolean类型是false
5、数组的下标
下标都是从0开始到 (数组名.length-1) 结束
6、数组的应用
6.1 给数值类型的数组中随机赋值
public class EX001 {
public static void main(String[] args) {
//1.创建一个数组
int[] nums = new int[100];
//2.获取数组中的每一位元素
//使用循环,循环数组的下标,然后通过数组名[下标],来获取每一位元素
// 下标的取值范围[0,.length-1]
for(int i=0;i<=nums.length-1;i++){
// nums[i],代表着数组中的每一个元素
//3.给每一个元素赋值(随机值)
nums[i] = (int)(Math.random()*10000);
}
}
}
6.2 从控制台上给数组中的每一个元素赋值
public class EX002 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//1.创建一个数组
int[] nums = new int[10];
//2.循环数组,获取数组中的每一个元素
for(int i=0;i<nums.length;i++){
//3.给每一元素从控制上输入内容
System.out.println("请输入第"+(i+1)+"个元素的值:");
nums[i] = input.nextInt();
}
}
}
6.3 输出数组中的每一个元素
public class EX003 {
public static void main(String[] args) {
int[] nums = new int[100];
//给数组中的每一个元素赋值
for(int i=0;i<nums.length;i++){
nums[i] = (int)(Math.random()*10000);
}
int count = 0;
//输出数组中的每一个元素
for(int i=0;i<nums.length;i++){
System.out.printf("%6d\t",nums[i]);
count++;
if(count%10==0){
System.out.println();
}
}
}
}
6.4 给一个长度位100的整数类型的数组中,赋1000-9000之间的随机值,并输出数组中所有可以被5整数的数,并且每一行只有5个
public class EX004 {
public static void main(String[] args) {
//1.创建一个长度位为100的int类型数组
int[] nums = new int[100];
//2.给数组中赋值,赋的值是1000-9000之间的随机数
for(int i=0;i<nums.length;i++){
int number = (int)(Math.random()*8001)+1000;
nums[i] = number;
}
//3.输出数组中的元素
//只输出可以被5整除的数
int count = 0;
for(int i=0;i<nums.length;i++){
if(nums[i]%5==0){
System.out.printf("%6d\t",nums[i]);
count++;
if(count%5==0){
System.out.println();
}
}
}
}
}
6.5 求数组中所有元素的和,平均值,最大值,最小值
public class EX005 {
public static void main(String[] args) {
int[] nums = new int[100];
int sum = 0;//保存所有元素的和
int max = 0; //最大值的初始值应该是所有元素中的最小值
int indexOfMax = 0; //保存的是最大值的下标
int min = 100000; //最小值的初始值应i该是所有元素中的最大值
for(int i=0;i<nums.length;i++){
nums[i] = (int)(Math.random()*10000);
sum = sum + nums[i];
}
//获取所有元素中的最大值和最小值
for(int i=0;i<nums.length;i++){
//如果当前的元素,比最大值还要大的话
if(nums[i] > max){
//需要将最大值改成当前的元素
max = nums[i];
indexOfMax = i; //当最大值修改的时候,同时也需要修改最大值的下标
}
if(nums[i] < min){
min = nums[i];
}
}
double avg = sum / (double)nums.length;
System.out.println("所有元素的和:"+sum);
System.out.println("所有元素的平均值:"+avg);
System.out.println("所有元素的最大值:"+max+",其下标为:"+indexOfMax);
System.out.println("所有元素的最小值:"+min);
}
}
7、数组的定义方式
7.1 数组的定义方式:
a.定义的数组,数组中的每一个元素的初始值都是默认值.
b.定义数组的时候,就给数组中的每一个元素赋值
public class EX006 {
public static void main(String[] args) {
//定义数组的同时,给数组每一个元素赋值
//数据类型[] 数组名 = new 数据类型[]{数组的初始值(使用,间隔)}
// int[] nums = new int[]{1,4,67,89,3,4,65};
// System.out.println(nums.length);
//每一个元素对应的下标,就是自定义的初始值的顺序
String[] strs = new String[]{"","","","","",""};
}
}
7.2 数组的排序
a.Java中提供了一种默认的排序方法,给数组中的所有的元素进行排序.
b.方法:Array.sort(数组名);
public class EX007 {
public static void main(String[] args) {
int[] nums = new int[]{568,4,8,64,3,987,584,999,265,1};
//如果没有使用循环,直接输出数组
//[I@4554617c,表示的是数组在内存中保存的位置(物理地址,是一组十六进制数)
// System.out.println(nums);
for(int i=0;i<nums.length;i++){
System.out.print(nums[i]+"\t");
}
System.out.println();
//排序:
//排序方法:Arrays.sort(数组名);是一种升序排序
Arrays.sort(nums);
System.out.println("排序完成之后(升序排序):");
for(int i=0;i<nums.length;i++){
System.out.print(nums[i]+"\t");
}
System.out.println();
System.out.println("排序完成之后(降序排序):");
//将下标从 最大值-0来取值,就是降序
for(int i=nums.length-1;i>=0;i--){
System.out.print(nums[i]+"\t");
}
System.out.println();
}
}
7.3 练习:
长度为10的数组中随机获取1000以内的整数,并且原序,升序,降序输出
public class EX008 {
public static void main(String[] args) {
int[] nums = new int[10];
for(int i=0;i<nums.length;i++){
nums[i] = (int)(Math.random()*1000);
}
for(int i=0;i<nums.length;i++){
System.out.print(nums[i]+"\t");
}
System.out.println();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
System.out.print(nums[i]+"\t");
}
System.out.println();
for(int i=nums.length-1;i>=0;i--){
System.out.print(nums[i]+"\t");
}
System.out.println();
}
}
7.4 编写数组的注意事项
a.数组总是和for循环联合使用.因为只有循环数组的下标,才可以获取数组中的每一个元素
b.使用for的时候,循环是数组的下标.
下标的取值范围:[0,数组的长度-1]
for(int i=0;i<数组的长度;i++)
如果倒序呢?下标的取值范围:[数组的长度-1,0]
for(int i=数组的长度-1;i>=0;i--){}
c.使用下标来获取数组的每个元素
7.5 字符串的排序
public class EX009 {
public static void main(String[] args) {
String[] strs = new String[]{"人之初", "性本善", "性相近", "习相远", "苟不教", "性乃迁", "教之道", "贵已专"};
for (int i = 0; i < strs.length; i++) {
System.out.print(strs[i] + "\t");
}
System.out.println();
//对数组进行排序
//是按照字符串中的每一个字符的ASCII值进行排序
//如果是中文,是按照中文字符的对应的编码方式(java中默认使用UTF-8)进行排序,
Arrays.sort(strs);
//排序之后输出
for (int i = 0; i < strs.length; i++) {
System.out.print(strs[i] + "\t");
}
System.out.println();
}
}
8、排序算法
a.排序的方式
b.常用的排序算法:冒泡排序法,直接插入排序法,快速排序法,合并排序法,希尔排序法等等.
c.冒泡排序法:
1.会比较数组中最后两位,大的放后面,小的放前面(默认排序都是升序)
2.一次比较相邻的两个数,按照上面的规则.
3.数组中完成一遍之后,再执行数组的长度次.
d.使用代码完成冒泡排序法
public class EX010 {
public static void main(String[] args) {
//定义数组
int[] nums = new int[]{5,8,9,10,2,6,11,23,59,65};
//冒泡排序法:
// 1.比较相邻的两个数
// 2.循环数组的长度次
for (int k = 0; k < nums.length; k++) {
for (int i = nums.length - 1; i >= 1; i--) {
int j = i - 1;
if (nums[i] < nums[j]) {
//需要将小的放再前面,大的放后面
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}
}
System.out.print("排序后:");
for(int m = 0;m < nums.length;m++ ){
System.out.print(nums[m]+"\t");
}
}
}
e.排序算法的指标:时间复杂度,空间复杂度
1.时间复杂度,表示的就是数组的循环的次数. O^2
2.空间复杂度,表示循环的过程中使用的元素的次数. 2*O
8、数组的一些其他操作
8.1 数组的复制
8.1.1 copyOf()
public class EX011 {
public static void main(String[] args) {
//源码:Arrays.copyOf(dataType[] srcArray,int length);
// 其中,srcArray 表示要进行复制的数组,length 表示复制后的新数组的长度。
//默认从原数组的第一个元素(索引值为 0)开始复制,
// 如果 length > srcArray.length,则目标数组中采用默认值填充;
// 如果 length < srcArray.length,则复制到第 length 个元素(索引值为 length-1)即止。
int[] arr1= {1,2,3,4};
int[] arr2= null;
arr2= Arrays.copyOf(arr1, 2);
System.out.println(Arrays.toString(arr2));
}
}
8.1.2 copyOfRange()
public class EX012 {
public static void main(String[] args) {
//源码:Arrays.copyOfRange(dataType[] srcArray,int startIndex,int endIndex)
//其中,srcArray 表示原数组,startIndex起始位置,endIndex结束位置
int[] arr1= {1,2,3,4};
int[] arr2= null;
arr2= Arrays.copyOfRange(arr1,1, 3);
System.out.println(Arrays.toString(arr2));
}
}
8.1.3 arraycopy()
public class EX013 {
public static void main(String[] args) {
//源码:System.arraycopy(dataType[] srcArray,int srcIndex,int destArray,int destIndex,int length)
//其中:
// srcArray 表示原数组;srcIndex 表示原数组中的起始索引;
// destArray 表示目标数组;destIndex 表示目标数组中的起始索引;
// length 表示要复制的数组长度。
int[] arr1= {1,2,3,4};
int[] arr2= {2,3,5};
System.arraycopy(arr1, 0, arr2, 0, 3);
System.out.println(Arrays.toString(arr2));
}
}
8.2 给数组中添加一个元素
在java中,如果一个数组被创建,那么它的长度就是固定的,不可以修改.
public class EX014 {
public static void main(String[] args) {
String[] strs = {"a","b","c","d","e","f"};
// 1.创建一个新的数组,新数组的长度是strs+1
String[] strs2 = new String[strs.length+1];
// 2.将新数组的前 strs.length 位复制成 strs中的相同下标的内容.
// 循环原来数组strs的下标
for(int i=0;i<strs.length;i++){
strs2[i] = strs[i];
}
// 3.将新数组的最后一位赋值成需要添加的元素.
strs2[strs2.length-1] = "h";
// 4.新数组就是添加元素之后的内容.
for(int i=0;i<strs2.length;i++){
System.out.print(strs2[i]+"\t");
}
}
}
8.3 拼接两个数组
public class EX015 {
public static void main(String[] args) {
String[] strs = {"人之初","性本善","性相近","习相远"};
String[] strs2 = {"苟不教","性乃迁","教之道","贵以专"};
//1.创建一个新的数组,新数组的长度,两个数组的长度之和
String[] strs3 = new String[strs.length+strs2.length];
//2.将第一个数组赋值给新数组,
// 新书组的下标和strs数组的下标一一对应
for(int i=0;i<strs.length;i++){
strs3[i] = strs[i];
}
//3.将第二个数组赋值给新书组
// 新书组:strs.length ====> strs2 : 0
for(int i=0;i<strs2.length;i++){
strs3[strs.length+i] = strs2[i];
}
//4.新数组就是合并之后的
for(int i=0;i<strs3.length;i++){
System.out.print(strs3[i]+"\t");
}
}
}
注意:
就是下标的对应关系.
8.4 删除
a.找到需要删除的元素在数组中的下标位置
b.下标之前的内容,下标是一一对应的.
c.下标之后的内容:
新书组:下标-1 = 原数组:下标
public class EX016 {
public static void main(String[] args) {
String[] strs = {"a","b","c","d","e","f"};
//删除d
int index = -1;
for(int i=0;i<strs.length;i++){
if(strs[i].equals("d")){
index = i;
break;//可以没有的.
}
}
String[] strs2 = new String[strs.length-1];
//下标之前的一一对应
for(int i=0;i<index;i++){
strs2[i] = strs[i];
}
//下标的之后的 -1 对应(减1)
for(int i=index+1;i<strs.length;i++){
strs2[i-1] = strs[i];
}
for(int i=0;i<strs2.length;i++){
System.out.println(strs2[i]);
}
}
}
9、数组的常见问题
9.1 数组下标超出范围异常
如果使用数组的时候,下标超出了[0,.length-1]范围的话,会产生异常:ArrayIndexOutOfBoundsException
//错误示例
public class EX011 {
public static void main(String[] args) {
int[] arr= {1,2,3};
System.out.println(arr[4]);
}
}
报错信息:
9.2 空指针异常
当使用一个空引用数组时,如尝试获取或赋值给数组中的元素,会产生异常NullPointerException。
//错误示例
public class EX011 {
public static void main(String[] args) {
int[] arr= null;
System.out.println(arr[1]);
}
}
报错信息:
9.3 输入的格式不匹配异常
Input(输入)Mis(丢失)match(符合匹配)Exception