[Java][华为云Java编程创造营][学习笔记][技能栈基本要求之数据结构][数组]
【摘要】 1,数组介绍数组是一种数据结构,用来存储同一类型值的集合。通过一个整形下标可以访问数组中的每个值。例如:如果a是一个整型数组,a[i]就是数组中下标为i的整数。在声明数组变量时,需要指出数组类型和数组变量的名字。例如:声明一个整型数组a:int[] a,不过这条语句只声明了变量a,并没有将a初始化成真正的数组。使用new运算符创建数组。int[] a = new int[100];,这条语...
1,数组介绍
-
数组是一种数据结构,用来存储同一类型值的集合。通过一个整形下标可以访问数组中的每个值。
- 例如:如果a是一个整型数组,a[i]就是数组中下标为i的整数。
-
在声明数组变量时,需要指出数组类型和数组变量的名字。
- 例如:声明一个整型数组a:
int[] a
,不过这条语句只声明了变量a,并没有将a初始化成真正的数组。使用new运算符创建数组。int[] a = new int[100];
,这条语句创建了可以存储100整数的数组。数组长度不要求是常量:new int[n]
会创建一个长度为n的数组。
- 例如:声明一个整型数组a:
-
创建数组有两种形式
int[] a
和int a[]
-
创建一个数组例子
public class Test
{
public static void main(String[] args)
{
int[] a = new int[5];
for (int i = 0; i < 5; i++)
{
a[i] = i;//fills the array with numbers 0 to 5
}
for (int n : a)
{
System.out.print(n + " ");//0 1 2 3 4
}
}
}
- 创建一个数字数组时,所有元素都初始化为0。boolean数组的元素会初始化为false。对象数组的元素则初始化为一个特殊值null,这表示这些元素还没存放任何对象。以下以一个例子说明:
public class Test
{
public static void main(String[] args)
{
int[] a = new int[5];
for (int n : a)
{
System.out.print(n + ",");//0,0,0,0,0,
}
System.out.println();
System.out.println("----------------");
boolean[] b = new boolean[5];
for (boolean n : b)
{
System.out.print(n + ",");//false,false,false,false,false,
}
System.out.println();
System.out.println("----------------");
String[] c = new String[5];
for (String n : c)
{
System.out.print(n + ",");//null,null,null,null,null,
}
}
}
- 想要获得数组中的元素个数,可以使用
array.length
public class Test
{
public static void main(String[] args)
{
int[] a = new int[5];
for (int i = 0; i < a.length; i++)
{
System.out.print(a[i] + ",");//0,0,0,0,0,
}
}
}
- 一旦创建了数组,就不能再改变它的大小(可以改变没一个数组元素)。如果经常需要在运行过程中拓展数组的大小,就应该使用另一种数据结构-数组列表(arry list)。
2,for each 循环
- Java有一种功能更强的循环结构,可以用来依次处理数组中的每个元素(其他类型的元素集合亦可)而不必为指定下标值而分心。
- 这种增强的for循环的语句格式为:
for (variable:collection) statement
- 定义一个变量用于暂存集合中的每一个元素,并执行相应的语句(也可以是语句块)。
public class Test
{
public static void main(String[] args)
{
int[] a = new int[5];
a[0] = 5;
a[1] = 4;
a[2] = 3;
a[3] = 2;
a[4] = 1;
for (int element : a)
{
System.out.print(element + ",");//5,4,3,2,1,
}
}
}
- for each循环语句显得更加简洁,更不易出错(不必为下标的起始值和终止值而操心)。
- 利用
Arrays
类中的toString()
方法可以更简单地打印数组中的所有值。调用Arrays.toString(a)
,返回一个包含数组元素的字符串,这些元素放置在括号内,并用逗号隔开。
import java.util.Arrays;
public class Test
{
public static void main(String[] args)
{
int[] a = new int[3];
a[0] = 3;
a[1] = 2;
a[2] = 1;
System.out.println(Arrays.toString(a));//[3, 2, 1]
}
}
3,数组初始化以及匿名数组
- 在Java中,提供了一种创建数组对象并同时赋予初始值的简化书写形式。例子:
int[] smallPrimes = {2,3,4,5};
,注意,在使用这种语句时,不需要调用new。 - 还可以初始化一个匿名的数组:
new int[] {1,2,3};
,这种表示法将创建一个新数组并利用括号中提供的值进行初始化,数组的大小就是初始值的个数。 - 使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组。例如:
smallPrimes = new int[]{1,2,3}
。 - 以下是语句的简写形式
int[] anonymous = {1,2,3};
smallPrimes = anonymous;
- 在Java中,允许数组长度为0。在编写一个结果为数组的方法时,如果碰巧结果为空,则这种语法形式就显得非常有用。此时可以创建一个长度为0的数组:
new elementType[0]
。数组长度为0与null不同。
4,数组拷贝
- 在Java中,允许将一个数组变量拷贝给另一个数组变量。这时,两个变量将引用同一个数组:
int[] smallPrimes = {1,2,3};
int[] luckyNumbers = smallPrimes;
luckyNumbers[2] = 12;// now smallPrimes[2] is also 12
- 如果希望将一个数组的所有值拷贝到一个新的数组中去,就要使用
Arrays
类的copyOf
方法
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers,luckyNumbers.length);
- 第2个参数是新数组的长度。这个方法通常用来增加数组的大小:
luckyNumbers = Arrays.copyOf(luckyNumbers,2*luckyNumbers.length);
- 如果数组元素是数值型,那么多雨的元素将被赋值为0;如果数组元素是布尔型,则将赋值为false。相反,如果长度小于原始数组的长度,则只拷贝最前面的数据元素。
5,命令行参数
- 每一个Java应用程序都有一个带
String args[]
参数的main
方法。这个参数表名main
方法将接收一个字符串数组,也就是命令行参数。
public class Test
{
public static void main(String[] args)
{
if (args.length == 0 || args[0].equals("-h"))
{
System.out.print("Hello,");
}
else if (args[0].equals("-g"))
{
System.out.print("Goodbye,");
}
//print the other command-line arguments
for (int i = 1; i < args.length; i++)
{
System.out.print(" " + args[i]);
}
System.out.println("!");
}
}
-
如果加入启动参数运行这个程序
-
程序将显示下列信息:
Goodbye, world!
6,数组排序
- 想要对数值型数组进行排序,可以使用
Arrays
类中的sort
方法 - 这个方法使用了优化的快速排序算法。快速排序算法对于大多数数据集合来说都是效率比较高的。
import java.util.*;
/*
* This program demonstrates array manipulation
* @Version 1.20 2004-02-10
* @author Cay Horstmann
* */
public class LotteryDrawing
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("How many numbers do you need to draw? ");
int k = in.nextInt();
System.out.println("What is the highest number you can draw? ");
int n = in.nextInt();
//fill an array with numbers 1 2 3 ... n
int[] numbers = new int[n];
for (int i = 0; i < numbers.length; i++)
{
numbers[i] = i + 1;
}
//draw k numbers and put them into a second array
int[] result = new int[k];
for (int i = 0; i < result.length; i++)
{
//make a random index between 0 and n-1
int r = (int) (Math.random() * n);
//pick the element at the random location
result[i] = numbers[r];
//move the last element into the random location
numbers[r] = numbers[n - 1];
n--;
}
//print the sorted array
Arrays.sort(result);
System.out.println("Bet the following combination. It'll make you rich!");
for (int r : result)
{
System.out.println(r);
}
}
}
- java.util.Arrays
static String toString(type[] a)
- 返回包含a中数据元素的字符串,这些数据元素被放在括号内,并用逗号分隔。
- 参数:a 类型为int、long、short、char、byte、boolean、float或double的数组。
static type copyOf(type[] a,int length)
static type copyOfRange(type[] a,int start,int end)
- 返回与a类型相同的一个数组,其长度为length或者end-start,数组元素为a的值。
- 参数:a 类型为int、long、short、char、byte、boolean、float或double的数组。
- 参数:start 起始下标(包含这个值)。
- 参数:end 终止下标(不包含这个值)。这个值可能大于a.length。在这种情况下,结果为0或false。
- 参数:length 拷贝的数据元素长度。如果length值大于a.length,结果为0或者false;否则数组中只有前面length个数据元素的拷贝值。
static void sort(type[] a)
- 采用优化的快速排序算法对数组进行排序。
- 参数:a 类型为int、long、short、char、byte、boolean、float或double的数组。
static int binarySearch(type[] a,type v)
static int binarySearch(type[] a,int start,int end,type v)
- 采用二分搜索算法查找值v。如果查找成功,则返回相应的下标值;否则,返回一个负数值r。-r-l是为了保持a有序v应插入的位置。
- 参数:a 类型为int、long、short、char、byte、boolean、float或double的数组。
- 参数:start 起始下标(包含这个值)。
- 参数:end 终止下标(不包含这个值)。
- 参数:v 同a的数据元素类型相同的值。
static void fill(type[] a,type v)
- 将数组的所有数据元素值设置为v。
- 参数:a 类型为int、long、short、char、byte、boolean、float或double的数组。
- 参数:v 与a数据元素类型相同的一个值。
static boolean equals(type[] a,type[] b)
- 如果两个数组大小相同,并且下标相同的元素都对应相等,返回true。
- 参数:a、b 类型为int、long、short、char、byte、boolean、float或double的数组。
7,多维数组
- 多维数组将使用多个下标访问数组元素,它适用于表示表格或更加复杂的排列形式。
- 假设需要建立一个数值表,用来显示在不同利率下投资$10000会增长多少,利息每年呈现,而且又被用于投资。
10% | 11% | 12% | 13% | 14% | 15% |
---|---|---|---|---|---|
10000.00 | 10000.00 | 10000.00 | 10000.00 | 10000.00 | 10000.00 |
11000.00 | 11100.00 | 11200.00 | 11300.00 | 11400.00 | 11500.00 |
12100.00 | 12321.00 | 12544.00 | 12769.00 | 12996.00 | 13225.00 |
13310.00 | 13676.31 | 14049.28 | 14428.97 | 14815.44 | 15208.75 |
14641.00 | 15180.70 | 15735.19 | 16304.74 | 16889.60 | 17490.06 |
16105.10 | 16850.58 | 17623.42 | 18424.35 | 19254.15 | 20113.57 |
17715.61 | 18704.15 | 19738.23 | 20819.52 | 21949.73 | 23130.61 |
19487.17 | 20761.60 | 22106.81 | 23526.05 | 25022.69 | 26600.20 |
21435.89 | 23045.38 | 24759.63 | 26584.44 | 28525.86 | 30590.23 |
23579.48 | 25580.57 | 27730.79 | 30040.42 | 32519.49 | 35178.76 |
- 可以使用一个二维数组(也称为矩阵)存储这些信息。这个数组被命名为balances。
- 在Java中,声明一个二维数组相当简单。
double[][] balances;
- 与一维数组一样,在调用new对多维数组进行初始化之前不能使用它。可以这样初始化
double[][] balances;
balances = new double[NYEARS][NRATES];
- 如果知道数组元素就可以不调用new,而直接使用简化的书写形式对多维数组进行初始化。例如:
int[][] magicSquare =
{
{1,2,3,4},
{2,3,4,5},
{3,4,5,6}
};
- 一旦数组完成初始化,可以利用两个方括号访问每个元素,例如:
magicSquare[i][j]
。 - for each循环语句不能自动处理二维数组的每个元素。它是按照行,也就是一维数组处理的。要访问二维数组a的所有元素,需要使用两个嵌套的循环。
for (double[] row : a)
for (double value : row)
do something with value
- 想快速打印一个二维数组的数据元素列表,可以调用:
System.out.println(Arrays.deepToString(a));
- 下面以上面的利率表为例子说明二维数组,用到了一个存储利率的一维数组interest与一个存储余额的二维数组balances。一维用于表示年,另一维用于表示利率。
/*
* This program shows how to store tabular data in a 2D array.
* @version 1.40 2004-02-10
* @author Cay Horstmann
* */
public class CompoundInterest
{
public static void main(String[] args)
{
final double STARTRATE = 10;
final int NRATES = 6;
final int NYEARS = 10;
//set interest rates to 10 ... 15%
double[] interestRate = new double[NRATES];
for (int j = 0; j < interestRate.length; j++)
{
interestRate[j] = (STARTRATE + j) / 100.0;
}
double[][] balances = new double[NYEARS][NRATES];
//set initial balances to 10000
for (int j = 0; j < balances[0].length; j++)
{
balances[0][j] = 10000;
}
//compute interest for future years
for (int i = 1; i < balances.length; i++)
{
for (int j = 0; j < balances[j].length; j++)
{
//get last year's balances from previous row
double oldBalance = balances[i - 1][j];
//compute interest
double interest = oldBalance * interestRate[j];
//compute this year's balances
balances[i][j] = oldBalance + interest;
}
}
//print one row of interest rates
for (int j = 0; j < interestRate.length; j++)
{
System.out.printf("%9.0f%%", 100 * interestRate[j]);
}
System.out.println();
//print balance table
for (double[] row : balances)
{
//print table row
for (double b : row)
{
System.out.printf("%10.2f", b);
}
System.out.println();
}
}
}
8,不规则数组
-
Java的独特在于:Java实际上没有多维数组,只有一维数组。多维数组被解释为"数组的数组"。
-
前面的利率表中,balances数组实际上是一个包含10个元素的数组,而每个元素又是一个由6个浮点数组成的数组。
-
表达式balances[i]引用第i个子数组,也就是二维表的第i行。它本身也是一个数组,balances[i][j]引用这个数组的第j项。
-
创建一个数组,第i行第j列将存放"从i个数值中抽取j个数值",由于j不可能大于i,所以矩阵是三角形的。第i行有i+1个元素(允许抽取0个元素)。
/*
* This program demonstrates a triangular array.
* @version 1.20 2004-02-10
* @author Cay Horstmann
* */
public class LotteryArray
{
public static void main(String[] args)
{
final int NMAX = 10;
//allocate triangular array
int[][] odds = new int[NMAX + 1][];
for (int n = 0; n <= NMAX; n++)
{
odds[n] = new int[n + 1];
}
//fill triangular array
for (int n = 0; n < odds.length; n++)
{
for (int k = 0; k < odds[n].length; k++)
{
/*
* compute binomial coefficient n*(n-1)*(n-2)*...*(n-k+1)/(1*2*3*...*k)
* */
int lotterOdds = 1;
for (int i = 1; i <= k; i++)
{
lotterOdds = lotterOdds * (n - i + 1) / i;
}
odds[n][k] = lotterOdds;
}
//print triangular array
for (int[] row : odds)
{
for (int odd : row)
{
System.out.printf("%4d", odd);
}
System.out.println();
}
}
}
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)