Java基础-基础语法-数组

Java工程师知识树 / Java基础

数组简介:

数组(Array)是Java 语言中内置的一种基本数据存储结构,通俗的理解,就是一组数的集合,目的是用来一次存储多个数据。

数组是程序中实现很多算法的基础,可以在一定程度上简化代码的书写。

备注:

  1. 数组的好处:数组里的每个元素都有编号,编号从0开始,并且依次递增,方便操作这些元素;
  2. 使用Java数组:必须先声明数组,再给该数组分配内存;
  3. 数组对应在内存中一段连续空间。
  4. 数组元素必须是相同数据类型,也可以是引用数据类型,但是同一个数组中的元素必须是同一类数据类型。

数组的声明

Java数组有两种声明方式:

//数组的两种声明方式
int[] a;
int b[];

数组的初始化

Java数组有三种初始化方式:静态初始化、用new声明、用new声明的同时初始化

//静态初始化
int[] array1 = {4,5,6};
Integer[] b = {
 new Integer(1),
 new Integer(2),
 new Integer(3),
 3, //Autoboxing
 3 //Autoboxing
};

//用new声明,之后分别初始化数组中的每个元素,声明时需指定数组大小
int[] array2 = new int[3];
array2[0] = 1;
array2[1] = 2;
array2[2] = 3;
(注:如果数组元素类型为基本数据类型,在完成new操作之后,数组中的元素会自动初始化为空值,可以直接使用.)

//用new声明的同时初始化,这种方式不能指定数组的大小,数组大小由初始化列表中数据个数决定
int[] array3 = new int[]{1,2,3};

数组的遍历

//for循环遍历
System.out.print("for循环遍历数组:");
for(int i = 0; i < 3; i++){
    System.out.print("  " + arr[i]);
}

//foreach遍历数组
System.out.print("foreach循环遍历数组:");
for(int i: arr){
    System.out.print("  " + i);
}

//Lambda表达式
Arrays.stream(arr).forEach(item -> {
    System.out.print(item + " ");
});

基本数据类型对应数组中元素的默认值

int数组中元素默认值是:0
float数组中元素默认值是:0.0
double数组中元素默认值是:0.0
char数组中元素默认值是:'\u0000' 0
boolean数组中元素默认值是:false

public static void main(String[] args) {
    byte arrByte[] = new byte[1];
    for (int i = 0; i < arrByte.length; i++) {
        System.out.println("arrByte ==> "+arrByte[i]);
    }
    short arrShort[] = new short[1];
    for (int i = 0; i < arrShort.length; i++) {
        System.out.println("arrShort ==> "+arrShort[i]);
    }
    int arrInt[] = new int[1];
    for (int i = 0; i < arrInt.length; i++) {
        System.out.println("arrInt ==> "+arrInt[i]);
    }
    long arrLong[] = new long[1];
    for (int i = 0; i < arrLong.length; i++) {
        System.out.println("arrLong ==> "+arrLong[i]);
    }
    float arrFloat[] = new float[1];
    for (int i = 0; i < arrFloat.length; i++) {
        System.out.println("arrFloat ==> "+arrFloat[i]);
    }
    double arrDouble[] = new double[1];
    for (int i = 0; i < arrDouble.length; i++) {
        System.out.println("arrDouble ==> "+arrDouble[i]);
    }
    boolean arrBoolean[] = new boolean[1];
    for (int i = 0; i < arrBoolean.length; i++) {
        System.out.println("arrBoolean ==> "+arrBoolean[i]);
    }
    char arrChar[] = new char[1];
    for (int i = 0; i < arrChar.length; i++) {
        System.out.println("arrChar ==> "+arrChar[i]);
    }
}

多维数组

二维数组:(其实是一个一维数组,它的每一个元素又是一个一维数组),
可以看做是一张表格。
初始化分为动态初始化和静态初始化
动态初始化

int[][] arr = new int[3][2];

定义了一个二维数组,其中有3个一维数组,每一个一维数组中有2个元素

静态初始化

int[][] arr = new int{{1,2},{3,4},{5,6}};
int[][] arr = {{1,2},{3,4},{5,6}};

数组操作

  • 判断数组是否重复

  • 求最大最小值

  • 数组排序

数组的内存分配

分配内存空间

数组名=new 数据类型[数组长度];
解释:new关键字用来实现为数组或对象分配内存;数组具有固定的长度。获取数组的长度: 数组名.length

定义数组+分配内存空间

数据类型[]数组名=new 数据类型[数组长度];
解释:定义数组时不指定长度,分配空间时指定数组长度;如:String cities[] = new String[6];

数组元素

获取数组元素:数组名[下标值];
数组下标从0开始 比如:scores[0]=75;

数组的内存分配 栈内存和堆内存

解释:如定义一个数组 int[]scores将在栈内存中为scores 分配内存空间,其值是一个不确定的值。
当执行语句scores=new int[5]时,将在堆内存分配连续5个空间,每个空间4个字节,用于存放整型数据,其初始值为0,然后将该段空间首地址,也就是第一个元素的地址,比如0*3000,赋给scores变量。该地址相当于一个指针,指向堆内存中分配的空间。此时堆内存中分配的5个空间可以分别使用scores[0],一直到scores[4]来表示。当执行四个赋值语句时,分别用指定值填充到对应元素位置。如果此时将null值赋给scores时,scores变量将不再指向任何位置,此时堆内存中分配的空间就变成了垃圾,由垃圾回收器在某一时间进行回收。

