Java中的数组

学习目标

"数组"是一种很基础但又极为重要的数据结构。几乎所有的编程语言对数组操作提供了支持。 Java中的数组既拥有数组普遍的特性: 比如按下标访问,元素连续存放等,也有它自己的特色,比如使用一维数组实现多维数组,数组可以是不整齐的等等。

本讲围绕“数组”这一核心内容而展开,重点是**引用类型数组的内存布局模型**。
本讲还包容了不少与数据结构相关的练习,完成它们,不仅可以训练自己的Java编程技能,同时还对数据结构的学习有一定的促进作用。事实上,在后面的课程中还会遇到不少与数据结构相关的内容,甚至有些数据结构的教材,就是以Java作为编程实现语言的。

数组的特点

  • 一种简单的数据结构
  • 元素具有相同的数据类型
  • 一旦创建之后,尺寸保持不变
  • 元素在内存中连续分布在这里插入图片描述

数组的下标

Subscript(下标)
  • 亦称index(索引),代表元素在整个数组中的位置
  • 必须是整数或整数表达式在这里插入图片描述

数组名

在这里插入图片描述

数组的创建

  • 数组是对象,需要占用内存空间
  • 以下代码声明一个数组变量并为之分配内存
int c[]= new int[12];
//相当于
int c[];//声明数组变量,declare array
c = new int[12];//分配内存空间,allocate array
  • 上面是创建“原始数据类型”的数组,我们还可以创建“对象数组”
String b[] = new String[100];

数组初始化

  • 数组创建之后,可以使用循环或赋值语句对其进行初始化
  • Java提供了一种使用初始化列表的方式,使用它可以省略使用new关键字创建数组对象的工作int n[]={1,2,3,4,5};
    在这里插入图片描述
import javax.swing.*;
public class welcome1
{
	public static void main(String[] args)
	{
		      String output = "";

		      // Initializer list specifies number of elements and
		      // value for each element.
		      int n[] = { 32, 27, 64, 18, 95, 14, 90, 70, 60, 37 };
		      output += "Subscript\tValue\n";		   
		      for ( int i = 0; i < n.length; i++ ) 
		         output += i + "\t" + n[ i ] + "\n";
		     //这里先把头部的两个标志写入output,然后再依次把行号和真正数据写入output,为下面的数据识别做准备
		      JTextArea outputArea = new JTextArea( 11, 10 );
		      outputArea.setText( output );
		      JOptionPane.showMessageDialog( null, outputArea,
		         "Initializing an Array with a Declaration",
		         JOptionPane.INFORMATION_MESSAGE );
		      System.exit( 0 );
	}
}
两种不同类型的数组初始化
  • 如数组元素是基本类型你听,初始化为0;
  • 数组元素是引用类型,使用之前必须先创建对象
myclass [] arr = new myclass[12];
arr[7].value = 32;
//运行时引发java.lang.NullPointerException,因为尝试访问一个还不存在的对象,是一种常见的错误
引用类型的数组内存布局
  • 对于数组元素是引用类型的数组,在访问数组中的对象之前,需要创建相应的对象并让数组元素引用它!
  • 牢记引用类型数组的内存布局模型!
    在这里插入图片描述

在这里插入图片描述数组元素必须具有相同类型?

public static void main()
{
Object[] arr ={"a","b",13};
System.out.println(arr);
}

上述代码可以通过编译,但是输出的数值有些奇怪

访问数组元素

  • 数组元素可以通过下标直接定位,如果需要遍历,则通过循环语句实现
int [] a = new int [100];
for(int i=0;i<a,length;i++)
{
   System.out.println(a[i]);
}
  • 当用循环语句遍历数组元素时
    1. 下标不能小于0;
    2. 下标必须小于最大的数组元素数目
    3. 否则:
      – 对于非法的数组下标,Java会抛出异常ArrayIndexOutOfBoundsException
      – 要处理异常,需要用try…catch语句
  • foreach访问数组
    JDK5.0引入for each循环
    1. 迭代变量必须在()中定义
    2. 集合变量可以是数组或任何一个实现了Iterable接口的集合类
int[] num=new int[100];
for(int element:nums)
System.out.println(element);

数组作为方法参数

  • 两种方法参数的传递方式
    1. Pass-by-value(按值传递):用于原始数据类型
    2. Pass-by-reference(按引用传递):对象都按引用传递
  • 数组参数按引用传递
    在这里插入图片描述

多维数组

  • 定义【多维数组可以是不整齐的
    在这里插入图片描述
    在这里插入图片描述
  • 其实没有多维数组,多维数组可以看成一维数组,只不过这个数组的元素又是一个数组罢了,由此不断迭代,最终得到一个多维数组
               int[][] a;
				a = new int[3][];
				for (int i = 0; i < a.length ; i++ )
				{
					System.out.println(a[i]);//null
				}	
				a[0] = new int[2];
				a[0][0] = 1;
				a[0][1] = 2;		
				for (int i = 0 ; i < a[0].length ; i ++ )
				{
					System.out.println(a[0][i]);//1 2!
				}
  • arrayName[index1][index2]最高维分配引用空间,也就是为最高维限制其能保存数据的最长的长度,index1必须固定,然后再为其每个数组元素单独分配空间 s0=new String(“Good”) 等操作。

数组拷贝

  • 使用arraycopy方法
        int[] from = {0,1,2,3,4,5,6,7,8,9,};
		int[] to = new int [10];
		System.arraycopy(from,5,to,4,2);
		for(int element:to )
		System.out.println(element);

