什么是数组
数组是相同类型数据的有序集合
数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们
数组的声明创建
首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] array;//例: int[] nums; 推荐使用这种写法
或者
dataType array[];//例: int nums[];
使用new来创建数组的语法:
dataType[] array = new dataType[arraySize]//例 int[] nums = new int[10];
数组的元素是通过索引访问的,数组索引从0开始。
获取数组的长度:array.length
练习:用循环给数组赋值1到10,并输出数组的总和
public static void main(String[] args) {
//创建一个数组
int[] array = new int[10];
//sum为总和
int sum = 0;
//循环给数组赋值
for (int i = 1;i<=array.length;i++){
array[i-1] = i;
}
//循环遍历数组,把每位加到sum计算总和
for (int j = 0;j<array.length;j++){
sum = sum + array[j];
}
System.out.println("数组总和为:"+sum);
}
内存分析:
结合以上练习和这张简单的内存分析思维导图来简单分析一下数组是如何生成在java内存的?
三种初始化状态
静态初始化
int[] a = {1,2,3};
Man[] mans = {new Man(1,1)}//Man是类名
动态初始化
int[] a = new int[2];
a[0] = 1;
a[1] = 2;
数组的默认初始化
动态初始化包含了默认初始化。数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
int[] a = new int[2];//可以理解为一但通过new实例化了,数组的每个元素也同样的被实例化位默认值存在堆的空间里
数组的四个基本特点
其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
其元素必须是相同类型,不允许出现混合类型。
数组中的元素可以是任何数据类型,包括基本类型和引用类型。
数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
数组的使用
For-Each循环
public static void main(String[] args) {
int[] arrays = {1,3,5,7,9};
//JDK1.5以上可以使用,但是没有下标
for (int array : arrays) {
System.out.println(array);
}
}
数组作方法入参
public static void main(String[] args) {
int[] arrays = {2,4,6,8,10};
printArray(reverse(arrays));//输出10 8 6 4 2
}
//打印数组元素
public static void printArray(int[] arrays){
for(int i = 0; i < arrays.length; i++){
System.out.print(arrays[i]+" ");
}
}
数组作返回值
public static void main(String[] args) {
int[] arrays = {2,4,6,8,10};
//使用for-each遍历出反转后的数组
for(int array : reverse(arrays)){
System.out.print(array+" ");
}
}
//反转数组,从数组最后一个元素到第一个元素
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
for (int i = 0,j=arrays.length-1; i < arrays.length; i++,j--) {
result[j] = arrays[i];
}
return result;
}
多维数组
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
二维数组
int a[][] = new int[3][2]//可以看作一个3行2列的数组来理解
例:创建并打印二维数组的所有元素
public static void main(String[] args) {
int[][] arrays = {{1,2},{3,4},{5,6}};
for (int i = 0; i <arrays.length ; i++) {
for (int j = 0;j<arrays[i].length;j++){
System.out.print(arrays[i][j]+" ");
}
System.out.println();
}
}
Arrays类
数组的工具类
java.util.Arrays
由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意:是"不用”而不是"不能")
常用功能:
返回指定数组的内容的字符串表示形式,通过toString方法。
public static void main(String[] args) {
int[] arrays = {9,5,8,7,100,365,277,25,64};
System.out.println(Arrays.toString(arrays));
}
将指定的int值分配给指定的int数组的每个元素:通过fill方法。
public static void main(String[] args) {
int[] arrays = {9,5,8,7,100,365,277,25,64};
Arrays.fill(arrays,0);//给数组里面所有元素替换为0
System.out.println(Arrays.toString(arrays));
//输出[0, 0, 0, 0, 0, 0, 0, 0, 0]
int[] arr = {9,5,8,7,100,365,277,25,64};
// a - 要填充的数组
// fromIndex - 要用指定值填充的第一个元素(包括)的索引
// toIndex - 要用指定值填充的最后一个元素(排除)的索引
// val - 要存储在数组的所有元素中的值
Arrays.fill(arr,0,5,9);//给数组里面所有下标范围替换为9
System.out.println(Arrays.toString(arr));
}
对数组排序:通过sort方法,按升序。
public static void main(String[] args) {
int[] arrays = {9,5,8,7,100,365,277,25,64};
Arrays.sort(arrays);//数组进行排序:升序
System.out.println(Arrays.toString(arrays));
//输出[5, 7, 8, 9, 25, 64, 100, 277, 365]
}
比较数组:通过equals方法比较数组中元素值是否相等。
public static void main(String[] args) {
int[] arrays = {9,5,8,7,100,365,277,25,64};
int[] arrays2 = {9,5,8,7,100,365,277,25,64};
boolean flag = Arrays.equals(arrays, arrays2);
System.out.println("arrays和arrays2中的元素比较结果:"+flag);
}
冒泡排序
冒泡排序算法的运作:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。比较完最后一对则最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码示例:
public static void main(String[] args) {
int[] arrays = {9,5,8,7,100,365,277,25,64};
sort(arrays);
}
//冒泡排序:比较相邻的元素。如果第一个比第二个大,就交换他们两个的值
public static void sort(int array[]){
//temp是临时变量,用于比较的值进行交换
int temp = 0;
for (int i = 0; i < array.length-1; i++) {
for (int j = 0; j < array.length-1-i; j++) {
if(array[j]>array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(array));
}
以上代码通过可以通过断点Debug发现,排序过程中,执行完最后的排序后,虽然数据已全部排序完备,但程序无法判断是否完成排序
为了解决这一不足,可设置一个标志位flag来进行优化,将其初始值设置为false,表示被排序的表是一个无序的表,每一次排序开始前设置flag值为false,在进行数据交换时,修改flag为非true。在新一轮排序开始时,检查此标志,若此标志为false,表示上一次没有做过交换数据,则结束排序;否则进行排序;
例:
public static void main(String[] args) {
int[] arrays = {9,5,8,7,100,365,277,25,64};
sort(arrays);
}
public static void sort(int array[]){
//temp是临时变量,用于比较的值进行交换
int temp = 0;
for (int i = 0; i < array.length-1; i++) {
boolean flag = false;
for (int j = 0; j < array.length-1-i; j++) {
if(array[j]>array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = true;
}
}
if(flag==false){
break;
}
}
System.out.println(Arrays.toString(array));
}
稀疏数组
当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:
记录数组一共有几行几列,有多少个不同值
把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
如下图:左边是原始数组,右边是稀疏数组
例:一个有11行11列的五子棋盘,下了黑子和白字和没下棋子的地方我们可以用不同数字表示
(0:无)(1:黑)(2:白)
因为该二维数组的很多值是默认值0,因此记录了很多没有意义的数据。我们可以用稀疏数组来优化压缩
public static void main(String[] args) {
//1.创建一个二维数组array1 有11行11列 (0:无 1:黑 2:白)
int[][] array1 = new int[11][11];
//根据示例图表示,1在第二行第三列,2在第三行第四列
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始数组
System.out.println("输出原始数组");
for(int[] ints : array1){
for (int anInt : ints){
System.out.print(anInt+"\t");
}
System.out.println();
}
System.out.println("==========================================");
//2.获取有效值的个数
int sum = 0;//sum拿来记录有效个数
//11为二维数组的行数
for (int i = 0; i < 11; i++) {
//11为二维数组的列数
for (int j = 0; j <11 ; j++) {
//如果几行几列的值不是0,则有效值个数+1
if(array1[i][j]!=0){
sum++;
}
}
}
System.out.println("有效值的个数:"+sum);
//3.创建一个代表稀疏数组的数组array2
//sum+1中的+1是第一行要存放总共几行几列几个有效值的数据,3列是固定存放行、列、值
int[][] array2 = new int[sum+1][3];
array2[0][0] = 11;//总共多少行
array2[0][1] = 11;//总共多少列
array2[0][2] = sum;//有效值个数
//4.遍历二维数组,将非0的值存放在稀疏数组中
int count = 0;//记录行数
for (int i = 0; i < array1.length ; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j]!=0){
count++;//查找到一个有效值就+1行记录在稀疏数组array2中
array2[count][0] = i;//横坐标
array2[count][1] = j;//纵坐标
array2[count][2] = array1[i][j];//值
}
}
}
System.out.println("输出稀疏数组");
System.out.println("行"+"\t"+"列"+"\t"+"值");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"
+array2[i][1]+"\t"
+array2[i][2]+"\t");
}
System.out.println("==========================================");
//5.把稀疏数组array2还原为原始数组array3
//稀疏数组中array2[0][0]和[0][1]固定存放是总共几行几列,array2是11行11列
int[][] array3 = new int[array2[0][0]][array2[0][1]];
//给其中的元素还原它的值,注意i要从1开始,因为array2[0]行存取的是几行几列
for (int i = 1; i < array2.length; i++) {
//0是int数组中的默认值,所以只需要在有效值的位置还原
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//打印array3
System.out.println("输出还原数组");
for(int[] ints : array3){
for (int anInt : ints){
System.out.print(anInt+"\t");
}
System.out.println();
}
}
结果:
来源:https://www.cnblogs.com/TriggerBlog/p/14970575.html


