Java入门(四)之 数组的定义与使用_头发都哪去了的博客-程序员宅基地

技术标签: jvm  Java学习  java  字符串  intellij idea  

数组基本用法

什么是数组

数组:一块连续的内存,且存储的是相同数据类型的集合。
数组本质上就是让我们能 “批量” 创建相同类型的变量。
例如:

  1. 如果需要表示两个数据, 那么直接创建两个变量即可 int a;int b。
  2. 如果需要表示五个数据, 那么可以创建五个变量 int a1; int a2; int a3; int a4; int a5;。
  3. 但是如果需要表示未知个数据,那么就不能创建未知个变量了。这时候就需要使用数组,帮我们批量创建。

注意事项:在 Java 中,数组中包含的变量必须是相同类型的。

创建数组

基本语法

// 动态初始化
数据类型[] 数组名称 = new 数据类型 [] {
     初始化数据 };
// 静态初始化
数据类型[] 数组名称 = {
     初始化数据 };

代码示例如下

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array1 = {
    1,2,3,4,5,6};//1.定义且初始化一个数组(静态初始化)。
        int[] array2 = new int[10];//2.定义了一个数组,但是没有初始化。new 关键字不可缺。
        int[] array3 = new int[]{
    1,2,3,4,5,6,7,8,9};//3.动态初始化数组。
    }
}

这个代码中,array1,array2,array3 都是局部变量;而{1,2,3,4,5,6},new int[10],{1,2,3,4,5,6,7,8,9}都是存放在堆区的。
在这里插入图片描述

注意: 数组,实际上是数组对象
在这里插入图片描述
引用不一定在栈上,取决于变量的位置。当变量做局部变量时,引用才在栈上。
在这里插入图片描述

所谓的 “引用” 本质上只是存了一个地址,Java 将数组设定成引用类型,这样的话后续进行数组参数传参,其实只是将数组的地址传入到函数形参中,这样可以避免对整个数组的拷贝(当数组可能比较长时, 拷贝开销就会很大)。

数组的使用

使用数组做局部变量时,必须对其初始化;若不知道引用对象,应使用引用对应的零值(null)。
我们来打印数组作为示例

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array = {
    1,2,3,4,5,6};
        int[] array2 = null;//array2 这个引用,不指向任何对象。
        //此时,我们来打印创建好的数组array。
        //3种方法
        //1.for 循环     length:数组的属性
        for (int i = 0; i < array.length;i++){
    
            System.out.print(array[i]+ " ");
        }
        System.out.println();
        //2.增强型for each循环
        for (int x :array) {
    
            System.out.print(x+ " ");
        }
        System.out.println();
        //3.使用操作数组工具类。
        //Arrays.toString 将数组以字符串的形式进行输出。
        /*String ret = Arrays.toString(array);
        System.out.println(ret);*/
        System.out.println(Arrays.toString(array));
    }
}

运行结果如下
在这里插入图片描述
这是三种打印数组的方式。
其中for()循环与for each () 循环的区别,for 循环通过下标 [ i ] 进行遍历整个数组;而for each () 循环遍历数组是不需要通过下标的。

注意事项

  1. 使用 array.length 能够获取到数组的长度。这个操作为成员访问操作符,在后期在面向对象中会经常用到。
  2. 使用 [ ] 按下标取数组元素。需要注意,下标从 0 开始计数。
  3. 使用 [ ] 操作既能读取数据,也能修改数据。
  4. 下标访问操作不能超出有效范围 [0, length - 1], 如果超出有效范围, 会出现下标越界异常。
import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array = {
    1,2,3,4,5,6};
        System.out.println(array[100]);
    }

运行结果如下
数组下标超出范围
这个异常的原因是数组下标超出范围(数组越界访问了)。

数组作为方法的参数

基本用法

我们还是用打印数组内容作为示例

public class TextDemo {
    
	public static void main(String[] args) {
    
		int[] arr = {
    1, 2, 3};
		printArray(arr);
		}
	public static void printArray(int[] a) {
    
		for (int x : a) {
    
			System.out.println(x);
			}
		}
}

运行结果如下
在这里插入图片描述
在这个代码中:

  1. int[] a 是函数的形参, int[] arr 是函数实参。
  2. 如果需要获取到数组长度, 同样可以使用 a.length

