文章目录

  • 2. Java程序设计环境
  • 2.1 java环境
  • 2.2 java的编译和运行
  • 2.3 集成开发环境-IDEA
  • 常用快捷键
  • 3. Java的基本程序设计结构
  • 3.3 数据类型
  • 整型
  • 浮点数
  • char型
  • (扩展)编码问题
  • boolean型
  • 3.4 变量
  • 3.5 运算符
  • 常用Math函数
  • 优先级
  • 枚举类型
  • Random
  • 3.6 字符串
  • 字符串
  • String API
  • StringBuilder
  • 3.7 输入输出
  • 读取输入
  • 格式化输出
  • 文件的输入和输出
  • 3.8 流程控制
  • 3.9 大数值
  • 3.9 数组 Arrays


2. Java程序设计环境

java核心卷电子书 java核心卷一_java

2.4、2.5小节略

2.1 java环境

添加系统变量

java核心卷电子书 java核心卷一_idea_02

编辑环境变量

java核心卷电子书 java核心卷一_java_03

验证配置成功与否

javac -version

2.2 java的编译和运行

windows下,在java源文件所在目录打开命令行窗口,输入以下指令

javac Test.java			//编译
java Test				//运行

注意:如果Test.java中有package语句,即java文件在某个包下,那么java Test将提示找不到主类

2.3 集成开发环境-IDEA

创建一个简单的java项目:NewProject - Java - 设置JDK安装路径 - 一直next

java核心卷电子书 java核心卷一_字符串_04

IDEA只能在标记为Source的文件下子目录中添加Java Class文件,即显示为蓝色的文件夹
解决方法:File - Project Structure - Modules - 在右侧目录中找到新建的包 - 右键Sources - Apply,即可

public class Test{
    public static void main(String[] args){
        String str = "helloworld";
        System.out.println(str);
        System.out.println(str.length());
    }
}

常用快捷键

  1. 跳转到函数所在类:按住ctrl+alt,点击函数名

3. Java的基本程序设计结构

命名规则:
类名大写字母开头,多个单词则每个单词首字母大写
公共类(如public class Test)应当与文件名相同

3.3 数据类型

Java是一种强类型语言。共有8种基本类型( primitive type),其中有4种整型、2种浮点类型、1种用于表示Unicode编码的字符单元的字符类型char和1种用于表示真值的boolean类型。

强制转换:int a = (int)2.2;//需要显式转换,否则报错

整型

java核心卷电子书 java核心卷一_Math_05

在java中,整型的范围和机器无关,这和c/c++不同
长整型有一个后缀L或l
从Java7开始,加上前缀0b或0B就可以表示二进制
从Java7开始,可以为数字加下划线,如100_000,等同于100000,编译器会自动删除下划线
java没有任何无符号(unsigned)类型

浮点数

java核心卷电子书 java核心卷一_Math_06

double精度是float的2倍,float需要加f或F作为后缀

三个特殊的浮点数值(实际中不常用)

  • 正无穷大:Double.POSITIVE_INFINITY
  • 负无穷大:Double.NEGATIVE_INFINITY
  • NaN(不是一个数字):Double.NaN;用Double.isNaN(x)判断是否为数字,而不能用Double.NaN

精度误差问题
如输出System.out.println(2.0-1.1); 结果为0.899999999
要想避免误差,可以使用BigDecimal类

char型

char类型占2个字节,范围从\u0000到\Uffff

“\u0022+\u0022”,会被解析为”“+”“
注释 // \user 会产生语法错误,提示\u未跟4个十六进制数

在java中,char 类型描述了 UTF-16 编码中的一个代码单元(C++中char只占1个字节)
java中不推荐使用char类型

(扩展)编码问题

原博客:

  • ASCII

美国制定的编码方式,描述英文字符同1个字节,即8位二进制数的对应关系
范围为0~256,如‘A’就是01000001,实际上只要128个字符被使用,8位中最高位始终为0

问题:英语用128个字符表示足够了,但其他语言不行。
部分国家将8个字节一同利用起来,范围变成0~255,但问题在于虽然在前128个字符中达成了一致,在128-255各国表示的字符却不相同
于是开始采用2个字节来表示字符,同时采用内码表来进行不同编码方式的切换

  • unicode

