Java修炼入门 P2

Java编程语言是个简单、面向对象、分布式、解释性、健壮、安全、与系统无关、可移植、高性能、多线程和动态的语言。

在Java中,对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如MyFirstJavaClass。所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写,例如myFirstJavaMethod。

基本程序设计结构

流程控制

Java的控制流程结构与C和C++的控制流程结构一样,只有很少的例外情况:

1.没有goto语句,但break语句可以带标签,可以利用它实现从内层循环跳出的目的。

2.有一种变形的for循环(for each循环)。

块作用域

1.块(block,即复合语句)是指由若干条Java语句组成的语句,并由一对大括号括起来。

2.块确定了变量的作用域。

3.一个块可以嵌套在另一个块中。

4.不能在嵌套的两个块中声明同名的变量。(在C++中可以在嵌套的块中重定义一个变量。在内层定义的变量会覆盖在外层定义的变量。这样可能会导致程序设计错误,因此在Java中不允许这样做。)

1
2
3
4
5
6
7
8
9
10
11
12
package com.noob.base;

public class BlockStudy {
public static void main(String[] args) {
int n;
{
int k;
/*k is only defined up to here*/
int n; /*ERROR: n can't redefine n in inner block*/
}
}
}

条件语句

1.if…else…

2.if…else if…else…

1
2
3
4
5
6
7
8
9
10
11
if(condition) statement

if(condition)
{
statement1
statement2
}

if(condition) statement1 else statement2

if(condition) statement1 else if(condition) statement2 /*code*/ else statement

1.使用块(复合语句)可以在Java程序结构中原本只能放置一条(简单)语句的地方放置多条语句。

2.if/else语句中else部分是可选的。else子句与最邻近的if构成一组。

1
2
3
if(x<=0) if(x==0) sign=0;else sign=-1;

if(x<=0) {if(x==0) sign=0;else sign=-1;}
1
if(x==0) sign=2; else if(x==1) sign=0;else if(x==3) sign=-1;else sign=4;

循环

1.while

2.do…while(循环体至少执行一次)

1
2
3
while(condition) statement

do statement while(condition);

确定循环

1.for(for循环语句是支持迭代的一种通用结构,由一个利用计数器或类似的变量控制迭代次数,每次迭代后这个变量将会更新。)

2.for语句的3个部分应该对同一个计数器变量进行初始化、检测和更新(便于理解)。

3.如果在for语句内部定义一个变量,这个变量就不能在循环体之外使用。因此,如果希望在for循环体之外使用循环计数器的最终值,该变量需要在循环语句的前面且在外部声明。

4.可以在各自独立的不同for循环中定义同名的变量(循环嵌套不可以)。

5.泛型for循环(for each循环) Java5

1
2
3
for(int i=1;i<=10;i++) {
System.out.println(i);
}
1
2
3
4
5
6
7
8
/*在循环中检测两个浮点数是否相等需要格外小心*/
for(double i=0;i!=10;i+=0.1) {
System.out.println(i);
if(i>=10) {
break;
}
}
/*死循环,由于舍入的误差,最终可能永远达不到精确的最终值。因为0.1无法精确地用二进制表示,所以,x将从跳到10.09999999999998。*/
1
2
3
4
5
for(int i=1;i<=10;i++) /*在for语句的此处声明一个变量后,该变量的作用域扩展到这个for循环体的末尾*/
{

}
//i no longer defined here
1
2
3
4
5
6
int i;
for(i=1;i<=10;i++)
{

}
//i is still defined here
1
2
3
4
for(int i=1;i<=10;i++) {		
}
for(int i=11;i<=20;i++) {
}

多重选择

1.Java中switch语句与C/C++完全一样:switch语句将从与选项值相匹配的case标签处开始执行,直到遇到break语句,或者执行到switch语句的结束处为止。如果没有相匹配的case标签,而有default子句,就执行这个子句。

2.如果在case分支语句的末尾没有break语句,那么就会接着执行下一个case分支语句,这种情况常常会引发错误。(不推荐使用switch语句)

3.编译代码时可以考虑加上-Xlint:fallthrough选项,如果某个分支最后缺少一个break语句,编译器会给出警告消息。

4.如果想使用这种"直通式"(fallthrough)行为,可以为其外围方法加一个标注@SuppressWarnings("fallthrough"),这样就不会对该方法生成警告。

5.case标签:

  • 类型为char、byte、short或int的常量表达式。
  • 枚举常量。
  • 字符串字面量(Java7)。
