Java数组

一、Java中有很多方式存储数据,为什么还要使用数组?

数组确实没有List、Set这些集合方便,但某些方面还是存在一些优势,如:速度,而且集合类底层也都是通过数组来实现的。数组是一种效率最高存储和随机访问对象引用序列的方式。

从上面时间消耗上面来说数组对于基本类型求和计算的速度是集合的5倍左右。其实在list集合中,求和当中有一个致命动作:list.get(i)。这个动作是进行拆箱动作,Integer对象通过intValue方法自动转换成一个int基本类型,在这里就产生了不必要的性能消耗。

数组是一种线性数据结构,使用连续内存空间存放相同数据类型,与其他容器相比,数组区别主要在于性能与保存基本类型的能力。数组是一种效率最高存储和随机访问对象方式,通过寻址公式,随机访问时间复杂可以达到O(1),但为了保持空间连续性,数组中插入、删除数据时,都要移动后面数据,该操作时间复杂度为O(n)。

由于数组空间上连续,借助CPU缓存机制,预读数组中数据,可提高访问效率。但由于数组是定长的,一旦声明之后就不可以改变长度,所以如果长度声明过大或者过小都会造成问题。

数组可以自动给数组中元素从0开始编号,方便操作元素。数组属于引用变量,并且数组长度是固定的。

Java中数组是一种引用数据类型,不属于基本数据类型。数组父类是object。

2.数组实际上是一个容器,可以容纳多个元素。数组是数据的集合,是集合中最简单的一种类型。

3.数组可以存储基本数据类型数据,也可以存储引用数据类型数据,但是在数组中存储引用数据类型时存储的是对象的地址,而不是直接存储对象。

4.数组对象在堆内存中,因为数组是引用数据类型。

5.所有数组对象都要length属性(Java自带)

6.数组都是拿首个元素的内存地址作为整个数组对象的内存地址。

7.int[]与person[]是一种数据类型只不过是引用数据类型,与int,char相似。Array1,Array2是变量名。

8.数组优点与缺点!查询/查找/检索某个下标的元素的效率极高,可以是查询速度最高。

为什么查找速度高?第一:第一个元素的内存地址在空间存储上是连续的。第二:每个元素类型都相同,所占内存空间大小一样。第三:知道第一个元素的内存地址,知道每一个元素占用内存空间的大小,又知道下标,所以通过一个数学表达式就可以算出某个下标元素的内存地址,直接通过内存地址定位元素,所以数组的检索效率最高。在有一百个元素的数组中和在有一百万元素的数组中,检索/查找元素的效率都是一样的因为数组找数据不是一个一个找,而是通过数学表达式计算出来(算出一个内存地址,直接定位的)。缺点:第一:由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者插入元素的时候,效率低,因为随机插入或者删除元素会涉及到后面元素统一向前或者向后位移的操作。第二:无法存储大数据量的数据,因为很难开辟很大的一片连续的存储空间。很多数据空间都是零星分布。

链表的优点:由于链表上的元素在空间存储上内存地址不连续。所以随机增删元素的时候不会有大量元素位移,因此效率高。在以后的开发中,如果遇到随机增删集合中元素的业务比较多时,建议使用linkedlist。链表缺点:不能通过数学表达式计算被查找的内存地址,每一次查找都是从头开始,节点开始遍历,直到找到为止,所以linkedlist集合检索/查找的效率低。

Java中数组和集合都可以用来存储一组数据,但它们各自有各自的优缺点和适用场景。

用数组的场景:

  1. 访问元素时的速度非常快,因为数组中的元素在内存中是连续存储的,可以直接计算出元素的地址,而不需要遍历整个数据结构。

  1. 如果能够预估数据量的大小,可以使用静态数组来保存元素。静态数组默认保存在栈内存中,速度比堆内存中的动态集合要快一些。

  1. 使用数组可以避免自动装箱和拆箱的开销,有利于节省内存和提高程序性能。

  1. 在需要使用多维数组和操作矩阵等场景下,使用数组更为合适。

用集合的场景:

  1. 集合可以动态地添加或删除元素,可以自动调整容量大小,比数组更为灵活。

  1. 在需要对数据进行排序、查找、去重、统计、分组等操作时,使用集合更为便捷。

  1. 使用集合类库提供的API可以大大简化代码编写的难度。例如:可以直接使用foreach语句对集合中的元素进行遍历,提高代码的可读性和编写效率。

  1. 如果需要使用到线程安全的集合可以考虑使用Java集合框架提供的线程安全集合类。

综上所述,对于数据量固定的静态结构化数据,可以使用数组。而对于动态数据或者需要进行复杂操作的情况,使用集合更为合适。

所以在性能要求较高的场景中请优先考虑数组。

数组使用有四个步骤:声明数组,分配空间,赋值,处理

元素类型[] 数组名 = new 元素类型[元素个数或数组长度];

元素类型[] 数组名 = new 元素类型[]{元素,元素,……};

元素类型[] 数组名 = {元素,元素,……};

Java 并不直接支持二维数组,但是允许定义数组元素是一维数组的一维数组,以达到同样效果。

声明二维数组的语法如下:

type arrayName[][]; // 数据类型 数组名[][];或

type[][] arrayName; // 数据类型[][] 数组名;

其中,type 表示二维数组类型,arrayName 表示数组名称,第一个中括号表示行,第二个中括号表示列。

注意:给数组分配空间时,必须指定数组能够存储的元素个数来确定数组大小。创建数组之后不能修改数组的大小。可以使用length 属性获取数组的大小。