提出的一种,能表示世界上所有字符的标准方案。
问题:有的字符可能1个字节,有的可能2个字节,甚至3个字节。如果以最大字节存储,造成浪费
解决:UTF-8、UTF-16、UTF-32

  • UTF-8
  • 使用最广泛的一种unicode编码方式,最大特点是可变长,可以使用1-4个字节来表示字符
  • 对于1个字节的字符,最高位为0,与ASCII完全兼容
  • 对于n字节字符,前n位为1,第n+1位为0,剩余的n-1个字节前两位都设为10,剩下的二进制位以该字符的unicode码点填充

Unicode 十六进制码点范围

UTF-8 二进制

0000 0000 - 0000 007F

0xxxxxxx

0000 0080 - 0000 07FF

110xxxxx 10xxxxxx

0000 0800 - 0000 FFFF

1110xxxx 10xxxxxx 10xxxxxx

0001 0000 - 0010 FFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

以“汉”为例,码点是0x6c49(0110 1100 0100 1001),占15位,则3个字节才能满足,将它依次填充后变为
UTF-8编码:11100110 10110001 10001001

  • UTF-16

unicode分区定义字符,每个区65536(16 bit)个字符,称为一个平面(plane),目前有17个平面(5 bit),也就是说目前整个unicode字符大小是221

最前面的65536称为基本平面(BMP),占2个字节,码点范围从 U+0000到U+FFFF,存放最常见的字符;其他平面称为辅助平面(SMP),占4个字节,码点范围从 U+010000到U+10FFFF

如何知道该字符是2字节还是4字节:
在BMP内,U+D800 到 U+DFFF 是一个空段,不对应任何字符
SMP有220个,需要20 bit;UTF-16将20 bit分为两部分,前 10 位映射在 U+D800 到 U+DBFF,称为高位(H),后 10 位映射在 U+DC00 到 U+DFFF,称为低位(L);
一个辅助平面的字符,被拆成两个基本平面的字符表示

因此,当遇到两个字节,发现它的码点在 U+D800 到 U+DBFF 之间,就可以断定,紧跟在后面的两个字节的码点,应该在 U+DC00 到 U+DFFF 之间,这四个字节必须放在一起解读。

字符 “?” 的unicode码点为 0x20BB7,超出了BMP的范围;
(1)计算超出部分:0x20BB7 - 0x10000 = 0b0001000010 1110110111,用20位二进制数表示
(2)前10位映射到 U+D800 到 U+DBFF:U+D800 = 0b110110 0000000000,映射(替换后10位)得到ob110110 0001000010
(3)后10位映射到 U+DC00 到 U+DFFF:U+DC00 = ob110111 0000000000,映射(替换后10位)得到ob110111 1110110111
(4)映射后前10位就是0xD842,后10位就是0xDFB7,即字符 “?”的UTF-16编码为 0xD842 0xDFB7

boolean型

2个值:false和true

java中,boolean型和整型不能相互转换;这和C++不同,也就是说类似 if(x = 0) 这样的代码将直接报错

3.4 变量

与多数语言相比,Java中“字母”和“数字”的范围更大。如字母包括’A’~‘Z’ 、 ‘a’~ ‘z’、‘_’、S或在某种语言中表示字母的任何Unicode字符。数字也如是

如果想要知道哪些Unicode字符属于Java中的“字母”,可以使用Character类的 isJavaldentifierStart 和 isJavaldentifierPart 方法检查

  • 变量应初始化再使用,否则会报错(一些静态变量会自动初始化);
  • java中,变量声明应尽可能靠近第一次使用的地方;(在C++中,可以使用extern声明变量,java没有这种用法,在java中,不区分变量的声明和定义)
  • 常量,用 final 修饰;1个常量如果希望在多个方法中使用,可以定义为类常量,用static final修饰,要在方法外定义
    (C++中使用const,java保留const作为关键字,但不使用,而是使用final)

3.5 运算符

整数被0除将抛出异常,而浮点数被0除将得到无穷大或者NaN结果

strictfp:
有关java规定的浮点数精度计算问题,有机会再了解

常用Math函数

import static java.lang.Math.*;//使用这条语句,使用函数时可不加 Math. 前缀