理解引用类型

一.参数传内置类型,代码如下:

public class TextDemo {
    
    public static void main(String[] args) {
    
        int num = 0;
        func(num);
        System.out.println("num = " + num);
    }
    public static void func(int x) {
    
        x = 10;
        System.out.println("x = " + x);
    }
}

执行结果
在这里插入图片描述
可以看出,修改形参 x 的值,不影响实参的 num 值。
在这里插入图片描述
二.参数传数组类型,代码如下:

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] arr = {
    1, 2, 3};
        func(arr);
        System.out.println("arr[0] = " + arr[0]);
    }
    public static void func(int[] a) {
    
        a[0] = 10;
        System.out.println("a[0] = " + a[0]);
    }
}

执行结果
在这里插入图片描述
可以看出,在函数内部修改数组内容,函数外部也发生改变。
此时数组名 arr 是一个 “引用” 。当传参的时候,是按照引用传参的。

认识 null

null 在 Java 中表示 “空引用” ,也就是一个无效的引用。

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] arr = null;
        System.out.println(arr[0]);
    }
}

执行结果如下
在这里插入图片描述
这是因为,null 的作用类似于 C 语言中的 NULL (空指针),都是表示一个无效的内存位置。因此不能对这个内存进行任何读写操作。一旦尝试读写,就会抛出 NullPointerException异常。

初识 JVM 内存区域划分

在这里插入图片描述

JVM Stack 虚拟机栈 :就是我们平时所说的栈,用来存储局部变量。
Native Method Stack 本地方法栈:C/C++代码。
Heap 堆:new 创建的对象都是在堆上保存,用来存放对象。
PC Register 程序计数器:只是一个很小的空间,用来保存下一条执行的指令的地址。
Method Area 方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法编译出的的字节码就是保存在这个区域。
Runtime Constant Pool 方法运行池:存放字面量(字符串常量)与符号引用。(从 JDK1.7 开始, 运行时常量池在堆上)

数组作为方法的返回值

将原来数组的值,扩大二倍。改变原数组。

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array = {
    1,2,3,4,5};
        System.out.println("数组扩大二倍前打印");
        System.out.println(Arrays.toString(array));
        int[] ret = fun(array);
        System.out.println("数组扩大二倍后打印");
        System.out.println(Arrays.toString(ret));
        System.out.println(Arrays.toString(array));
    	}
    public static int[] fun(int[] array){
    
        for (int i = 0;i < array.length;i++){
    
            array[i] = array[i] * 2;
        }
        return array;
    }
}

运行结果如下
在这里插入图片描述
可见,修改了原数组。
将原来数组的值,扩大二倍。不改变原数组。

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array = {
    1,2,3,4,5};
        System.out.println("数组扩大二倍前打印");
        System.out.println(Arrays.toString(array));
        int[] ret = fun(array);
        System.out.println("数组扩大二倍后打印新数组");
        System.out.println(Arrays.toString(ret));
        System.out.println("数组扩大二倍后,打印原数组");
        System.out.println(Arrays.toString(array));
        }
    public static int[] fun(int[] array){
    
        int[] ret = new int [array.length];
        for (int i = 0;i < array.length;i++){
    
            ret[i] = array[i] * 2;
        }
        return ret;
    }
}

运行结果如下
在这里插入图片描述
可见,未修改原数组。

这两个代码的区别在于,是否改变原数组。
这就是典型的数组作为方法的返回值。

数组练习

数组转字符串

这道题,在这一期前面的内容有写过,非常之简单。

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array = {
    1,2,3,4,5,6};
        String ret = Arrays.toString(array);
        System.out.println(ret);
    }
}

执行结果
在这里插入图片描述

Java 中提供了 java.util.Arrays 包,其中包含了一些操作数组的常用方法。
用自己的方法如下

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array = {
    1,2,3,4,5};
        //String ret = Arrays.toString(array);
        System.out.println(toString(array));
    }
    public static String toString(int[] array){
    
        String ret = "[";
        for (int i = 0;i <array.length;i++){
    
            ret += array[i];
            if (i != array.length-1){
    
                ret += ",";//各元素之间需要添加‘,’
            }
        }
        ret += "]";
        return ret;
    }
}

执行结果
在这里插入图片描述