猜你喜欢
- 一、定时任务的使用场景和常见的定时任务某个时间定时处理某个任务、发邮件、短信、消息提醒、订单通知、统计报表等定时任务划分单机定时任务:单机的
- 一、Statementimport java.sql.*;public class TestJDBC { public stati
- 曾经自学C#做计算机图形学的作业,GDI+画图确实好用,目前在找.NET的实习,尝试做了一个最基本的五子棋,复习一下C#的基本语法,目前只能
- 一、创建Config配置中心项目1.添加依赖 <dependency> <groupId>org.sp
- 前言假如你做了一个云盘类的app,或者可以保存用户导入的配置。用户在未来肯定需要获取这些文件,一个办法是写一个Activity,向一个文件管
- 1.XxlJob简介官方网址:https://www.xuxueli.com/xxl-jobXXL-JOB是一个分布式任务调度平台,其核心设
- 在.NET中有三种计时器:1、System.Windows.Forms命名空间下的Timer控件,它直接继承自Componet。Timer控
- 好久没有更新了,之前公司在做 关注/粉丝 这块儿缓存的时候,我选择的就是 Bitmap ,那时是我第一次见识到这种数据数组形式,用到的有 S
- 本文实例讲述了Android中悬浮窗口的实现原理。分享给大家供大家参考。具体如下:用了我一个周末的时间,个中愤懑就不说了,就这个问题,我翻遍
- 1 C++类型转换本质1.1 自动类型转换(隐式)利用编译器内置的转换规则,或者用户自定义的转换构造函数以及类型转换函数(这些都可以认为是已
- 堆溢出:/*** @author LXA* 堆溢出*/public class Heap{ public
- 如何实现封装可以分为两步:第一步:将类的变量声明为private。第二步:提供公共set和get方法来修改和获取变量的值。代码展示publi
- 本文实例为大家分享了Java实现斗地主的具体代码,供大家参考,具体内容如下import java.util.ArrayList;import
- Java%(取模运算)Java的取模运算1.实现算法public static double ramainder(double divide
- 功能:通过响应UI Textbox 的值向ListView 绑定新添加的纪录。UI XAML 代码<Grid Margin="
- 说到Java的本地存储,肯定使用IO流进行操作。首先,我们需要一个创建文件的函数createNewFile:public static bo
- 1. 运算符是什么?1.1 定义:对常量和变量进行运算操作的符号程序对数据进行运算时要用运算符1.2 常见运算符的概述1.3 表达式1.3.
- 前言Java.util包中的List接口继承了Collection接口,用来存放对象集合,所以对这些对象进行排序的时候,要么让对象类自己实现
- 场景既然要搞懂Redis分布式锁,那肯定要有一个需要它的场景。高并发售票问题就是一个经典案例。搭建环境准备redis服务,设置redis的键
- 一、设计模式概述设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他