Math.sqrt((x);//<double>
Math.pow(x, a);//<double, double>, 求x的a次幂
//<int>或<long>,取余;floorMod(13,5)=3;floorMod(-13,5)=2;floorMod(13,-5)=-2;floorMod(-13,-5)=-3
Math.floorMod(x, a);
Math.round(x);//<double>类型,四舍五入保留整数
Math.random();//产生一个0到1的随机数,生成任意范围的随机数:(int) (Math.random()*(max-min)+min); 
          
Math,sin(x);//<double>,x = 度数*π/180
Math.cos(x);
Math.tan(x);
Math.atan(x);
Math.atan2(x);
          
Math.exp(x);//<double>,指数函数,e的x次方
Math.log(x);//<double>,以e为底的对数
Math.log10(x);//<double>,以10为底的对数
以任意的x为底:logx(y) = Math.log(x) / Math.log(y);//换底公式
          
Math.PI;//近似的π
Math.E;//近似的e常量
          
//如果想得到一个完全可预测的结果(各平台运行一致),应使用StrictMath类,Math类使用例程,胜在运行速度

优先级

java核心卷电子书 java核心卷一_字符串_07

枚举类型

enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };//不能放在方法内,要作为一个类去定义
Size s = Size.MEDIUM;//System.out.println(s),将输出MEDIUM

Random

Random generator = new Random();
nextId = generator.nextInt(10000);;//生成0-9999的随机数
Random();//构造一个新的随机数生成器。
int nextInt(int n);//1.2,返回一个0 ~ n-1之间的随机数

3.6 字符串

字符串

Java 没有内置的字符串类型, 而是在标准 Java 类库中提供了 String 类

  • 子串:substring
String str = "hello";
String s = str.substring(1, 3);
System.out.println(s);//输出"el"
//方法一:public String substring(int beginIndex, int endIndex);
//方法二:public String substring(int beginIndex);
  • 拼接:join
//方法1:使用"+"拼接
String str = "PC" + 16;//str为"PC16"
//方法2:join,第1个参数是CharSequence类型,不能用单个字符
String str = String.join("--", "S", "M", "L", "XL");//输出"S--M--L--XL"
  • 不可变字符串
    java中String类型的字符串是不能修改的,这和C++不同
    必须修改是可以借助 substring 和 + 来完成
    虽然String不允许使用类似 str[2] = ‘a’,但却可以对整个字符串重新赋值,如 str = “newstr”;java会自动对原字符串进行回收
  • 相等:equals() 或者 compareTo()
s.equals(t);//判断字符串s和t是否相等
s.equalsIgnoreCase(t);//判断字符串s和t是否相等,并忽略大小写
s.compareTo(t) == 0;//compareTo返回int型,0代表相等,比t小返回-1,比t大返回1
s.compareToIgnoreCase(t) == 0;//忽略大小写

注意:不能使用 == 来判断字符串相等;== 只能判断两个字符串是否放在同一个位置上,但相同的字符串可能放在不同的内存位置

String greeting = "Hello";//initialize greeting to a string
if (greeting == "Hello"){};//true
if (greeting.substring(0, 3) == "Hel"){}//false

如果虚拟机始终将相同的字符串共享,就可以使用 == 运算符检测是否相等
但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的

  • 空串和null串
//判断空串"",空串是一个长度为0的java对象
if(str.length() == 0){}
if(str.equals("")){}
//判断null串,null串不是一个对象
if(str == null);
  • 码点和代码单元
    Java 字符串由char值序列组成,char 数据类型是一个采用UTF-16 编码表示Unicode码点的代码单元
    大多数的常用Unicode 字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示
  • length():返回代码单元数量 = 基本字符个数 + 2*辅助字符个数
String str = "🍷Hello";
System.out.println(str.length());//返回7,第1个字符是辅助字符,占2个代码单元
  • codePointCount():返回字符个数(码点数量),不区分基本字符还是普通字符
System.out.println(str.codePointCount(0, str.length()));//返回6,因为有6个字符
  • charAt():返回指定位置的字符,位置要小于length()
    !要注意存在辅助字符时,charAt() 将导致错误访问
String str = "🍷Hello";
for(int i=0; i<str.length(); ++i)
	System.out.print(str.charAt(i));//输出🍷Hello
//如果用的println,那么第0个和第1个代码单元将被分开,导致输出非原来字符
  • codePointAt():返回第i个字符的码点