数组拷贝

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array1 = {
    1,2,3,4,5};
        int[] array2 = new int[array1.length];
        System.out.println("拷贝完成前,打印数组array1");
        System.out.println(Arrays.toString(array1));
        System.out.println("拷贝完成前,打印数组array2");
        System.out.println(Arrays.toString(array2));
        System.out.println("=========================");
        for (int i = 0;i < array1.length;i++){
    
            array2[i] = array1[i];
        }//方法一
        
        /* array2 = Arrays.copyOf(array1,array1.length);
        //使用操作数组工具类
        //方法二
         */
        /*System.arraycopy(array1,0,array2,0,array1.length);
        方法三
         */
        /*array2 = array1.clone();
        方法四
         */
        System.out.println("拷贝完成后,打印数组array1");
        System.out.println(Arrays.toString(array1));
        System.out.println("拷贝完成后,打印数组array2");
        System.out.println(Arrays.toString(array2));
        //四种方法其中方法三最快。
        System.out.println("=========================");
        array2[0] = 99;
        System.out.println("修改array2后,打印数组array1");
        System.out.println(Arrays.toString(array1));
        System.out.println("修改array2后,打印数组array2");
        System.out.println(Arrays.toString(array2));
        //拷贝后修改array2数组的值,array1数组不发生改变。
    }
}

运行结果如下(其中四种方法的运行结果均相同)
在这里插入图片描述
只拷贝某个范围。

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array1 = {
    1,2,3,4,5};
        int[] array2 = new int[array1.length];
        array2 = Arrays.copyOfRange(array1,2,5);
        System.out.println(Arrays.toString(array2));
        // 范围拷贝
    }
}

执行结果
在这里插入图片描述

找数组中的最大元素

import java.util.*;

public class TextDemo {
    

    public static void main(String[] args) {
    
        int[] arr = {
    12,21,33,24,45,16};
        System.out.println(max(arr));
    }
    public static int max(int[] arr) {
    
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
    
            if (arr[i] > max) {
    
                max = arr[i];
            }
        }
        return max;
    }
}

执行结果
在这里插入图片描述

求数组中元素的平均值

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] arr = {
    1,2,3,4,5,6,7};
        System.out.println(avg(arr));
    }
    public static double avg(int[] arr) {
    
        int sum = 0;
        for (int x : arr) {
    
            sum += x;
        }
        return (double)sum / (double)arr.length;
    }
}

执行结果
在这里插入图片描述

查找数组中指定元素(顺序查找)

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] arr = {
    21,12,3,81,59,36};
        System.out.println(find(arr, 81));
    }
    public static int find(int[] arr, int toFind) {
    
        for (int i = 0; i < arr.length; i++) {
    
            if (arr[i] == toFind) {
    
                return i;
            }
        }
        return -1; // 表示没有找到
    }
}

执行结果
在这里插入图片描述

查找数组中指定元素(二分查找)

针对有序数组,可以使用更高效的二分查找。

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] arr = {
    1,2,3,4,5,6};
        System.out.println(binarySearch(arr, 6));
    }
    public static int binarySearch(int[] arr, int toFind) {
    
        int left = 0;
        int right = arr.length - 1;
        while (left <= right) {
    
            int mid = (left + right) / 2;
            if (toFind < arr[mid]) {
    
                // 去左侧区间找
                right = mid - 1;
            } else if (toFind > arr[mid]) {
    
                // 去右侧区间找
                left = mid + 1;
            } else {
    
                // 相等, 说明找到了
                return mid;
                }
            }
            // 循环结束, 说明没找到
        return -1;
    }
}

执行结果
在这里插入图片描述