在方法中定义的变量,包括基本数据类型变量和引用数据类型变量,都将在栈内存中分配空间,当超过变量作用范围后,自动回收。

操作数组的工具类-Arrays

static int binarySearch(type[] a, type key) /*使用二分搜索法来搜索key元素在数组中的索引;若a数组不包括key,返回负数。
    (该方法必须已按升序排列后调用)。 */
static int binarySearch(type[] a, int fromIndex, int toIndex, type key) /*使用二分搜索法来搜索key元素在数组中
    从fromIndex到toIndex的索引;若a数组不包括key,返回负数。(该方法必须已按升序排列后调用)。*/
static boolean[] copyOf(type[] original, int newLength) //复制指定的数组见下面备注
static byte[] copyOfRange(type[] original, int from, int to) //将数组的指定范围复制到一个新数组。 

static boolean equals(type[] a, type[] a2) //如果两个数组长度相等和元素一一相等,则返回 true 
static void fill(type[] a, type val) //将a数组所有元素都赋为val。
static void fill(type[] a, int fromIndex, int toIndex, type val) //将a数组从formIndex 到tiondex索引之间的元素都赋为val。  
static void sort(type[] a) //sort(int[] arr)对指定的数组按数字升序进行排序。 
static void sort(type[] a, int fromIndex, int toIndex) //对指定数组的从formIndex 到tiondex索引之间的元素按数字升序进行排序。 
static String toString(type[] a) //返回指定数组内容的字符串表示形式。多个数组元素之间用英文逗号或空格隔开。

动态数组

什么是动态数组

​ 数据结构中顺序表的物理实现,同类数据元素的集合,在计算机中以连续的地址存储,大小在创建时决定,但是可以改变。

为什么使用动态数组

​ 支持随机访问,查询速度快。但是插入和删除都需要移动元素,比起链表开销较大。如:java集合类中的ArrayList Vector等

动态数组实现代码(ArrayList原理)
/**
 * 顺序表的实现
 */
public class ArrayList<E> {
    private Object[] data = null; // data: 用来保存此线性表数据的数组
    private int capacity; // capacity: 线性表的容量
    private int current; // current: 当前数据的下标
    /**
     * 初始化为声明大小,则设置为10。
     */
    ArrayList() {
        this(10);
    }
    /**
     * 初始化线性表,声明保存数据的数组大小。
     * @param initialSize 顺序表的初始化大小
     */
    ArrayList(int initialSize) {
        if (initialSize >= 0) {
            this.capacity = initialSize;
            data = new Object[initialSize];
            current = 0;
        } else {
            throw new RuntimeException("初始化大小不能小于0:" + initialSize);
        }
    }
    /**
     * 在线性表的末尾添加元素,添加之前确认线性表是否已满
     * @param e 待加入的元素
     * @return
     */
    public boolean AddElement(E e) {
        ensureCapacity();
        data[current] = e;
        ++current;
        return true;
    }
    /**
     * 检查存储数据的数组容量,如果数组已经满,则扩充容量;否则不操作。
     */
    private void ensureCapacity() {
        int index;
        if (current == capacity) {
            capacity *= 2;
            Object[] newData = new Object[capacity];
            for(index = 0; index < current; ++index) {
                newData[index] = data[index];
            }
            data = newData;
        }
    }
    /**
     * 返回下标为index的元素
     * @param index 欲取得元素的下标
     * @return
     */
    public E get(int index) {
        validateIndex(index);
        return (E) data[index];
    }
    /**
     * 
     * @param index 待插入的位置
     * @param e 待插入的元素
     * @return
     */
    public boolean set(int index, E e) {
        validateIndex(index);
        data[index] = e;
        return true;
    }
    /**
     * 验证下标值是否合法,非法时抛出异常
     * @param index 待验证的下标值
     */
    private void validateIndex(int index) {
        if (index < 0 || index > current) {
            throw new RuntimeException("无效的下标:" + index);
        }
    }
    /**
     * 返回当前顺序表的大小
     * @return
     */
    public int size() {
        return current;
    }
    /**
     * 在指定位置插入指定元素
     * @param index 待插入的位置
     * @param e 待插入的元素
     * @return
     */
    public boolean insert(int index, E e) {
        validateIndex(index);
        ensureCapacity();
        for (int temp = current; temp > index; --temp) {
            data[temp] = data[temp - 1];
        }
        data[index] = e;
        return true;
    }
    /**
     * 删除下标为index元素
     * @param index 待删除元素的下标
     * @return
     */
    public boolean delete(int index) {
        validateIndex(index);
        for ( ; index < current - 1; ++index) {
            data[index] = data[index + 1];
        }
        data[current - 1] = null;
        --current;
        return true;
    }
    @Override
    public String toString() {
        String str = "[ ";
        for (Object o : data) {
            if (o != null) {
                str += o + " ";
            }
        }
        str += "]";
        return str;
    }
} 
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容