//依次查看各个字符的码点
//方法1
String str = "🍷Hello";
for(int i=0; i<str.codePointCount(0, str.length()); ++i) {
    int index = str.offsetByCodePoints(0, i);//index依次为 0 2 3 4 5 6
    int cp = str.codePointAt(index);//str.codePointAt(0)将输出:0x1f377
    System.out.println(Integer.toHexString(cp));//依次输出:1f377 48 65 6c 6c 6f
}
//方法2:isSupplementaryCodePoint()判断是否为辅助字符
String str = "🍷Hello";
for(int i=0; i<str.length(); ++i){
    int cp = str.codePointAt(i);
    System.out.println(Integer.toHexString(cp));
    if(Character.isSupplementaryCodePoint(cp)) i++;//是辅助字符,前进一个代码单元
}
//方法3:isSurrogate()判断指向的代码单元是否是辅助字符
String str = "🍷Hello";//7个代码单位,isSurrogate()依次是true true false false false false false
for(int i=0; i<str.length(); ++i){
    int cp = str.codePointAt(i);
    System.out.println(Integer.toHexString(cp));
    if(Character.isSurrogate(str.charAt(i))) i++;//是辅助字符,前进一个代码单元
}
  • codePoints():返回字符串所有的码点,比codePointAt()更便捷
//获得码点数组
String str = "🍷Hello";
int[] codePoints = str.codePoints().toArray();
for(int i=0; i<codePoints.length; ++i)
    System.out.println(Integer.toHexString(codePoints[i]));
//将码点数组还原为字符串
String code1 = new String(codePoints, 0, codePoints.length) ;
System.out.println(code1);//输出:🍷Hello

String API

int 1ength();//返回长度
int compareTo(String other);//按字典顺序,相等为0;字符串在other之前,返回负数(ASCII码值相减),反之返回正数
boolean equals(0bject other);
boolean equalsIgnoreCase(String other);
char charAt (int index);//返回给定位置的代码单元所代表的字符
boolean startsWith(String prefix);
boolean endsWith(String suffix);//以指定字符串开头或结尾,返回true
String replace(CharSequence oldString, CharSequence newString);//子串替换,返回一个新的字符串
String substring(int beginIndex);//取子串
String substring(int beginlndex, int endlndex);//取子串,固定结尾位置
String toLowerCase();//转小写
String toUpperCase();//转大写
String trim( );//删除字符串开头和结尾的空格
String join(CharSequence delimiter, CharSequence... elements);//8,如String.join("_", str1, str2)

int indexOf(String str);//返回字符串中与str匹配第一个位置的索引,从0开始,辅助字符记为 2
int indexOf(String str, int fromlndex);//同上,但限定从fromlndex之后,没有返回0
int indexOf(int cp);//与代码点cp匹配的第一个子串的开始位置,如 oldstr.indexOf("\u0048");
int indexOf(int cp, int fromlndex);

int codePointAt(int Index);//5.0,返回从给定位置开始的码点
int codePointCount (int startlndex, int endlndex);//5.0,返回代码点的数量,辅助字符记为 1
int offsetByCodePoints(int startIndex, int cpCount);//5.0,返回从startIndex字符开始,位移cpCount字符后的码点索引;
IntStream codePoints();//8,将这个字符串的码点作为一个流返回。调用toArray将它们放在一个数组中
new String(int[] codePoints, int offset, int count);//5.0,用数组中从offset 开始的count 个码点构造一个字符串

其他API可以查java的API文档

StringBuilder

StringBuilder builder = new StringBuilder();
builder.append('a');
builder.append("bc");
String str = builder.toString();//转化为字符串

每次添加都会创建一个新的String对象,效率较低

StringBuilder类在JDK5.0中引入,前身是StringBuffer类,两者API相同
StringBuilder类效率较低,但支持多线程;单线程时应使用StringBuffer类

  • StringBuilder API
StringBuilder();//构造一个空的字符串构建器
int length();//返回构建器或缓冲器中的代码单元数量,builder.length()
StringBuilder append(String str);//追加一个String
StringBuilder append(char c);//追加一个char
StringBuilder appendCodePoint(int cp);//追加一个代码点,并将其转换为一个或两个代码单元并返回this。
void setCharAt(int i, char c);//将第i个代码单元设置为c
StringBuilder insert(int offset, String str);//在offset位置插入一个字符串并返回this
StringBuilder insert(int offset, char c);//在offset 位置插入一个代码单元并返回this。
StringBuilder delete(int startIndex, int endIndex);//删除偏移量从startIndex到endIndex-1的代码单元并返回this
String toString();//返回一个与构建器或缓冲器内容相同的字符串

3.7 输入输出

读取输入

首先需要构造一个Scanner对象,并与“ 标准输人流” System.in关联

  • 示例
import java.util.Scanner;
//读入一行
Scanner in = new Scanner(System.in);
String str = in.nextLine();
System.out.println(str);
  • 读入各种类型