检查数组的有序性

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] arr = {
    1,2,3,10,5,6};
        System.out.println(isSorted(arr));
    }
    public static boolean isSorted(int[] arr) {
    
        for (int i = 0; i < arr.length - 1; i++) {
    
            if (arr[i] > arr[i + 1]) {
    
                return false;
            }
        }
        return true;

执行结果
在这里插入图片描述

数组排序(冒泡排序)

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array = {
    9, 9, 8, 1};
        bubbleSort(array);
        System.out.println(Arrays.toString(array));
    }

    public static void  bubbleSort(int[] arr){
    
        for (int i = 0; i < arr.length; i++) {
    
            for (int j = arr.length - 1; j > i; j--) {
    
                if (arr[j - 1] > arr[j]) {
    
                    int temp = arr[j - 1];
                    arr[j - 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
}

执行结果
在这里插入图片描述

Java中,实现数组排序可以使用操作数组工具类。代码如下

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] arr = {
    3, 2, 5, 1};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

执行结果
在这里插入图片描述

数组逆序

给定一个数组,将里面的元素逆序排列。
思路
设定两个下标, 分别指向第一个元素和最后一个元素. 交换两个位置的元素.
然后让前一个下标自增, 后一个下标自减, 循环继续即可。

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] arr = {
    1, 2, 3, 4,5,6,7,8,9};
        reverse(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void reverse(int[] arr) {
    
        int left = 0;
        int right = arr.length - 1;
        while (left < right) {
    
            int tmp = arr[left];
            arr[left] = arr[right];
            arr[right] = tmp;
            left++;
            right--;
        }
    }
}

执行如下
在这里插入图片描述

数组数字排列

给定一个整型数组,将所有的偶数放在前半部分,将所有的奇数放在数组后半部分。代码如下:

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[] array = {
    1, 2, 3, 4, 5, 6,7,8};
        transform(array);
        System.out.println(Arrays.toString(array));
    }
    public static void transform(int[] arr) {
    
        int left = 0;
        int right = arr.length - 1;
        while (left < right) {
    
            // 该循环结束, left 就指向了一个奇数

            while (left < right && arr[left] % 2 == 0) {
    
                left++;
            }
            // 该循环结束, right 就指向了一个偶数
            while (left < right && arr[right] % 2 != 0) {
    
                right--;
            }
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
        }
    }
}

执行结果
在这里插入图片描述

二维数组

二维数组本质上也就是一维数组,只不过每个元素又是一个一维数组。
在这里插入图片描述

基本语法

数据类型[][] 数组名称 = new 数据类型 [行数][列数] {
     初始化数据 };

我们用打印一个二维数组作为示例,代码如下:

import java.util.*;

public class TextDemo {
    
    public static void main(String[] args) {
    
        int[][] array = {
    
                {
    1,2,3,4},
                {
    5,6,7,8},
                {
    9,10,11,12},
        };
        for (int row = 0; row < array.length; row++) {
    
            for (int col = 0; col < array[row].length; col++) {
    
                System.out.printf("%d\t", array[row][col]);
            }
            System.out.println("");
        }
    }
}

执行结果
在这里插入图片描述
二维数组的用法和一维数组并没有明显差别,因此我们不再赘述。
同理,还存在 “三维数组”,“四维数组” 等更复杂的数组, 只不过出现频率都很低,很少用到。

Java入门(四)之 数组的定义与使用,到这里就基本结束了。
下期带来Java入门(五)之 类和对象。各位铁铁,我们下期见。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Kaiiiiiiiiiiiiii/article/details/112397463

智能推荐

七、集合框架,Collection、list、set、map老师说集合学好了走到哪里都不怕-程序员宅基地

集合框架文章目录集合框架1. 数组2.collection集合collection集合方法2.1add方法增加字符串增加数组2.2clear方法2.3size方法2.3addAll方法2.4containsAll/contains方法2.5isEpty方法2.6iterator方法(重点掌握)2.7 remove/removeAll方法2.8 retinAll方法2.9toArray方法3.List集合方法-----ArrayList的特有方法3.1 add()插入到指定位置3.2 addAll方法插入3

openstack--T版—nava计算服务_nova conductor-程序员宅基地

