什么是数组,一组数据,一堆数据:
所谓数组,是在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种数据形式。这些按一定顺序排列的同类型数据的集合称为数组。而数组中的每一个数据称之为数组元素,数组中的元素以索引来表示其存放的位置,索引从0开始,步长是1
基本数据类型:byte,short,int,long,float,double,char,boolean
引用数据类型:类,接口,数组.
变量的定义:
数据类型 变量名; 如: int age;
数组的定义:
方式1: 数组元素的类型[] 数组名; int[] ages;推荐的. 可以吧int[]看成是一种数据类型,int类型的数组类型.
方式2:数组元素的类型 数组名[]; int ages[];
数组必须先初始化,才能使用,因为初始化表示在内存中分配空间.
Java中数组必先初始化后才能使用,所谓初始化就是给数组元素分配内存,并为每个元素赋初始值。
初始化数组的两种方式:
静态初始化;
动态初始化;
无论,以哪种方式初始化数组,一旦初始化完成,数组的长度就固定了,不能改变,除非重新初始化。也就是说数组是定长的。
数组是定长的: 数组一旦初始化成功,数组中的元素个数就已经固定了,不能更改,如果需要更改,只能重新做初始化.
数组的静态初始化操作:
特点:有我们自己来为每一个数组元素设置初始化值,而数组的长度由系统(JVM)决定.
语法:
数组元素类型[] 数组名 = new 数组元素类型[]{元素1,元素2,元素3,…};
举例:
int[] nums = new int[]{1,3,5,7,9};
简单写法,必须声明之后,立刻初始化,不能先声明后初始化:
int[] nums = {1,3,5,7,9};
数组的动态初始化操作:
由我们来设置数组的元素个数(数组长度),而每一个数组元素的初始值有系统决定.
语法:
数组元素类型[] 数组名 = new 数组元素类型[ length ];
比如:
int[] ages = new int[100];
int[] nums = new int[5]{1,3,5,7,9};//写法是错误的,不能同时使用静态初始化和动态初始化.
什么时候使用静态初始化,什么时候使用动态初始化.
当我们事先知道,需要存储哪一些数据的时候,选用静态初始化.
当我们事先不知道,需要存储哪些数据的时候,只能使用动态初始化.
数组的基本操作:
1:数组基本操作:
获取元素: 元素类型 变量 = 数组名[index];
设置元素: 数组名[index] = 值;
遍历数组元素: 建议使用for循环,事先知道循环的次数.
数组长度: int len = 数组名.length; length是属性,不是方法.
索引范围: 从0开始,逐一递增. [0,数组名.length-1]
2:操作数组常见异常:
NullPointerException:空指针异常(空引用).
当数组还未初始化,就直接操作数组.
String[] bs = null;
System.out.println(bs.length)
ArrayIndexOutOfBoundsException:数组的索引越界异常.
3:获取数组最大最小元素(getMax,getMin).
4:打印数组元素:
直接打印数组的时候,打印出来是hashCode值,如[I@7439aca7.
我们不喜欢,我们想打印数组的时候,把该数组的元素打印出来.
String[] arr = {“A”,“B”,“C”,“D”,“E”};
main方法是static修饰的,说明直接使用Hello类调用即可.
在底层是JVM通过Hello.main(new String[]{});
main方法的String数组参数,其实是暴露给程序运行者的,用于给程序传递一个数据信息.
方法参数的值传递机制之基本数据类型
方法内部无法改变实参的值
方法参数的值传递机制之引用数据类型
因为引用类型的传递是传递内存地址,所以可以直接改变引用类型的值
前面说了,数组是多个数据的集合.
int[] arr = new int[] {1,3,5,7,9};
如果现在有多个数组,我想把多个数组保存在一个集合中,此时我又应该如何完成.
int[] arr1 = {1,2,3};
int[] arr2 = {4,5};
int[] arr3 = {6};
把上述的每个数组都作为一个元素,那么此时元素的类型为:int[].
数组的语法:
数组元素类型[] 数组名;
int[][] arr = new int[][] {
arr1 ,arr2,arr3
};
int[][] arr = new int[][] {
{1,2,3} ,
{4,5},
{6}
};
一维数组:数组中的每一个元素都是一个值(基本类型和引用类型的值).
二维数组:数组中的每一个元素又是一个一位数组.
三维数组:数组中的每一个元素又是一个二维数组.
严格上说,在Java中不存在多维数组的概念,和C语言做区分,一般称之为数组中的数组.
二维数组的初始化操作:
静态初始化:
int[][] arr = new int[][] {
{1,2,3} ,
{4,5},
{6}
};
动态初始化:
int[][] arr = new int[3][5] ;创建一个长度为3的二维数组,每一个元素(一维数组)的长度为5.
int[][] arr = new int[0][5]
针对于N维数组,需要N个循环嵌套.
Java5对数组的新语法支持:
1):增强for循环-foreach
2):方法的可变参数
增强for循环-foreach:
其实,我们在使用循环迭代数组的时候,往往是不关心迭代变量(数组的索引),有没有更好的方式,迭代数组元素的时候,就只操作数组元素,不去操作数组的索引.
从Java5开始(JDK1.5)开始,Java提供了一种新的语法:增强for循环(foreach).
语法:
for(数组元素类型 变量 : 数组名)
{
循环体
}
通过反编译工具查看字节码,发现foreach其实在底层依然是使用for循环+索引来操作数组的.
我们把增强for循环,称之为编译器的新特性---->语法糖.
语法糖的最大甜头就是:让开发者写更少,更简单的代码,完成相同的功能.
for循环功能比foreach更彪悍.
如果迭代数组元素,而不关心数组的索引的时候,首选使用foreach.
foreach还未结束—>集合框架.
方法的可变参数:
方法的可变参数,其实也是一个语法糖,编译器级别的新特性,让开发者写代码更简单.
方法的可变参数其底层是就是一个数组类型.
可变参数必须作为方法的最后一个参数,避免参数的歧义性.
推论:方法最大只有一个可变参数.
定义一个数组元素的拷贝方法,能支持任意类型的数组元素拷贝操作(反射).
数组拷贝操作,是经常使用到的,SUN就直接把数组的拷贝操作存放在JDK中的System类中.
Object:Java语言中的根类,老祖宗类,Object可以表示任意数据类型.
该方法没有方法体,该方法使用了native修饰符(本地方法),该方法底层使用了C/C++语言实现了,Java直接调用其他语言编写好的功能:
排序:按照指定的顺序排列出来.
升序:从小到大:
降序:从大到小.
排序的分类:
选择排序(直接选择排序、堆排序)
交换排序(冒泡排序、快速排序)
插入排序(直接插入排序、二分法插入排序、Shell排序)
归并排序等。
排序有升序排列和降序排列之分,我们现在单讲升序排列:
我们主要讲解冒泡,选择,插入排序,当然在开发中因为性能问题,我们都不会自己写排序算法,不过排序在笔试题里却是常客。
冒泡排序(Bubble Sort):
数据按照两个一组按顺序比较大小,第一个比第二个大就交换元素位置,一直比到尾,这样就得到了该数组最大值,下一次循环次数减一得到第二大值以此类推
选择排序(Selection Sort):
先把第一个元素当做最小值,和其他元素一一比对,如果比最小还要小,那这个元素的值当做最小值,最后得出这组元素的最小值,和第一个元素交换位置,下一次循环从第二位开始,把第二位当做最小值,一次类推
数组的搜索算法:从指定数组中去搜索某一个元素的索引是多少.
方式1:线性搜索(从头搜到尾/从尾搜到头):indexOf/lastIndexOf
对于元素过多的数组,性能极低:有N个元素,循环次数= (N + 1) / 2;
方式2:二分搜索法/二分查找法/折半查找.
前提:数组元素必须有顺序.
算法:当数据量很大适宜采用该方法。采用二分法查找时,数据需是排好序的