数组的初始化:

int[] arr = new int[5];//创建数组第一种方式,此时默认值都是为0
arr[0] = 1;//数组的初始化
int[] arr = new int[]{3,5,1,7};//第二种方式:创建并初始化数组
int[] arr = {3,5,1,7};//第三种方式:创建并初始化数组
int[] arr;
arr = {1,2,3,4,5};//这种方式是错误的

//二维数组定义:数组类型[][] 数组名 = new 数组类型[一维数组的个数][每一个一维数组中元素的个数];
//二维数组可以初始化,和一维数组一样,可以通过 3 种方式来指定元素的初始值。这 3 种方式的语法如下:
type[][] arrayName = new type[][]{值 1,值 2,值 3,…,值 n}; // 在定义时初始化
type[][] arrayName = new type[size1][size2]; // 给定空间,在赋值
type[][] arrayName = new type[size][]; // 数组第二维长度为空,可变化

//多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组,例如:
String[][] str = new String[3][4];
//初始化
//1. 直接为每一维分配空间,格式如下:
type[][] typeName = new type[typeLength1][typeLength2];
//type 可以为基本数据类型和复合数据类型,typeLength1 和 typeLength2 必须为正整数,typeLength1 为行数,typeLength2 为列数。
//例如:
int[][] a = new int[2][3];//二维数组 a 可以看成一个两行三列的数组。

数组的常见异常:

//ArrayIndexOutOfBoundsException 索引值越界。
//原因:访问了不存在的索引值:
public static void main(String[] args) {
    int[] x = { 1, 2, 3 };
    System.out.println(x[3]);//数组角标从0开始
}
//NullPointerException 空指针异常:
//原因: 引用类型变量没有指向任何对象,而访问了对象的属性或者是调用了对象的方法。
public static void main(String[] args) {
    int[] x = { 1, 2, 3 };
    x = null;
    System.out.println(x[1]);
}

数组的遍历

public class Main {
    public static void main(String[] args) {
        int [] arr = {11,22,33,44,55};
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

JDK 1.5 引进了一种新的循环类型,被称为 For-Each 循环或者加强型循环,它能在不使用下标的情况下遍历数组。

语法格式如下:

for(type element: array)
{
    System.out.println(element);
}

该实例用来显示数组 myList 中的所有元素:

public class TestArray {   
    public static void main(String[] args) {      
    double[] myList = {1.9, 2.9, 3.4, 3.5};       
    // 打印所有数组元素      
    for (double element: myList) {         
        System.out.println(element);      
        }   
    }
}
//1.9  2.9   3.4  3.5

数组取MAX值:(MIN值同理)

public class Main {
    //public  int main(String[] args) {
    public  static void main(String[] args) {
        int[] arr = {11,22,33,44,55,66,77,88};
        int index = 0;
        int max = arr[0];//取数组中的第一个数据为max值

        for (int i = 0; i < arr.length; i++) {
            max = arr[i];
            index = i;
        }
        System.out.println("最大值是" + max + "下标是"+index);
        //return  max;
        //return  index;
    }
}

将数组元素倒置后输出:

public class Main {
    public  static void main(String[] args) {
        int[] arr = {11,22,33,44,55,66,77,88};
        int t;
        for (int i = 0; i < arr.length/2; i++) {
            t = arr[i];
            arr[i] = arr[arr.length-i-1];
            arr[arr.length-i-1] = t;

        }
        System.out.println("数组逆序存放后的状态为:" );
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

Arrays 类 (java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。)

给数组赋值:通过 fill 方法。

对数组排序:通过 sort 方法,按升序。

比较数组:通过 equals 方法比较数组中元素值是否相等。

查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。

遍历: toString() 将数组的元素以字符串的形式返回

查找: binarySearch()在指定数组中查找指定元素,返回元素的索引,如果没有找到返回(-插入点-1) 注意:使用查找的功能的时候,数组一定要先排序。

要把数组中内容打印出来,直接使用toString方法只会打印出数组地址,因此需要使用Arrays的toString方法,该方法支持入参可以是long,float,double,int,boolean,byte,object 型的数组。

public static void main(String[] args) {
int[] array = new int[]{10,30,50,40,60};
System.out.println(Arrays.toString(array));
    Arrays.sort(array);
System.out.println(Arrays.toString(array));
System.out.println("最小值:"+array[0]+";最大值:"+array[array.length-1]);
int result = Arrays.binarySearch(array, 40);
    System.out.println("目标值的角标:"+result);
}

public static void main(String[] args) {
int[][] a = new int[3][4];
System.out.println(a);//[[I@15db9742
System.out.println(a.length);//获取二维数组中存储的一维数组的个数3
System.out.println(a[0]);//获取的是二维数组中第一个一维数组:[I@6d06d69c
System.out.println(a[0].length);//第一个一维数组的长度:4
System.out.println(Arrays.toString(a[0]));//默认值都是0:[0, 0, 0, 0]
}

关于int[][] a = new int[3][4];为什么a.length = 3, a[0].length = 4

“a数组有3行4列”,我们直接取a.length的话,取的值是行数3;想取列数的话我们就可以给行数任意一个值比如你在for循环中的“i”,于是a[i].length就等于4了;

二、关于数组认识上的一个误区

String类的底层数据结构确实是一个char类型的数组,但是String本质上是一个类,不是基本数据类型char的数组。String类封装了这个底层的char数组,并提供了很多方法来操作这个字符串对象。因此,String是一个Java中非常重要的引用类型。String属于Java中的引用类型中的类。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值