新手初学Java数组

什么是数组

  • 数组是相同类型数据的有序集合
  • 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
  • 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们

数组的声明创建

  • 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
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();
        }
    }

结果:

总结

本篇文章就到这里了,希望能够帮助到你,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Java开发必备知识之数组详解

    一.ASCII码 二.为什么需要数组 案例: 160班 现在 77人 统计 全班的Java成绩 用程序进行存储 变量 统计 全班不及格的同学 要 补考 补考过的同学 修改成绩 定义 77 个变量 int 帅 = 59: int 洋 = 100: int cto = 60: int ceo = 58: 三.什么是数组 概念:数组就是内存中一块 连续的 内存空间,用于存放 相同类型 的多个数据 四.定义数组 声明一个数组:确定数组中存放的数据类型 语法: 数据类型[] 数组名://建议 数据类型 [

  • 新手了解java 集合基础知识(二)

    目录 三.Map 1.HashMap 2.TreeMap 3.ConcurrentHashMap 总结 三.Map ​ 存储的双列元素,Key是无序的,不可重复,而Value是无序,可重复的. 1.HashMap public class HashMapDemo { private Map map = null; public void init() { map = new HashMap(); map.put("a", "aaa"); map.put("

  • 带你轻松搞定Java面向对象的编程--数组,集合框架

    目录 一.数组 1.数组的定义 2.数组的声明 3.数组的初始化 二.集合概述 三.Collection接口 1.Collection接口概述 2.集合框架的三个组件 3.Iterator接口 四.List接口 1.ArrayList类 2.LinkedList类 五.Set接口 1.HashSet类 六.Map接口 1.HashMap类 七.泛型 总结 一.数组 1.数组的定义 数组是为了解决同类数据整合摆放而提出的,可以理解为一组具有相同类型的变量的集合,它的每个元素都具有相同的数据类型.

  • 教你怎么用Java数组和链表实现栈

    一.何为栈? 栈(stack)又名堆栈,它是一种运算受限的线性表.限定仅在表尾进行插入和删除操作的线性表.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素:从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素. 栈可以类比成现实生活中的弹夹或者羽毛球桶 二.用数组实现栈 用数组模拟栈的思路分析如图: 1.定义一个top变量(指针)表示栈顶初始化为-1. 2.定义一个变量来记

  • 新手初学Java数组

    什么是数组 数组是相同类型数据的有序集合 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们 数组的声明创建 首先必须声明数组变量,才能在程序中使用数组.下面是声明数组变量的语法: dataType[] array;//例: int[] nums; 推荐使用这种写法 或者 dataType array[];//例: int nums[]; 使用new来创建数组的语法: dataType[] array =

  • 新手初学Java对象内存构成

    目录 Java对象内存构成 对象内存构成 对象头 Mark Word Klass Pointer# 实例数据 对齐数据 Talk is cheap, show me code 普通对象# 数组对象 总结 Java对象内存构成 今天来讲些抽象的东西 -- 对象头,因为我在学习的过程中发现很多地方都关联到了对象头的知识点,例如JDK中的 synchronized锁优化 和 JVM 中对象年龄升级等等.要深入理解这些知识的原理,了解对象头的概念很有必要,而且可以为后面分享 synchronized 原

  • 新手初学Java List 接口

    目录 源码展示 总结 源码展示 package java.util; import java.util.function.UnaryOperator; public interface List<E> extends Collection<E> { /** * 返回 list 中元素的个数. */ int size(); /** * list 是否为空. */ boolean isEmpty(); /** * list 是否包含某个对象. */ boolean contains(O

  • 新手初学Java流程控制

    目录 Java流程控制 用户交互Scanner next() nextLine() 选择结构 if单选择结构 if双选择结构 if多选择结构 嵌套if结构 Switch多选择结构 while循环 do while 循环 For循环 增强for循环 break和continue 总结 Java流程控制 用户交互Scanner java.util.Scanner是Java5的新特征,可以通过Scanner类来获取用户的输入 基本语法 Scanner sc = new Scanner(System.i

  • 新手初学Java集合框架

    目录 Java集合框架 集合 List接口 ArrayList Vector LinkedList: 泛型: Set接口 HashSet TreeSet Map接口 特点: 遍历: HashMap Hashtable TreeMap 总结 Java集合框架 集合 概念:对象的容器,定义了对多个对象进行操作的常用方法.可实现数组的功能. 集合和数组的区别: 数组长度固定,集合长度不固定 数组可以存储基本类型和引用类型,集合只能存储引用类型. 测试 /* 1.添加 2.删除 3.遍历 4.判断 */

  • 新手初学Java基础

    目录 1.Java的基本数据类型有哪些? 2.如何理解面向对象和面向过程? 3.如何理解多态 4.封装举例? 5.继承? 6.char可不可以存储一个中文汉字,为什么? 7.自动拆装箱?int和integer有什么区别? 8. == 和 equals 的区别? 9.String可以被继承吗? 10.String buffer和String Builder的区别? 11.final.finally.Finalize有什么区别? 12.Object中有哪些方法? 13.集合框架简单体系图 14.Ar

  • 新手初学Java面向对象

    目录 java面向对象 知识点 总结 java面向对象 面向对象[Java语言的核心机制,最重要的内容,Java语言的特色] * 面向过程和面向对象的区别 - 面向过程:主要关注点是:实现的具体过程,因果关系[集成显卡的开发思路] * 优点:对于业务逻辑比较简单的程序,可以达到快速开发,前期投入成本较低. * 缺点:采用面向过程的方式开发很难解决非常复杂的业务逻辑,另外面向过程的 方式导致软件元素之间的"耦合度"非常高,只要其中一环出问题,整个系统受到影响, 导致最终的软件"

  • 新手初学Java网络编程

    目录 运行线程 回调 同步方法 同步块 死锁 优先级 暂停 可以对IO阻塞 可以对同步对象阻塞 可以放弃 可以休眠 可以连接另一个线程 可以等待一个对象 可以结束 可以被更高优先级线程抢占 总结 运行线程 创建Thread的子类 public class ThreadChild extends Thread { @Override public void run() { while (true) { System.out.println("run"); } } } public cla

  • 新手初学Java的内部类

    目录 Java的内部类 成员内部类 静态内部类 局部内部类 总结 Java的内部类 概念: 内部类就是在一个类的内部定义一个类,比如,A类中定义一个B类,那么B类相对于A类来说就是称为内部类,而A类相对于B类来说就是外部类. 成员内部类 静态内部类 局部内部类 匿名内部类 特点: 内部类编译之后可以生成独立的字节码文件. 内部类可以直接访问外部类的私有成员,而不破坏封装. 内部类可为外部类提供必要的内部功能组件. 外部类要访问内部类的成员,必须要建立内部类的对象 成员内部类 在内的内部定义,与实

  • 新手初学Java常见排序算法

    目录 1.冒泡排序 2.选择排序 3.简单插入排序 4.希尔排序 5.归并排序 6.快速排序 总结 1.冒泡排序 排序原理:相邻两个元素比较,如果前者比后者大,则交换两个元素.每执行一次,都会确定一个最大值,其位置就固定了,下一次就不需要再参与排序了. 时间复杂度:O(n^2) 稳定性:稳定 具体实现: public class Bubble { /** * 对数组a中的元素进行排序 */ public static void sort(Comparable[] a){ //每冒泡一次,参与冒泡

随机推荐