Java语言中的数组是一种引用数据类型,不属于基本数据类,数据的父类是Object。数组实际上是一个容器,可以同时容纳多个元素(数组是一个数据的集合),数组当中可以存储基本数据类的数据,也可以存储引用数据类的数据。因为数组是引用数据类型,所以数组是存储在堆内存中的
- 数组当中如果存储的是“java对象”的话,实际上存储的是对象的“引用(内存地址)”
- 数组一旦创建,在java中规定,长度不可变
- 数组的分类:一维数组、二维数组、三维数组、多维数组
- 所有的数组对象都有length属性,用来获取数组中元素的个数
- java中的数组要求数组中元素的类型唯一,例如int类型数组只能存储int类型
- 数组在内存方面存储的时候,数组中的元素内存地址是连续的
- 数组中每一个元素都有下标,小标从0开始,最后一个元素的下标是length-1
查询/检索某个下标上的元素时效率较高,因为每一个元素的内存地址在空间上存储是连续的,每一个元素类型相同,所以占用的空间大小一样,知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以,通过一个数学表达式就可以计算出某个下标上元素的内存地址,直接通过内存地址定位元素,所以数组的检索效率最高
一维数组缺点:由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率较低,因为随机增删元素涉及到后面元素统一向前或向后位移操作,但是数组中最后一个元素的增删没有影响。数组不能存储大数据量,因为在内存空间上,找不到一块特别大的连续的内存空间
声明/定义一个一维数组:int[] array1;
double[] array2;
boolean[] array3;
String[] array4;
Object[] array5;
初始化一维数组:// 静态初始化
int[] array1 = {100, 200, 300, 400};
// 动态初始化
int[] array1 = new int[5]; // 5表示数组内元素的个数,每个元素默认值0
String array2 = new String[5]; // 数组内元素个数为5,每个元素默认值null
静态初始化一个int类型的数组:public class ArrayTest {
public static void main(String[] args) {
// 声明一个int类型数组,静态初始化
int[] array1 = {100, 200, 300, 4000};
// 数组中每一个元素都有下标,所有的数组都有length属性
System.out.println(array1.length);
System.out.println("第一个元素" + array1[0]);
System.out.println("最后一个元素" + array1[array1.length - 1]);
// 修改
array1[0] = 110;
array1[array1.length - 1] = 0;
System.out.println("第一个元素" + array1[0]);
System.out.println("最后一个元素" + array1[array1.length - 1]);
}
}
数组的遍历:public class ArrayTest {
public static void main(String[] args) {
// 声明一个int类型数组,静态初始化
int[] array1 = {100, 200, 300, 4000};
for (int i = 0;i < array1.length;i++){
System.out.println("第" + i + "个元素是" + array1[i]);
}
// 超过数组下标取值会报错
// java.lang.ArrayIndexOutOfBoundsException
// System.out.println(array1[5]);
}
}
动态数组初始化:public class ArrayTest {
public static void main(String[] args) {
// 声明一个int类型数组,动态初始化
// 创建长度为5的int数组,数组中,每个元素默认值0
int[] array1 = new int[5];
for (int i = 0; i < array1.length; i++){
System.out.println(array1[i]);
}
}
}
当创建数组的时候,确定数组中存储哪些具体的元素时,采用静态初始化方式;当创建数组的时候,不确定数组中存储哪些数据,可以采用动态初始化的方式,预先分配内存空间
方法的参数是数组:public class ArrayTest {
public static void main(String[] args) {
// 调用方法的时候传一个数组
int[] array1 = {100, 2000, 400, 5000};
printArray(array1);
}
public static void printArray(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
public class ArrayTest {
public static void main(String[] args) {
// 调用方法的时候传一个数组
printArray(new int[3]);
System.out.println("========");
// 也可以这样写
printArray(new int[]{100,200,300,400});
}
public static void printArray(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
main方法上面的“String[] args”有什么用?JVM负责调用main方法,程序员负责写main方法,JVM负责调用该方法
JVM调用main方法的时候,会自动传一个String数组:public class ArrayTest {
public static void main(String[] args) {
System.out.println("JVM传递过来的String参数数组的长度:" + args.length);// 0
}
}
可以看到,数组对象创建了,但是数组中没有任何数据。其实这个数组是留给用户的,用户可以在控制台上输入参数,这个参数会自动被转换为“String[] args”。例如这样运行java程序:java ArrayTest abc def xyz,JVM会自动将“abc def xyz”通过空格的方式分离,分离完成之后,自动放到“String[] args”数组中。那么你可以自己试一下
public class ArrayTest {
public static void main(String[] args) {
System.out.println("JVM传递过来的String参数数组的长度:" + args.length);// 0
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
数组中存储的类型为引用数据类型:public class ArrayTest {
public static void main(String[] args) {
// 创建一个Animal数组
Animal animal1 = new Animal();
Animal animal2 = new Animal();
Animal[] animals = {animal1, animal2};
// 对Animal数组遍历
for (int i = 0; i < animals.length; i++) {
Animal a = animals[i];
a.move();
}
// Animal数组不能存放Animal类型,不能存放Product类型
// animals[2] = new Product();
// Animal可以存放Dog类型数据,因为Dog是Animal的子类
// 在这里数组不可以直接扩容的
// 所以修改最后一个元素的值 为Dog类型
animals[1] = new Dog();
for (int i = 0; i < animals.length; i++) {
animals[i].move();
}
}
}
// 动物类
class Animal{
public void move(){
System.out.println("Animal moving....");
}
}
// 商品类
class Product{}
// 狗类
class Dog extends Animal{
public void move(){
System.out.println("Dog eating bone.....");
}
}
public class ArrayTest {
public static void main(String[] args) {
// 创建一个Animal数组
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal[] animals = {animal1, animal2};
for (int i = 0; i < animals.length; i++) {
// 这里取出来的可能是Dog,Cat,但都属于Animal
// 如果调用的方法是父类中存在的方法不需要向下转型
// 直接使用父类型引用调用
// Animal a = animals[]i;
// a.move();
// 调用子对象特有的方法,需要向下转型
if(animals[i] instanceof Dog){
Dog d = (Dog)animals[i];
d.eatBone();
}else {
Cat c = (Cat)animals[i];
c.eatFish();
}
}
}
}
// 动物类
class Animal{
public void move(){
System.out.println("Animal moving....");
}
}
// 狗类
class Dog extends Animal{
public void move(){
System.out.println("汪汪汪....");
}
// 狗特有的方法
public void eatBone(){
System.out.println("狗在吃骨头");
}
}
// 猫类
class Cat extends Animal{
public void move(){
System.out.println("喵喵喵....");
}
// 猫特有的方法
public void eatFish(){
System.out.println("猫会吃鱼");
}
}
一维数组扩容和拷贝:在java开发中,数组的长度一旦确定不可变,如果想要进行数组扩容,需要先建一个大容量的数组,然后再将小容量数组中的数组一个一个拷贝到大数组中去,所以数组扩容效率较低,涉及到拷贝,所以再开发中尽量少的进行数组的拷贝。
public class ArrayTest {
public static void main(String[] args) {
// 拷贝源
int[] array1 = {1,22,11,33,44};
// 拷贝目标(拷贝到这个目标数组上)
int[] array2 = new int[20];
// 源,源数组的起点,目标数组,目标数组起点,拷贝长度
System.arraycopy(array1, 1, array2, 2,2);
// 遍历目标数组
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i]); // 0 0 22 11 0 ...
}
// 将array1全部拷贝到array2
// System.arraycopy(array1,0,array2,0,array1.length);
}
}
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!