in.nextLine():读入一行,以换行符作为分隔符
in.next():读入一个单词,以空格作为分隔符
in.nextInt():读入一个整数
in.nextDouble():读入一个浮点数
  • Console类
//注意,eclipse或者idea是没有控制台的,在这2个平台运行会报错;可以在命令行进行编译和运行,能够正常执行
import java.io.Console;
//可以读取密码,使输入时不可见;每次只能读取一行
try {
    Console cons = System.console();
    String username = cons.readLine("User name: ");
    char[] passwd = cons.readPassword("Password:");
    for (int i = 0; i < passwd.length; ++i)
        System.out.println(passwd[i]);
}catch (Exception e) {
    e.printStackTrace();
}
  • 常用API
//java.util.Scanner 5.0
Scanner (InputStream in);//用给定的输人流创建一个Scanner对象
String nextLine();//读取输入的下一行内容
String next();//读取输入的下一个单词(以空格作为分隔符)
int nextInt();
double nextDouble();//读取并转换下一个表示整数或浮点数的字符序列
boolean hasNext();//检测输人中是否还有其他单词
boolean hasNextInt();
boolean hasNextDouble();//检测是否还有表示整数或浮点数的下一个字符序列

//java.lang.System 1.0
static Console console();//没有控制台返回null

//java.io.Console 6
static char[] readPassword(String prompt, Object...args);
static String readLine(String prompt, Object...args);//显示字符串prompt,并且读取用户输入,直到输入行结束。args 参数可以用来提供输入

格式化输出

  • printf转换符,java5.0 沿用
System.out.printf("%x", 17);//输出17的十六进制:11
System.out.printf("%s is %8.2f\n", "number", 3.3333);//输出3.33,一共占8位,保留2位小数
  • printf标识符
System.out.printf("%,.2f", 10000.0/3.0);//输出:3,333.33
System.out.printf("%,(.2f", -10000.0/3.0);//输出:(3,333.33);正数无影响,负数不对应负号,而是加括号
System.out.printf("%-7d", 3);//左对齐,必须跟一个宽度数字
  • format()格式化:格式化字符串,但不打印
String str = String.format("%s is %#x", "number", 17);
System.out.printf(str);//输出:number is 0x11
  • 日期和时间 - printf实现(实际推荐使用java.time包)
import java.util.Date;
System.out.printf("%tc", new Date());//输出:星期二 十一月 08 14:39:39 CST 2022
System.out.printf("%1$s %2$tB %2$te, %2$tY", "Due date:", new Date());//输出:Due date: 十一月 8, 2022
//这种格式的索引从1开始,必须从%开始,$结尾
System.out.printf ("%s %tB %<te, %<tY", "Due date:", new Date());//结果同上

文件的输入和输出

  • 输入
import java.io.IOException;//必须加异常处理
import java.nio.file.Paths;
import java.util.Scanner;
public class Test{
    public static void main(String[] args) throws IOException {
        Scanner in = new Scanner(Paths.get("e:\\test.txt") , "UTF-8");
        String str = in.nextLine();
        System.out.println(str);
    }
}

注意:Paths.get()里的路径问题,特别是相对路径,如IDEA的默认相对路径应当是整个项目所在位置,而不是.java文件所在路径

  • 输出
import java.io.IOException;
import java.io.PrintWriter;
public class Test{
    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter("e:/test.txt", "UTF-8");
        out.print("new line");//每次都会覆盖原有内容
        out.close();//要关闭后才能看到效果
    }
}
  • API
//java.util.Scanner 5.0
Scanner(File f);//构造一个从给定文件读取数据的Scanner
Scanner(String data);//构造一个从给定字符串读取数据的Scanner

//java.io.PrintWriter 1.1
PrintWriter(String fileName);//构造一个将数据写入文件的PrintWriter。文件名由参数指定

//java.nio.file.Paths 7
static Path get(String pathname);//根据给定的路径名构造一个Path

3.8 流程控制

java中不允许在嵌套的块中重定义一个变量;C++可以,重定义的变量会覆盖掉前面的定义

注意:避免检测两个浮点数相等,由于精度问题,可能永不会相等

如:if while do…while for switch break continue

  • switch中case的常量必须是:
    类型为char、byte、short 或 int 的常量表达式。
    枚举常量。
    从Java SE 7 开始, case 标签还可以是字符串字面量。
  • switch使用枚举
Size sz = ...;
switch (sz){
	case SMALL: // no need to use Size.SMALL
        ...
		break;
	...
}
  • 带标签的break
