目录
1、数组的基本概念和语法
1)Java语言中的数组是一种引用数据类型。 不属于基本数据类型。数组的父类是Object。
2)数组实际上是一个容器,可以同时容纳多个元素。(数组是一个数据的集合。)
数组:字面意思是“一组数据”
3)数组当中可以存储"基本数据类型"的数据,也可以存储“引用数据类型”的数据。
4)数据因为是引用类型,所以数据对象是堆内存当中。(数组是存储在堆当中的)
5)数组当中如果存储的是"java对象”的话,实际上存储的是对象的引用(内存地址)”, 数组中不能直接存储java对象。
6)数组一旦创建,在java中规定,长度不可变。 (数据长度不可变);
7)数组的分类:一维数组,二维数组、三维数组、 多维数组... ( 一维数组较多,二维数组偶尔使用)
8) 所有的数组对象都有length属性(java自带的),用来获取数组中元素的个数。
9) java中的数组要求数据中元素的类型统一。比部int 类型数组只能存能int类型. Person类型数组只能存储Person类型。
例加:超市的物,购做袋中只能装苹果,不能同时装苹果和橘子。( 数组中存储的元素类型统一)
10)数组在内存方面存储的时候, 数祖中的元素内存地址(存储的每一个元素都是有规则的挨着排列的)是连续的。 内存地址连续这是数组存储元素的特点(特色)。数组实际上是一种简单的数据结构。
11)所有的数组都是拿“第一个小方框的内存地址“作为整个数组对象的内存地址。
12) 数组这种数据结构的优点和缺点是什么?
优点:查询/查找/检索某个下标上的元素时效率极高。可以说是查询效率最高的一个数据结构。
为什么检索效率高?
第一:每一个元素的内存地址在空间存储上是连续的。
第二:每一个元素类型相同,所以占用空间大小一样。
第三:知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址。直接通过内存地址定位元素,所以数组的检索效率是最高的。
数组中存储100个元素,或者存100万个元素,在元素查询/检索方面,效率是相同的,因为数组中元素查找的时候不会一个一个找 ,而是通过数学表达式计算出来的。 (算出一 个内存地址,直接定位的。)
缺点:
第一:由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率较低,因为随机增加元素会涉及到后面元素统一向前或者向后位移的操作。
第二:数组不能存储大数据量,因为很难在内存空间上找到一块特别大的连续的存储空间
2、声明和初始化一维数组
2.1 声明
数据类型[] 数组名;
e.g.:int[ ] array1; String[ ] array2; Object[ ] array3;
2.2 初始化
静态初始化语法格式
int [ ] array = (1,2,3,4,5);
使用静态方法初始化,方便不需要new对象
动态初始化语法格式
int [ ] array = new int[5];
,通过for循环赋值
public class HelloWorld{
public static void main(String[] args) {
//动态初始化一维数组
printArray(new int[3]);
//传递静态数组
printArray(new int[]{1,2,3});
}
public static void printArray(int[] array){
for(int i = 0;i < array.length;i++){
System.out.println(array[i]);
}
}
}
2.3 实例
采用静态初始化的方法
String[] str = ("abc","ert","ijn");
for(int i=0;i<str.length;i++){
System.out.println(str[i]);
}
采用动态初始化的方法
Object o1 = new Object();
Object o1 = new Object();
Object o1 = new Object();
Object[] objects = {o1,o2,o3};
//以上四行可换为下面一行
//Object[] object = {new Object(),new Object(),new Object()};
for(int i=0;i<object.length;i++){
System.out.println(Object[i]);
}
3、main方法的String数组
public class HelloWorld{
public static void main(String[] args) {
}
}
1)这个方法程序员负责写出来,JVM负责调用,JVM调用的时候传一个数组长度args为0的String数组;
2)关于String[ ] args
这个数组是留给用户的,用户可以在控制台输入参数,这个参数会自动转换为"String[ ] args"
Edit Configurations——>Program arguments 这里可以输入参数,
args.length访问输入字符串长度
args[]可以访问字符串内容
String username = args[0];
String password = args[1];
if(username.equals("admin") && password.equals("123")){
}
username.equals("admin") && password.equals("123")这样写容易造成空指针异常;
优化:"admin".equals(username) && "123".equals(password)不容易造成空指针异常;
4、继承关系的数组
数组中可以存放子类的对象,调用的方法是父类中存在的方法不需要向下转型,直接使用父类型引用调用即可
当调用子类中特有的方法时,需要向下转型再调用
public class HelloWorld{
public static void main(String[] args) {
Animal[] ani ={new Cat(),new Fish()};
for (int i =0;i<ani.length;i++){
ani[i].move();//调用的方法是父类中存在的方法不需要向下转型,直接使用父类型引用调用即可
if(ani[i] instanceof Cat){
Cat c = (Cat)ani[i];
c.catchMouse();//当调用子类中特有的方法时,需要向下转型再调用
}
if(ani[i] instanceof Fish){
Fish f = (Fish)ani[i];
f.swim();
}
}
}
}
class Animal{
public void move(){
System.out.println("动物在移动!");
}
}
class Cat extends Animal{
public void move(){
System.out.println("猫在爬!");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Fish extends Animal{
public void move(){
System.out.println("鸟儿在飞行!");
}
public void swim(){
System.out.println("鱼游泳");
}
}
5、一维数组的扩容
先建立一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到大数组中【数组扩容效率较低,减少数组的拷贝和扩容次数,提高效率】
6、数组拷贝
System.arraycopy(源,源的起始下标,目标,目标的起始下标,长度) Ctrl + P可以看提示
//拷贝源(从这个数组中拷贝)
int[] src = {1,11,,22,3,4};
//拷贝目标(拷贝到这个目标数组上)
int[] dest = new int[20];//动态初始化一个长度为20的数组,每一个元素默认值为0
//调用JDK Sydtem类中的arraycopy方法,来完成数据的拷贝
System.arraycopy(src,1,dest,3,2);
数组中如果存储的元素是引用数据类型,也可以拷贝
数组中如果存储的元素是对象,则拷贝的是内存地址
7、二维数组
7.1 二维数组的声明和初始化
(二维数组的每个元素是一个一维数组)
int[][] a = { {100,200,300},{12,23,45},{23,54,1},{23,54,1} }
7.2 length属性
//以上面例子说明length属性
a.length = 4;
a[0].length = 3;
//a[0]代表的是{100,200,300};
7.3 关于二维数组中元素的访问
1)取出二维数组中的第一个一维数组
a [0] = {100,200,300}
2)取出二维数组中的第一个一维数组的第一个元素
a [0] [0] = 100