Java 数组

来源:互联网 发布:重庆网络运营公司 编辑:程序博客网 时间:2024/05/21 11:10
数组相当于一堆数放到一起。

String[] players = {"player1","player2","player3"};String[] cards = {"黑桃Q", "黑桃K", "黑桃A"};

如上所示,在变量的命名上就体现了"一堆"的意义。 
数组的声明有两种方式,如下所示: 
int[] ary:声明了数组变量 ary, 数组变量是代词。int ary[];:为了与C语法兼容的写法,不建议写法。

定义数组方式如下代码:

public class ArrayTest {public static void main(String[] args) {// 声明和初始化一个数组int[] arr = new int[4]; // 第1种写法int arr1[] = new int[4]; // 第2种写法(不推荐)}}


数组对象初始化


public class ArrayDemo {public static void main(String[] args) {// 声明一个数组变量int[] arr;// 创建一个数组对象,有4个int元素arr = new int[4];// java数组必须给定大小,元素是自动初始化的,数组下标0~3System.out.println(arr[2]);System.out.println(arr[3]);// 直接使用元素创建数组,arr引用了一个新的数组arr = new int[] { 1, 2, 3 };System.out.println(arr);}}

注:
1、数组变量引用了具体数组对象, 就是代词。
2、数组元素是自动初始化的,自劢初始化为"零"值。
3、"零"值包括:0(整型)、0.0(浮点型)、 \u0000(char)、false(boolean)、null(引用类型)。
在今后的的学习中会经常出现如下异常,请大家先熟悉一下,如图所示:
public class TestArray {public static void main(String[] args) {// 声明一个数组变量int[] arr = new int[4];System.out.println(arr[0]); // 结果为0System.out.println(arr[5]); // 数组访问越界,会出异常}}//运行结果如下:0Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5at basic.array.TestArray.main(TestArray.java:9)

Java中的初始化分为两种方式:动态初始化和静态初始化,如下所示:

public class ArrayTest {public static void main(String[] args) {// 声明和初始化一个数组int[] arr = new int[4]; // 动态初始化int arr1[] = new int[4]; // 动态初始化int arr2[] = new int[] { 1, 2, 3 }; // 动态初始化int arr3[] = { 1, 2, 3 }; // 静态初始化}}

注:静态初始化只能用在声明数组变量时候同时初始化。



数组变量,数组对象,数组元素


请理解并熟悉这些名词:

public class Test {// 声明和初始化一个数组int[] arr = new int[] { 1, 2, 3 };// arr : 数组变量// { 1, 2, 3 } : 数组对象// 1, 2, 3 : 数组元素}

数组元素的访问

数组对象的大小是固定的,长度是n,下标范围是0~n-1。 
我们通常使用[下标] 访问数组元素,越界访问(小于0/大于等于n),都会发生运行异常。
Java中使用.length 属性可以获取数组对象长度 如下图所示:

重新强化两个概念:编译错误和运行时异常,如下图所示: 
编译错误

运行时异常


数组对象的复制


我们先理解数组赋值概念,如下所示:


/** * 数组的复制与动态扩展算法 */public class ArrayCopyDemo {public static void main(String[] args) {int[] arr = new int[] { 1, 2, 3, 4 };// 数组的赋值int[] arr2 = arr; // 一个数组对象,两个引用同时引用}}

继续案例,如下图所示:

注:这种现象叫数组赋值,可以发现如果这样赋值,数组对象没有隔离性,不小心就修改了。
所以我们使用数组对象的复制实现数组的隔离性,如下所示:

/** * 数组的复制与动态扩展算法 */public class ArrayCopyDemo_01 {public static void main(String[] args) {int[] arr = new int[] { 1, 2, 3, 4 };// 数组的复制:两个不同的数组对象int[] arr3 = new int[arr.length]; // 空数组for (int i = 0; i < arr.length; i++) {arr3[i] = arr[i]; // 将每个元素复制一遍}// arr3是arr的复制结果,不通的数组对象,arr和arr3是隔离的arr3[1] = 9999;System.out.println(arr[1]); // 2, 没有改变}}

注:新数组ary3是数组ary1的副本,ary3是新数组。
ary1和ary3分别指向不同对象,内存示意图如下所示:

那么如何输出数组中全部元素?我们使用"数组的迭代"方法,迭代(Iterate)的意思就是"重复"。
如下所示:
public class Test {public static void main(String[] args) {// 声明和初始化一个数组int[] arr = new int[] { 1, 2, 3, 4 };// 迭代输出每个元素for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}}

Java提供了更简单的输出数组的方法,如下所示:

import java.util.Arrays;public class Test2 {public static void main(String[] args) {// 声明和初始化一个数组int[] arr = new int[] { 1, 2, 3, 4 };System.out.println(Arrays.toString(arr));}}

注:使用Java提供的方法需要import。
下面我们介绍数组拷贝(复制)效率更高的2种方法:
System.arraycopy(src , srcPos, dest , destPos , length)
这个方法是Java API提供的,底层是用C++写的,所以速度非常快,比for()循环实现数组拷贝效率要高很多,所以推荐使用。 
Arrays.copyOf(src,length):是JDK1.6版本提供的方法,比起System.arraycopy()使用更简便,但需要注意的是你的开发环境JDK版本必须是1.6及以上。
copyOf() 方法的底层就是arraycopy()方法. 下面我们首先演示System.arraycopy()方法,如下所示:

/** * Java 提供的数组复制方法 */public class Test3 {public static void main(String[] args) {int[] src = { 1, 2, 3, 4 };int[] dest = new int[4]; // [0,0,0,0]System.arraycopy(src, 0, dest, 0, src.length);System.out.println(Arrays.toString(dest));}}

Arrays.copyOf(src, length)方法演示代码如下:

/** * Java 提供的数组复制方法 */public class Test4 {public static void main(String[] args) {int[] src = { 1, 2, 3, 4 };int[] dest = Arrays.copyOf(src, src.length);System.out.println(Arrays.toString(dest));}}


注:实现数组复制更加简洁和方便(推荐)。


数组的扩展问题


我们先明确一点,Java数组对象的大小是固定的,数组对象是不能扩展的,我们利用数组复制的方法可以变通的实现数组扩展。
创建数组副本的同时将数组长度增加就变通的实现了,数组的扩展。
1、System.arraycopy() 可以复制数组。
2、Arrays.copyOf() 可以简便的创建数组副本。
我们演示一个例子实现了数组扩展功能,如下所示,

import java.util.Arrays;/** * Java 提供的数组复制方法 */public class Test5 {public static void main(String[] args) {char[] cArr = { '北', '京' };char[] temp = Arrays.copyOf(cArr, 4);char[] cArr2 = temp; // { '北',[Fields]'京', 0, 0 } 后两位自动补零cArr2[2] = '人';cArr2[3] = '民';System.out.println(cArr2);}}

需要注意: 在数组输出时,会有一些不同,让我们看看会有哪些不同情况发生,如下所示:
/** * Java 提供的数组复制方法 */public class Test6 {public static void main(String[] args) {char[] cArr = { '北', '京' };System.out.println(cArr);System.out.println(Arrays.toString(cArr));int[] iArr = { 1, 2 };System.out.println(iArr);System.out.println(Arrays.toString(iArr));String[] sArr = { "人", "民" };System.out.println(sArr);System.out.println(Arrays.toString(sArr));}}//输出结果如下所示:北京[北, 京][I@f99ff5[1, 2][Ljava.lang.String;@1d9fd51[人, 民]


完成如下案例: 统计一个字符在字符串中所有的位置。
比如"统计一个字符在字符串中所有的位置"这个字符串中的"字"出现2次,分别出现在下标4和7的位置。
要求,将下标位置放入到一个int数组中,每找到一个就放入并对数组扩容。
import java.util.Arrays;public class CharCountDemo {public static void main(String[] args) {String str = "统计一个字符在字符串中的位置";int[] arr = countAll(str, '字');System.out.println(Arrays.toString(arr));}/** * 统计一个字符在字符串中所有位置的方法 *  * @param str *            被统计的字符串 str = "统计一个字符在字符串中的位置" * @param ch *            统计的字符 ch ='字' * @return 数组,包含所有的位置 */private static int[] countAll(String str, char ch) {int[] arry = {};for (int i = 0; i < str.length(); i++) { // i 是每个字符的位置char c = str.charAt(i); // c 就是字符串中每个字符if (c == ch) { // 找到被查找的字符// i -> arry; 将数组扩展,将i插入到数组中arry = Arrays.copyOf(arry, arry.length + 1);arry[arry.length - 1] = i;}}return arry;}}


注:本例中的重要知识点如下所示:
1、复习方法的定义和调用概念。
2、Int[] ary = {} 表示初始化了一个空数组。
3、数组长度使用arr.length表示,字符串长度使用str.length()表示。
4、ary[ary.length-1]表示数组的最后一个元素。



原创粉丝点击