第一个参数是原数组
第二个是原数组开始复制的起点下标
第三个参数是目标数组
第四个参数是目标数组待复制的起始位置
第五个参数是要复制多少个在目标数组里

Arrays类中的静态方法

  • JDK中有一个Arrays类,封装了一些与数组相关的静态方法,这些静态方法可以完成诸如查找、复制、比较等各种数组常用功能
  • Arrays类某些方法【java.Arrays类能方便地操作数组,它提供的所有方法都是静态的
    在这里插入图片描述

作业部分

在这里插入图片描述

public class WhatDoesThisDo {
	static int result;
	static String output;

	public static void main(String[] args) {
		int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
		result = whatIsThis(a, a.length);
		output = "Result is: " + result;
		System.out.println(output);
	}

	public static int whatIsThis(int b[], int size) {
		if (size == 1)
			return b[0];
		else
			return b[size - 1] + whatIsThis(b, size - 1);
	}
}
//数组求和运算
public class WhatDoesThisDo2 {
	public static void main(String[] args) {
		int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
		StringBuilder sbBuilder=new StringBuilder();
		someFunction(a, 0, sbBuilder);
		System.out.println(sbBuilder);
	}
	public static void someFunction(int b[], int x, StringBuilder out) {
		if (x < b.length) {
			someFunction(b, x + 1, out);
			out.append(b[x] + "  ");
		}
	}
}
//倒序输出

在这里插入图片描述
在这里插入图片描述

// This program sorts an array's values into
// ascending order

public class BubbleSort  {
	public static void main(String[] args) {
		  int a[] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };

	      String output = "Data items in original order\n";

	      for ( int i = 0; i < a.length; i++ ) 
	         output += "   " + a[ i ];
	 	
	      bubbleSort( a );

	      output += "\n\nData items in ascending order\n";

	      for ( int i = 0; i < a.length; i++ ) 
	         output += "   " + a[ i ];

	      System.out.println(output);
	}
  
   // sort the elements of an array with bubble sort
   private static void bubbleSort( int b[] )
   {   
      for ( int pass = 1; pass < b.length; pass++ ) // passes
         for ( int i = 0; i < b.length - 1; i++ ) // one pass   
            if ( b[ i ] > b[ i + 1 ] )        // one comparison
               swap( b, i, i + 1 );           // one swap
   }

   // swap two elements of an array
   private static void swap( int c[], int first, int second )
   {
      int hold;  // temporary holding area for swap
      hold = c[ first ];         
      c[ first ] = c[ second ];  
      c[ second ] = hold;
   }
}

把能抽象的,能复用的都单独写出来
在这里插入图片描述

如何计算Java代码执行时间

总体思想:
在程序运行前记录一次待测试部分程序前当下时间,在待测试部分程序结束后记录一次当下时间,二者做差即可。
第一种以毫秒为计算单位

long startTime = System.currentTimeMillis();    //获取开始时间
doSomething();    //测试的代码段
long endTime = System.currentTimeMillis();    //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) + "ms");    //输出程序运行时间

第二种是以纳秒为计算单位

long startTime=System.nanoTime();   //获取开始时间  
doSomeThing(); //测试的代码段  
long endTime=System.nanoTime(); //获取结束时间  
System.out.println("程序运行时间: "+(endTime-startTime)+"ns"); 
public static void main(String[] args) {
		String str = "hello";
		long starttime = System.currentTimeMillis();
		for(int i=0;i<1000;i++)
		{
			str=str+i;
		}
		long endtime = System.currentTimeMillis();
		System.out.println(endtime-starttime);
		//StringBuilder str1 = "h";
		//注意:StringBuilder不像是String一样直接赋值的
		StringBuilder str1 = new StringBuilder("hello");
		starttime = System.currentTimeMillis();
		for(int i=0;i<1000;i++)
		{
			str1.append(i);
		}
		endtime = System.currentTimeMillis();
		System.out.println(starttime-endtime);
	}
//输出结果
//2
//0

在这里插入图片描述


import java.io.*;
public class QiPan
{
	private String[][] board;
	
	private static int BOARD_SIZE = 15;
	public void initBoard()
	{
		board = new String[BOARD_SIZE][BOARD_SIZE];
		
		for (int i = 0 ; i < BOARD_SIZE ; i++)
		{
			for ( int j = 0 ; j < BOARD_SIZE ; j++)
			{
				board[i][j] = "+";
			}
		}
	}
	public void printBoard()
	{
		for (int i = 0 ; i < BOARD_SIZE ; i++)
		{
			for ( int j = 0 ; j < BOARD_SIZE ; j++)
			{
					System.out.print(board[i][j]);
			}
			System.out.print("\n");
		}
	}
    public static void main(String[] args)throws Exception
    {
        QiPan gb = new QiPan();
		gb.initBoard();
		gb.printBoard();	
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String inputStr = null;
                System.out.println("please input the location you want to put the chess:");
		while ((inputStr = br.readLine()) != null)
		{	//主要是这里把要输入的字符变成数字,即下标索引
			String[] posStrArr = inputStr.split(",");
			int xPos = Integer.parseInt(posStrArr[0]);
			int yPos = Integer.parseInt(posStrArr[1]);
			gb.board[xPos - 1][yPos - 1] = "0";				
			gb.printBoard();
		}
    }
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值