1
javac -Xlint:fallthrough Test.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.noob.base;

import java.util.Scanner;

public class SwitchStudy {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Select an option(1,2,3,4)");
int choice = in.nextInt();
switch(choice)
{
case 1:
System.out.println("Option1");
break;
case 2:
System.out.println("Option2");
break;
case 3:
System.out.println("Option3");
break;
case 4:
System.out.println("Option4");
break;
default:
System.out.println("No Option");
break;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.noob.base;

import java.util.Scanner;
/*当在switch语句中使用枚举常量时,不必在每个标签中指明枚举名,可以由switch的表达式值推导而出*/
public class SwitchStudy {
public static void main(String[] args) {
enum Size{SMALL,MEDIUM,LARGE};
Scanner in = new Scanner(System.in);
Size sz=Size.MEDIUM;
switch(sz)
{
case SMALL:
System.out.println("SMALL SIZE");
break;
case MEDIUM:
System.out.println("MEDIUM SIZE");
break;
case LARGE:
System.out.println("LARGE SIZE");
break;
}
}
}

中断流程控制

1.尽管Java的设计者将goto作为保留字,但实际上并没有打算在语言中使用它。通常,使用goto语句被认为是一种拙劣的程序设计风格,但偶尔使用goto跳出循环是有帮助的。在Java语言中可以使用带标签的break。

2,break语句与用于退出switch语句的break语句一样,可以用于退出循环语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.noob.base;

import java.util.Scanner;

public class InterruptStudy {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("How much money do you need to retire?");
double goal = in.nextDouble();

System.out.println("How much money will you contribute every year");
double payment = in.nextDouble();

System.out.println("Interest rate in %:");
double interestRate = in.nextDouble();

double balance = 0;
int years = 0;
while(years<=100) { //while(years<=100 && balance < goal) {
balance+=payment;
double interest = balance*interestRate/100;
balance +=interest;
if(balance>=goal) break;
/*if(balance < goal) 不使用break需要检测两次balance < goal*/
years++;
}
System.out.println("You need "+years+" years to save a targeted amount of retirement money.");
}
}

1.与C++不同,Java提供了一种带标签的break语句,用于跳出多重嵌套的循环语句。有时候可能更加希望完全跳出所有嵌套循环之外,不需要添加为各层循环检测添加一些额外的条件,更加方便。

2.标签必须放在希望跳出的最外层循环之前,并且必须紧跟一个冒号。(循环必需紧跟着标号)

3.执行带标签的break会跳转到带标签的语句块末尾。

3.可以将标签应用到任何语句中,甚至可以将其应用到if语句或者块语句中。

4.只能跳出语句块,而不能跳入语句块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
如果输入有误,通过执行带标签的break跳转到带标签的语句块末尾。与任何使用break语句的代码一样,都需要检测循环是正常结束,还是由break跳出。
*/
package com.noob.base;

import java.util.Scanner;

public class BreakLabelStudy {
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
int t;
int n=0;
read_data:
while(n<=10) {
for(int i=1;i<=5;i++) {
System.out.print("Please enter a number>=0:");
t = in.nextInt();
if(t<=0) {
break read_data;
}
}
n++;
}
if(n>10){
//carry out normal processing
}
else{
//deal with bad situation
System.out.print("You input a bad number.");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.noob.base;

import java.util.Scanner;

public class BreakLabelStudy {
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
int t;
int n=0;
read_data:
{
System.out.print("Please enter a number>=0:");
t = in.nextInt();
if(t<=0) {
break read_data;
}
System.out.println("You must input a good num.");
n=1;
}
// jump here when the break statement executes
if(n==0) {
System.out.print("You input a bad number.");
}
}
}

1.continue语句与break语句一样,它将中断正常的控制流程。continue语句将控制转移到最内层循环的首部。

2.如果将continue语句用于for循环中,就可以跳到for循环的"更新"部分。

3.使用带标签的continue语句,将跳到与标签匹配的循环的首部。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.noob.base;

import java.util.Scanner;

public class BreakLabelStudy {
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
int sum=in.nextInt();
int goal=in.nextInt();
while (sum<goal) {
System.out.print("Enter a number:");
int n=in.nextInt();
if(n<0) continue;
sum+=n; //not executed i
System.out.println(sum);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.noob.base;

import java.util.Scanner;

public class BreakLabelStudy {
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
int sum=0;
for(int count=1;count<100;count++) {
System.out.println("Enter a number:");
int n=in.nextInt();
if(n<0) continue; /*如果n<0,则continue语句跳到count++语句*/
sum+=n;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.noob.base;

import java.io.IOException;
import java.util.Scanner;

public class BreakLabelStudy {
public static void main(String[] args) throws IOException {
outer:
for(int i=1;i<=10;i++) {
for(int t=1;t<=10;t++) {
if(i==5&&t==5) {
continue outer;
}
System.out.println("i: "+i+" t: "+t);
}
}
}
}

大数

1.java.math包中两个可以处理包含任意长度数字序列的数值的类:BigInteger和BigDecimal。BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。

2.使用静态的valueOf方法可以将普通的数值转换为大数,对于更大的数可以使用一个带字符串参数的构造器。

3..使用大数值类中的add和multiply方法代替算术运算符(如+ *)。(与C++不同,Java没有提供运算符重载功能。程序员无法重定义+和*运算符来提供BigInteger类的add和multiply运算。Java语言的设计者确实为字符串的连接重载了+运算符,但没有重载其他的运算符,也没有给Java程序员在自己的类中重载运算符的机会。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.noob.base;
import java.math.*;
public class BigNumber {
public static void main(String[] args) {
BigInteger a = BigInteger.valueOf(100);
BigInteger reallyBig = new BigInteger("1000000000000000000000");
BigInteger c = a.add(reallyBig);
BigInteger d = a.multiply(reallyBig);
BigInteger q = c.multiply(a.add(BigInteger.valueOf(12)));
System.out.println(a);
System.out.println(reallyBig);
System.out.println(c);
System.out.println(d);
/*3常量BigInteger.ONE BigInteger.ZERO BigInteger.TEN BigInteger.TWO(Java9)*/
System.out.println(BigInteger.ONE+" "+BigInteger.ZERO+" "+BigInteger.TEN);
System.out.println(q);
}
}
/*
100
1000000000000000000000
1000000000000000000100
100000000000000000000000
1 0 10
112000000000000000011200
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.noob.base;
import java.math.*;
import java.util.Scanner;

public class BigNumber {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
BigInteger lotteryOdds = BigInteger.valueOf(1);

for(int i=1;i<=a;i++){
lotteryOdds=lotteryOdds.multiply(BigInteger.valueOf(b-i+1)).divide(BigInteger.valueOf(i));

}
System.out.println("You odds are 1 in "+lotteryOdds);
}
}

数组

数组存储相同类型值的序列。

声明数组

1.数组是一种数据结构,用来存储同一类型值的集合

2.通过一个整型下标(index,或称索引)可以访问数组中的每一个值。

3.在声明数组变量时,需要指出数组类型(数据元素类型紧跟[])和数组变量的名字。

4.声明数组变量并将其初始化,使用new运算符创建数组。

5.数组长度不要求是常量。

6.一旦创建了数组,就不能再改变它的长度(可以修改数组元素),如果需要扩展数组的大小,可以使用另一种数据类型-array list(数组列表)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.noob.base;

public class ArrayStudy {
public static void main(String[] args) {
int n=20;

int[] c; /*该风格可以将类型int[](整型数组)与变量名清晰分开*/
c = new int[] {88,99,66};

int e[];
int[] a=new int[100];/*创建一个可以存储100个整数的数组*/

var b=new int[10];
b[0]=1000;
System.out.println(b[0]);

int[] d=new int[n]; /*创建一个长度为n的数组*/
/*Java提供了一个创建数组对象并同时提供初始值的简写形式,不需要new,不要指定长度*/
int[] smallPrimes = {1,3,4,5,8};
System.out.println(smallPrimes); //数组在堆内存中的地址

//数组类型默认值 boolean:false String:null double:0.0 int:0
boolean [] bl = new boolean[3];
System.out.println(bl[0]);
String [] s = new String [3];
System.out.println(s[0]);
double [] dou = new double[3];
System.out.println(dou[0]);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.noob.base;

public class ArrayStudy {
public static void main(String[] args) {
/* 最后一个值后面允许有逗号,方便不断为数组增加值 */
String[] authors= {
"James Gosling",
"Bill Joy",
"Guy Steele",
//add more names here and put a comma after each name
};

/*声明匿名变量*/
System.out.println(new int[] {17,19,23,9,37}[1]);
/*
* anonymous int array : new int[] { 1, 2, 3, 4};
* anonymous String array : new String[] {"one", "two", "three"};
* anonymous char array : new char[] {'a', 'b', 'c');
*/
/*
Best use of anonymous array is to implement variable argument method which can be invoked with a different number on arguments.
*/
sum(new int[]{ 1, 2, 3 });
}

public static void sum(int[] a)
{
int total = 0;

// using for-each loop
for (int i : a)
total = total + i;

System.out.println("The sum is:" + total);
}
}
1
2
3
4
5
6
7
8
9
public class ArrayStudy {
public static void main(String[] args) {
/*在Java中允许有长度为0的数组,如结果为数组的方法,结果为空时就需要长度为0的数组*/
int[] a =new int[0];
int[] b =new int[]{};
/*长度为0的数组与null并不相同*/
System.out.println(a.length);
}
}

访问数组元素

1.数组的下标从0开始。一旦创建了数组,就可以给数组元素赋值。

2.创建一个数字数组时,所有元素都初始化为0。boolean数组的元素会初始化为false。对象数组的元素则初始化为一个特殊值null,表示这些元素(还)未存放任何对象。

1
2
3
4
5
6
7
8
9
10
package com.noob.base;

public class ArrayStudy {
public static void main(String[] args) {
int[] a=new int[100];
for(int i=0;i<100;i++) {
a[i]=i;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.noob.base;

public class ArrayStudy {
public static void main(String[] args) {
int[] a=new int[100];
for(int i=0;i<100;i++) {
a[i]=i;
}
/*创建一个包含10个字符串的数组,所有字符串都为null*/
String[] names = new String[10];
System.out.println(names[1]); //null
/*空串*/
names[2]="";
System.out.println(names[2]);
/*获得数组中的元素个数,可以使用array.length*/
System.out.println(names.length);
/*System.out.println(names[12]);
ArrayIndexOutOfBoundsException: Index 12 out of bounds for length 10
如果创建了一个100个元素的数组,并且试图访问元素a[100](或任何在0~99之外的下标),
就会引发"array index out of bounds"异常。
*/

}
}

for each循环

for each循环的语句格式:

1
for (variable : collection) statement

1.定义一个变量用于暂存集合中的每一个元素,并执行相应的语句(语句块)。collection这一集合表达式必须是一个数组或者是一个实现了Iterable接口的类对象(例如ArrayList)。

2.for each循环语句的循环变量将会遍历数组中的每个元素,而不需要使用下标值。

3.利用Arrays类的toString方法可打印数组中的所有值,返回一个包含数组元素的字符串,这些元素包围在中括号内,并用逗号分隔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.noob.base;

import java.util.Arrays;

public class ArrayStudy {
public static void main(String[] args) {
String[] names = {
"Jack",
"Tom",
"Keven",
"Rick",
"Zard"
};
for(String name:names) {
System.out.println(name);
}
for(int i=0;i<names.length;i++) {
System.out.println(names[i]);
}
System.out.println(Arrays.toString(names));
}
}

数组拷贝

1.在Java中,允许将一个数组变量拷贝到另一个数组变量,即两个变量将引用同一个数组。

2.将一个数组的所有值拷贝到一个新的数组中去,使用Arrays类的copyOf方法。第2个参数是新数组的长度。这个方法通常用来增加数组的大小。如果数组元素是数值型,那么多余的元素将被赋值为0;如果数组元素是布尔型,则将赋值为false。相反,如果长度小于原始数组的长度,则只拷贝最前面的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.noob.base;

import java.util.Arrays;

public class ArrayStudy {
public static void main(String[] args) {
int[] smallPrimes = {1,6,7,88,78};
System.out.println(smallPrimes[3]);
int[] luckyNumbers = smallPrimes;
System.out.println(luckyNumbers[4]);
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);
System.out.println(copiedLuckyNumbers[1]);
int[] copiedLuckyNumbers2 = Arrays.copyOf(luckyNumbers, luckyNumbers.length*2);
System.out.println(copiedLuckyNumbers2[6]);
}
}

Java数组与堆栈上的C++数组有很大不同,但基本上与在堆(heap)上分配的数组指针一样。

1
int[] a = new int[100]; // Java 

不同于

1
int a[100]; //C++ 

而等同于

1
int* a = new int[100]; //C++

Java中的[]运算符被预定义会为完成越界数组,而且没有指针运算,即不能通过a加1得到数组的下一个元素。

命令行参数

每一个Java应用程序都有一个带String arg[]参数的main方法。这个参数表明main方法将接收一个字符串数组,也就是命令行参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Message {
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,");
for(int i=1;i<args.length;i++)
System.out.print(" "+args[i]);
System.out.print("!");
}
}
/*
java Message -g cruel world
Goodbye, cruel world!
*/

在Java应用程序的main方法中,程序名并没有存储在args数组中。

1
2
> java Message -h world
Hello, world!

数组排序

1.对数值型数组进行排序,使用Arrays类中的sort方法(优化的快速排序(QuickSort)算法)。

1
2
3
4
5
6
7
8
9
10
package com.noob.base;
import java.util.Arrays;

public class SortLearn {
public static void main(String[] args) {
int[] numbers = {1,5,7,2,3,4,6,7,9,1};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.noob.base;

import java.util.Arrays;
import java.util.Scanner;

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();

int[] numbers= new int[n];
for(int i=0;i<numbers.length;i++) {
numbers[i] = i+1;
}
int[] result = new int[k];
for(int i=0;i<result.length;i++) {
/*Math.random方法将返回一个0到1之间(包含0、不包含1)的随机浮点数*/
int r=(int) (Math.random()*n);
result[i]=numbers[r];
numbers[r]=numbers[n-1];
/*
确保不会再次抽取到那个数值,因为所有抽彩的数值必须不相同。
因此,这里用数组中的最后一个数值改写number[r],并将n减1
*/
n--;
}
Arrays.sort(result);
System.out.println("Bet the following combination.It'll make you rich!");
for(int r:result) {
System.out.println(r);
}
}
}

多维数组

1.多维数组将使用多个下标访问数组元素,适用于表示表格或更加复杂的排列形式。

2.for each循环语句不能自动处理二维数组的每一个元素。它会循环处理行,而这些行本身就是一维数组。要想访问二维数组的所有元素,需要使用两个嵌套的循环。

1
2
3
for (double[] row : a)
for(double value : row)
do something with value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.noob.base;

import java.util.Arrays;

public class MatrixStudy {
public static void main(String[] args) {
int x=6;
int y=6;
/*声明一个二维数组(矩阵)*/
double[][] matrix;
/*对数组进行初始化之前是不能使用的*/
matrix = new double[x][y];
/*如果知道数组元素,就可以不调用new,而直接使用简写形式对多维数组进行初始化*/
int[][] magicSquare= {
{16,3,2,13},
{5,10,12,13},
{6,13,6,3},
{1,3,2,26}
};
/*一旦数组初始化,就可以利用两个中括号访问各个元素*/
System.out.println(magicSquare[2][2]);

for(int i=0;i<magicSquare.length;i++) {
for(int t=0;t<magicSquare[i].length;t++) {
System.out.println(magicSquare[i][t]);
}
}

for(int[] row:magicSquare) {
for(int num:row) {
System.out.println(num);
}
}
/*快速打印一个二维数组的数据元素列表*/
System.out.println(Arrays.deepToString(magicSquare));
}
}

不规则数组

1.Java实际上没有多维数组,只有一维数组。多维数组被解释为"数组的数组"。

表达式balances[i]引用第i个子数组,也就是表格的第i行。它本身也是一个数组,balances[i][j]引用这个数组的第j个元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.noob.base;

import java.util.Arrays;

public class MatrixStudy {
public static void main(String[] args) {

int[][] magicSquare= {
{16,3,2,13},
{5,10,12,13},
{6,13,6,3},
{1,3,2,26}
};
/*可以单独访问数组的某一行,可以让两行交换*/
System.out.println(Arrays.deepToString(magicSquare));
int[] temp = magicSquare[1];
System.out.println(Arrays.toString(temp));
magicSquare[1]=magicSquare[2];
magicSquare[2]=temp;
System.out.println(Arrays.deepToString(magicSquare));
/*方便构造一个“不规则”数组,即数组的每一行有不同的长度*/
int lines=5;
int[][] odds=new int[lines][];

for(int n=0;n<odds.length;n++) {
odds[n]=new int[n+1];
for(int t=0;t<odds[n].length;t++) {
odds[n][t]=t;
}
}
System.out.println(Arrays.deepToString(odds));
}
}

在C++中,Java声明

1
double[][] balances = new double[10][6];  //Java

不同于

1
double balances[10][6]; //C++

也不同于

1
double (*balances)[6] = new double[10][6]; // C++

而是分配了一个包含10个指针的数组:

1
double** balances = new double*[10]; // C++

然后,指针数组的每一个元素被填充了一个包含6个数字的数组:

1
2
for (i = 0; i < 10; i++)
balances[i] = new double[6];

当创建new double[10][6]时,这个循环是自动的。当需要不规则的数组时,只能单独地创建行数组。