> 文档中心 > [JavaSE] 一维数组【排序】【查找】【复制】【扩容】【可变参数】—Day12

[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);}}