nava计算服务①计算服务是openstack最核心的服务之一,负责维护和管理云环境的计算资源,它在openstack项目中代号是nova。②Nova自身并没有提供任何虚拟化能力,它提供计算服务,使用个同的应1驱动来与底层支持的Hypervisor(虚拟机管理器进行交互。所有的计算实例(虚拟服务器)由Nova进行生命周期的调度管理(启动、挂起、停止、删除等)③Nova需要keystone、glance、neutron、cinder和swift等其他服务的支持,能与这些服务集成,实现如加密磁盘、裸金属_nova conductor

乔布斯《遗失的访谈》摘记-程序员宅基地

壹、(5'13'')公司的真正价值在于员工。It was clear that the company(指惠普公司) recognized its true value was its employees.贰、(18'39'')独立思考和怀疑Nobody thinks deeply in business.Ask a lot of questions, think about...

newSQL 到底是什么?-程序员宅基地

数据库发展至今已经有3代了:SQL,传统关系型数据库,例如 MySQL noSQL,例如 MongoDB newSQLSQL 的问题互联网在本世纪初开始迅速发展,互联网应用的用户规模、数据量都越来越大,并且要求7X24小时在线。传统关系型数据库在这种环境下成为了瓶颈,通常有2种解决方法:升级服务器硬件虽然提升了性能,但总有天花板。数据分片,使用分布式集群结构对单点数据库进行数据分片,存放到由廉价机器组成的分布式的集群里。可扩展性更好了,但也带来了新的麻烦。以前在一个库里

Unix Shell 范例精解——awk课后题_unix shell范例精解 书后练习-程序员宅基地

题目数据如下Mike Harrington:(510) 548-1278:250:100:175Christian Dobbins:(408) 538-2358:155:90:201Susan Dalsass:(206) 654-6279:250:60:50Archie McNichol:(206) 548-1348:250:100:175Jody Savage:(206) 54..._unix shell范例精解 书后练习

计算机图形学之光线跟踪算法的研究与实现2017年我的优秀毕业论文-程序员宅基地

计算机图形学之光线跟踪算法的研究与实现2017年我的优秀毕业论文版权所有使用者请联系我 刘创QQ:9031885932.2.2 Phong光照模型事实上对于漫反射的物体表面,使用Lambert就足够,但是实际生活中并不存在这种理想的漫反射材质。Phong光照模型是现代真实图形学中提出的第一个有影响的光照明模型,不过该模型只考虑到了物体对直接光照的反射作用。此外,

随便推点

Java网络编程--简单聊天程序-程序员宅基地

背景  毕业设计前的练手,学校小比赛中的一个题目。开发环境  Java(eclipse)+Mysql简介  使用Java+Mysql开发以个简单的聊天工具,在本次项目(V1.0)中实现了:    1. 用户登录(客户端至服务器)    2. 登录服务器的用户可以公共聊天    3. 用户间可以实现私密聊天    4. 同一账号只能一地登录下一次版本更新..._第1题:java版即时聊天程序

在Ubuntu下安装Gnome 3-程序员宅基地

原文:http://www.ubuntusoft.com/in-the-ubuntu-install-gnome-3.html想预先看一下Gnome的情况,就看这里 Ubuntu 11.04下:sudo add-apt-repository ppa:gnome3-team/gnome3sudo apt-get updatesudo apt-get dis

微服务架构概述---扫盲片_颗粒度复杂度-程序员宅基地

不知从何而起,与微服务相关的技术已然成为检验一个程序员是否合格的第一要素,微服务这一名词无论是博客、社交媒体还是会议讲演 其热度绝对可以拔得头筹。可是当我试图百度出什么是微服务时,发现度娘的介绍含糊其辞,一个“新技术”也是足够让你微醺一会。图1、百度对微服务架构的解释然后试图搜些帖子看看,不过很少有人能讲清楚微服务到底是什么。于是便忍痛花了点银两买了这本名为《Spring Could ..._颗粒度复杂度

使用Dash开发交互式数据可视化网页--页面布局-程序员宅基地

Dash应用布局后续的操作前,需要安装如下Python包pip install dash==0.20.0 # The core dash backendpip install dash-renderer==0.11.2 # The dash front-endpip install dash-html-components==0.8.0 # HTML componen..._dash中的html.div()中的参数children

gdb在执行maintenance info program-spaces命令时coredump-程序员宅基地

coredump时的信息:(gdb) maintenance info program-spaces *** Error in `gdb': free(): invalid pointer: 0x0000000003c6bcf0 ***======= Backtrace: =========/lib64/libc.so.6(+0x7d1fd)[0x7fc875c0d1fd]gdb(fi

A JavaScript error occured in the main process-程序员宅基地

如图,打开某软件时,抛下错:A JavaScript error occured in the main processUncaught Exception:Error: Unable to find a valid app at Object.<anonymous> (E:\ProgramFiles(x86)\.....\resources\electron.asar\browser\init.js:121:9 at Object...