[JavaSE] 一维数组【排序】【查找】【复制】【扩容】【可变参数】—Day12
目录
一、数组的概念
1、简介
2、特性
3、特点
二、数组的作用
三、数组的声明
四、数组的初始化
1.静态初始化:
2.动态初始化:
五、数组的使用
六、数组的排序
冒泡排序
七、数组的查找
7.1.顺序查找:从头到尾遍历
7.2.二分法查找(把排好序的数组一分为二的查找)
八、扩展-数组的复制
知识点:数组的复制1
知识点:数组的复制2
九、扩展-数组的扩容
十、扩展-数组的删除
十一、扩展-数组作为返回值和参数
十二、扩展-可变参数
总结:
十三、Arrays工具类
一、数组的概念
1、简介
数组(Array),在 Java 中也属于一种数据类型,区别于 int,String 之类的基本数据类型,数组是引用数据类型的一种。数组是有序数组的集合,里面的每个元素都必须具有相同的类型,可以用不同的数组名加上不同的下标来定位数组中唯一的元素。
2、特性
在大部分计算机语言中,数组基本上都具有一下三大基本特性:
(1)一致性:数组中存储的所有元素都必须是相同数据类型的。
(2)有序性:数组中的元素是有序的,可以通过数组下标来访问的。
(3)不可变性:数组一旦初始化,数组中的元素个数就不可变了。
3、特点
(1)数组可分为一维数组、二维数组以及多维数组。
(2)数组中数值元素的默认值是0,引用元素的默认值是null。
(3)数组的索引都是从0开始,如果数组内有n个元素,那么最大下标就是(n-1)。
(4)数组元素的类型可以是任何的数据类型,包括数组这一个复合数据类型。
(5)数组初始化开辟的空间在内存中是连续的
(6)数组类型是从抽象类 Array 派生的引用类型。
二、数组的作用
一组数据的容器,存放数据,并且操作数据
三、数组的声明
//数据类型[] 数组名; 或 数据类型 数组名[];int[] a; int b[];
四、数组的初始化
1.静态初始化:
程序员指定元素,系统自动分配长度
//静态初始化1//String[] names = new String[]{"朴树","肖战","杨洋","任嘉伦","郑业成"};//静态初始化2(先声明,在初始化)//String[] names;//names = new String[]{"朴树","肖战","杨洋","任嘉伦","郑业成"};//静态初始化3(简化静态初始化1)String[] names = {"朴树","肖战","杨洋","任嘉伦","郑业成"};
2.动态初始化:
程序员指定长度,系统自动分配元素
//动态初始化1:String[] names = new String[5];//5 - 表示开辟5个连续的空间
默认值:
整数类型:0
浮点类型:0.0
字符类型:' '
布尔类型:false
引用类型:null(空)
静态初始化 vs 动态初始化
一开始我们就知道数据,就使用静态初始化
一开始我们就知道长度,就使用动态初始化
五、数组的使用
数组的使用包括:通过下标设置元素、获取元素,获取数组中元素个数和数组的遍历等等
//通过下标设置元素names[2] = "鹿晗"; //通过下标获取元素String n = names[2];System.out.println("通过下标获取元素:" + n);//徐精华 //获取数组中元素的个数int len = names.length;System.out.println("获取数组中元素的个数:" + len);//5 System.out.println("-------------"); //遍历 - for循环for(int i = 0;i<names.length;i++){ System.out.println(names[i]);} System.out.println("-------------"); //遍历 - 增强for循环/foreachfor(String element : names){//遍历names数组,依次取出元素赋值给element System.out.println(element);}
注意点1:
for vs foreach
遍历时需要操作下标的功能,就使用for循环
遍历时不需要操作下标的功能,就使用foreach循环
可参考文章:浅析Java中for循环和foreach循环的区别_Vengo€bs的博客-CSDN博客
注意点2:下标为负数或者大于等于长度会出现"数组下标越界异常"-ArrayIndexOutOfBoundsException
System.out.println(names[-10]);
System.out.println(names[5]);
六、数组的排序
冒泡排序
口诀:
N个数字来排队
两两相比小靠前
外层循环N-1
内层循环N-1-i
代码实现:
public class Test03{public static void main(String[] args){int[] is = {67,45,81,24,16};//冒泡排序for(int i = 0;i<is.length-1;i++){for(int j = 0;j is[j+1]){int temp = is[j];is[j] = is[j+1];is[j+1] = temp;}}}//打印for(int element : is){System.out.println(element);}}}
其他排序算法可参考:Java数组之8种排序算法_明天,你好呀的博客-CSDN博客_java8数组排序
七、数组的查找
7.1.顺序查找:从头到尾遍历
int[] is = {67,45,81,24,16}; int num = 81;//要查找的数据 for(int element : is){ if(element == num){ System.out.println("查找到元素了"); } }
7.2.二分法查找(把排好序的数组一分为二的查找)
前提条件:必须先排序
int[] is = {67,45,81,24,16};Arrays.sort(is);//排序int num = 81;//要查找的数据int start = 0;int end = is.length-1;while(start num){end = mid-1;}else if(is[mid] < num){start = mid+1;}else{System.out.println("查找到元素了");break;}}
八、扩展-数组的复制
知识点:数组的复制1
缺点:更改原数组,新数据中的数据也跟着改变
//原数组String[] names = {"朴树","肖战","杨洋","任嘉伦"};//新数组(将原数组中的对象地址赋值给新数组这个引用,names和newNames这两个引用是指向的同一个数组对象)String[] newNames = names;//改变原数组中的数据names[1] = "郑业成";//遍历新数组for(String element : newNames){System.out.println(element);}
知识点:数组的复制2
//原数组String[] names = {"朴树","肖战","杨洋","任嘉伦"};//新数组String[] newNames = new String[names.length];//遍历原数组,将原数组中的数据依次迁移到新数组中for(int i = 0;i<names.length;i++){newNames[i] = names[i];}//改变原数组中的数据names[1] = "郑业成";//遍历新数组for(String element : newNames){System.out.println(element);}
九、扩展-数组的扩容
需求:扩容后的数据长度是原来长度的1.5倍
//原数组String[] names = {"朴树","肖战","杨洋","任嘉伦"};//创建新数组(新数组长度是原数组长度的1.5倍)int capacity = names.length;//4int newCapacity = capacity + (capacity>>1);//6String[] newNames = new String[newCapacity];//将原数组的数据迁移到新数组中for(int i = 0;i<names.length;i++){newNames[i] = names[i];}//将新数组赋值给原数组names = newNames;//遍历原数组for(String element : names){System.out.println(element);}
十、扩展-数组的删除
缺点:数组作为容器,是存储数据的,不要轻易把容量给改小
//原数组String[] names = {"朴树","肖战","杨洋","任嘉伦"};//新数组String[] newNames = new String[names.length-1];//遍历原数组( 把除了"任嘉伦"以外的数据迁移到新数组中)int index = 0;for(String element : names){if(!element.equals("任嘉伦")){newNames[index] = element;index++;}}//将新数组赋值给原数组names = newNames;//遍历原数组for(String element : names){System.out.println(element);}
/**知识点:数组的删除2*///原数组String[] names = {"朴树","肖战","杨洋","任嘉伦"};//数据的迁移for(int i = 1;i<names.length-1;i++){names[i] = names[i+1];}names[names.length-1] = null;//遍历原数组for(String element : names){System.out.println(element);}
十一、扩展-数组作为返回值和参数
需求:设计一个方法,传入int类型的数组,返回最大值和最小值
这时候就需要数组作为返回值及参数,如下例:
int[] is = {67,45,81,24,16};int[] maxAndMin = getMaxAndMin(is);System.out.println("最大值为:" + maxAndMin[0]);System.out.println("最小值为:" + maxAndMin[1]);}public static int[] getMaxAndMin(int[] is){int max = is[0];int min = is[0];for(int i = 1;i<is.length;i++){if(max is[i]){min = is[i];}}int[] maxAndMin = new int[]{max,min};return maxAndMin;
十二、扩展-可变参数
需求:设计一个方法,传入两个int值,返回最大值
那么需求改变呢?
需求升级:三个int值比较大小
需求升级:四个int值比较大小
需求升级:....
这时就需要用到我们的可变参数
int max = getMax(1,2,3,4);//传入的参数作为元素压入到数组中System.out.println("最大值为:" + max);}public static int getMax(int... is){if(is.length != 0){//判断调用该方法时是否传入参数int max = is[0];for(int i = 1;i<is.length;i++){if(max < is[i]){max = is[i];}}return max;}return 0;}//可变参数后面不允许声明其他参数public static void method(int i,String... ss){}
总结:
1.可变参数底层就是数组
2.形参为可变参数,调用时可以根据需求传参或不传参
3.调用时传入的数据作为元素压入到数组中
4.可变参数后面不允许声明其他参数
十三、Arrays工具类
Arrays:Java给我们提供的专门操作数组的类,提供了一些排序、查找、替换...
工具类:该类中的方法都是静态的,使用类名调用即可
API:Java的各种类的使用说明书
下载链接: jdkapi1.8压缩包-Java文档类资源-CSDN下载
import java.util.Arrays;public class Test14{public static void main(String... args){int[] is = {67,45,81,24,16};//排序 - 16,24,45,67,81Arrays.sort(is);//查找/搜索//如果key在数组中,就返回下标;否则,返回 -插入点-1int key = 51;int index = Arrays.binarySearch(is,key);System.out.println("查询到元素的下标为:" + index);//-4//替换Arrays.fill(is,888);//局部替换Arrays.fill(is,1,3,666);//fill(目标数组,开始下标-包含,结束下标-不包含,要替换的值)//扩容int[] copyOf = Arrays.copyOf(is,is.length*2);//copyOf(目标数组,新的长度)//局部拷贝int[] copyOfRange = Arrays.copyOfRange(copyOf,2,5);copyOfRange(目标数组,开始下标-包含,结束下标-不包含)//将数组转换为字符串String str = Arrays.toString(copyOfRange);System.out.println(str);}}