//用法如下:break跳出标签所指的循环,下述代码不加标签,将陷入死循环
System.out.println("start");
flag:
while(true)
    for(int i=0; i<10; ++i)
        for(int j=0; j<10; ++j)
            if(i==5 && j==5)
                break flag;
System.out.println("end");

3.9 大数值

  • java.math包中的 Biglnteger 类实现了任意精度的整数运算,BigDecimal 实现了任意精度的浮点数运算
//a = 100;
BigInteger a = BigInteger.valueOf(100);
//b = 50;
BigInteger b = BigInteger.valueOf(50);
//c = a+b = 150;
BigInteger c = a.add(b);
//d = c*(b+2) = 7800;
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));
//e = d*(a-b+1)/c = 2652;
BigInteger e = d.multiply(a.subtract(b).add(BigInteger.valueOf(1))).divide(c);
System.out.println(e);
  • API
//BigInteger
static BigInteger valueOf(1ong x);//转换为大数
BigInteger add(BigInteger other);//加法
BigInteger subtract(BigInteger other);//减法
BigInteger multipiy(BigInteger other);//乘法
BigInteger divide(BigInteger other);//除法
BigInteger mod(BigInteger other);//取余
int compareTo(BigInteger other);//比较,相等为0,否则 num<other ? -1 : 1

//BigDecimal
static BigDecimal valueOf(long x);
static BigDecimal valueOf(long x, int scale);//表示x/10^scale
BigDecimal add(BigDecimal other);//加法
BigDecimal subtract(BigDecimal other);//减法
BigDecimal multipiy(BigDecimal other);//乘法
BigDecimal divide(BigDecimal other, RoundingMode mode);//除法,RoundingMode舍入方式,可以不写,默认四舍五入
//RoundingMode.HALF_UP四舍五入,BigDecimal.ROUND_UP进位,BigDecimal.ROUND_DOWN舍去
int compareTo(BigDecimal other);

3.9 数组 Arrays

  • for each:只能是数组或实现了Iterable接口的类对象(如ArrayList)
int[] a = new int[5];
for(int num:a) System.out.print(num);

打印数组的所有元素,还可以使用java.util.Arrays类

System.out.println(Arrays.toString(a));//输出:[0, 0, 0, 0, 0]
  • 数组初始化和匿名数组
//初始化
int[] a = {1,2,3,4,5};
int[] a = new int[] {1,2,3,4,5};
//匿名数组
System.out.println(Arrays.toString(new int[]{1,2,3}));

在java中,允许数组长度为0,如new int[0];这和null数组不同;

  • 浅拷贝和深拷贝
//浅拷贝,a和b指向同一个位置
int[] a = {1,2,3,4,5};
int[] b = a;
b[2] = 100;
System.out.println(Arrays.toString(a));//发现a也被修改了

//深拷贝
//使用copyOf,第一个参数是要复制的数组a,第二个参数是b的大小,可以用来扩充数组;多的赋初值0或false
int[] a = {1,2,3,4,5};
int[] b = Arrays.copyOf(a, a.length);
b[2] = 100;
System.out.println(Arrays.toString(b));//a不会被修改
  • Arrays API
//java.util.Arrays 1.2
static String toString(type[] a);//5.0
static type copyOf(type[] a, int length);
static type copyOfRange(type[] a, int start, int end);
static void sort(type[] a);//采用优化的快速排序算法对数组进行排序
static int binarySearch(type[] a, type v);//二分查找值,查找成功返回下标值,否则返回一个负数
static int binarySearch(type[] a, int start, int end, type v);//6
static void fill(type[] a , type v);//将数组的所有元素设置为v
static boolean equals(type[] a, type[] b);//比较是否相同,type不包括String
  • 多维数组
  • for each
for(double[] row : a)
	for(double value : row)
		...
  • 打印数组
System.out.println(Arrays.deepToString(a));
  • 交换两行
//balances是一个二维数组
double[] temp = balances[i] :
balances[i] = balances[i+1];
balances[i+1] = temp;
  • 不规则数组
//需要先确定行数,然后为每行分配大小
int nrows = 5;//定义有多少行
int[][] odds = new int[nrows][];
for(int i=0; i<nrows; ++i)
    odds[i] = new int[i+1];//为每行分配不同大小

可以再了解一下C++的指针和数据,如:
double (* balances) [6] = new double[10] [6] ;//分配了一个包含10 个指针的数组
double** balances = new double *[10];//指针数组的每一个元素被填充了一个包含6个数字的数组