java的基本代码结构_1-03 Java的基本程序设计结构

1-03 Java的基本程序设计结构

3.1 & 3.2

在一个单词中间使用大写字母的方式称为骆驼命名法。以其自身为例,应该写成CamelCase)。

与C/C++一样,关键字void表示这个方法没有返回值,所不同的是main方法没有为操作系统返回“退出代码”。如果main方法正常退出,那么Java应用程序的退出代码为0,表示成功地运行了程序。如果希望在终止程序时返回其他的代码,那就需要调用System.exit方法。

3.3 数据类型

Java是一种强类型语言。这就意味着必须为每一个变量声明一种类型。

在Java中,一共有8种基本类型(primitive type),其中有:

1. 4种整型

bd808fe1a3fbf6270dc5d1d6bae81928.png

Java没有任何无符号(unsigned) 形式的int、long、 short 或byte类型。

2. 2种浮点类型

145ab2577b0db445031d6f55506725bc.png

浮点数值不适用于无法接受舍入误差的金融计算中。 例如,命令System.out.printn(2.0-1.1 )将打印出0.89999999999999, 而不是人们想象的0.9。 这种舍入误差的主要原因是浮点数值采用二进制系统表示,而在二进制系统中无法精确地表示分数1/10。这.就好像十进制无法精确地表示分数1/3一样。如果在数值计算中不允许有任何舍入误差,就应该使用BigDecimal类。

3. 1种用于表示Unicode编码的字符单元的字符类型char

4b2d10be697df388073b98f474d9e12a.png

Unicode转义序列会在解析代码之前得到处理。 例如,"\u0022+\u022"并不是一个由引号(U+0022)包围加号构成的字符串。实际上,\u0022会在解析之前转换为",这会得到""+"",也就是一个空串。

强烈建议不要在程序中使用char类型,除非确实需要处理UTF-16代码单元。最好,将字符串作为抽象数据类型处理(有关这方面的内容将在3.6节讨论)。

4. 1种用于表示真值的boolean 类型。

3.4 变量

在Java中不区分变量的声明和定义,而C/C++区分。

在Java中,利用关键字final指示常量。关键字final表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改了。习惯上,常量名使用全大写。

在Java中,经常希望某个常量可以在一个类中的多个方法中使用,通常将这些常量称为类常量。可以使用关键字static final 设置一个类常量。

3.5 运算符

整数被0除将会产生一个异常,而浮点数被0除将会得到无穷大或NaN结果。

在默认情况下,虚拟机设计者允许对中间计算结果采用扩展的精度。但是,对于使用strictfp关键字标记的方法必须使用严格的浮点计算来生成可再生的结果。例如,可以把main方法标记为

public static strictfp void main(String[] args)

于是,在main方法中的所有指令都将使用严格的浮点计算。

如果将一个类标记为strictfp,这个类中的所有方法都要使用严格的浮点计算。

3.5.1 数学函数与常量

Math类:各种各样的数学函数。

StrictMath类:得到一个完全可预测的结果比运行速度更重要。

3.5.2 数值类型之间的转换

在图3-1中有6个实心箭头,表示无信息丢失的转换;有3个虚箭头,表示可能有精度损失的转换

1c37864884ca028fb06f8bd098839d36.png

3.5.3 强制类型转换

强制类型转换的语法格式是在圆括号中给出想要转换的目标类型

不要在boolean类型与任何数值类型之间进行强制类型转换

3.5.4 结合赋值和运算符

+=

3.5.5 自增与自减运算符

n++将变量n的当前值加1,n--则将n的值减1。

用在表达式中时,前缀形式会先完成加1;而后缀形式会使用变量原来的值。

int m= 7;

int n= 7;

int a=2*++m; // now a is 16,m is 8

int b=2*n++; // now b is 14,n is 8

3.5.6 关系和boolean运算符

&&

||

!

?:

3.5.7 位运算符

处理整型类型时,可以直接对组成整型数值的各个位完成操作。

这意味着可以使用掩码技术得到整数中的各个位。

利用&并结合使用适当的2的幂,可以把其他位掩掉,而只保留其中某一位。

移位运算符的右操作数要完成模32的运算(除非左操作数是long类型,在这种情况下需要对右操作数模64)。例如,1<<35的值等同于1<<3或8。

&

|

^

~

<<

>>

>>> 用0填充高位

3.5.8 括号与运算符级别

5bcbb0d6446c30e0db241b24033930cd.png

3.5.9 枚举类型

枚举类型包括有限个命名的值。例如,

enum Size { SMAL, MEDIUM, LARCE, EXTRA_ _LARGE };

现在,可以声明这种类型的变量:

Size s = Size.MEDIUM;

Size类型的变量只能存储这个类型声明中给定的某个枚举值,或者null 值,null 表示这个变量没有设置任何值。

3.6 字符串

从概念上讲,Java字符串就是Unicode字符序列。

Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类,即String类。每个用双引号括起来的字符串都是String类的一个实例。

3.6.1 字串

String.substring(a, b); //容易计算子串的长度。length = b-a

3.6.2 拼接

使用 + 号连接两个字符串;

如果需要把多个字符串放在一起,用一个定界符分隔,可以使用静态join方法:

String all = String.join(" / ", "S", "M", "L", "XL");

// all is the string "S/M/L / XL"

3.6.3 不可变字符串

由于不能修改Java字符串中的字符,所以在Java文档中将String 类对象称为不可变字符串。

优点:编译器可以让字符串共享。

3.6.4 监测字符串是否相等

String.equals();

//比较的可以是字符串变量,也可能是字符串字面量。

"hello".equals(a); //是合法的

//要想检测两个字符串是否相等,而不区分大小写

"Hel1o".equalsIgnoreCase("hello");

一定不要使用==运算符检测两个字符串是否相等。这个运算符只能够确定两个字符串是否放置在同一个位置上。当然,如果字符串放置在同一个位置上,它们必然相等。但是,

完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上。

如果虚拟机始终将相同的字符串共亨,就可以使用=运算符检测是否相等。但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的。因此,千万不要使用==运算符测试字符串的相等性,以免在程序中出现糟糕的bug。从表面上看,这种bug 很像随机产生的间歇性错误。

3.6.5 空串与Null串

空串""是长度为0的字符串。可以调用以下代码检查一个字符串是否 为空:

if (str,1ength() == 0)

//or

if (str.equals(""))

空串是一个Java对象,有自己的串长度(0)和内容(空)。不过,String 变量还可以存放一个特殊的值,名为null,这表示目前没有任何对象与该变量关联(关于null的更多信息请参见第4章)。要检查一个字符串是否为null,要使用以下条件:

if (str == null)

有时要检查一个字符串既不是null也不为空串,这种情况下就需要使用以下条件:

if (str != null &8 str.1ength() != 0)

首先要检查str不为null。在第4章会看到,如果在一个null值上调用方法,会出现错误。

3.6.6 码点与代码单元

Java字符串由char值序列组成。一个char即一个代码单元。

char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元。

大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

String.length(); //返回采用UTF-16编码表示的给定字符串所需要的代码单元数量。

要想得到实际的长度,即码点数量,可以调用:

int cpCount = greeting .codePointCount(0, greeting.length());

调用s.charAt(n)将返回位置n的代码单元,n介于0 ~ s.length)-1 之间。例如:

char first = greeting.charAt(0); // first is 'H'

char last = greeting.charAt(4); // last is '0'

要想得到第i个码点,应该使用下列语句

int index = greeting .offsetByCodePoints(0, i);

int cp = greeting.codePointAt(index);

类似于C和C++,Java 对字符串中的代码单元和码点从0开始计数。

遍历一个字符串,并且依次查看每一个码点,可以使用下列语句:

int[] codePoints = str.codePoints().toArray();

上述使用codePoints方法,它会生成一个int值的“流”,每个int值对应一个码点。 (流将在卷II的第2章中讨论)。可以将它转换为一个数组(见3.10节),再完成遍历。

反之,要把一个码点数组转换为一个字符串,可以使用构造函数(我们将在第4章详细讨论构造函数和new操作符)。

String str = new String(codePoints, 0, codePoints.length);

3.6.7 String API

详见API文档

3.6.8 阅读联机API文档

浏览器指向安装JDK的docs/api/index.html 子目录。

在浏览器中将docs/api/index.html 页面建一个书签。

3.6.9 构建字符串

有些时候,需要由较短的字符串构建字符串,例如,按键或来自文件中的单词。采用字符串连接的方式达到此目的效率比较低。每次连接字符串,都会构建一个新的String对象,既耗时,又浪费空间。使用StringBuilder类就可以避免这个问题的发生。

用许多小段的字符串构建一个字符串,那么应该按照下列步骤进行:

//1、构建一个空的字符串构建器

StringBuilder builder = new StringBuilder();

//2、调用append()添加内容

builder.append(ch);

//3、使用toString()构建字符串

String completedString = builder.toString();

3.7 输入输出

3.7.1 读取输入

要想通过控制台进行输入,首先需要构造一个Scanner对象,并与“标准输入流” System.in 关联。

Scanner in = new Scanner(System.in);

现在,就可以使用Scanner类的各种方法实现输入操作了。例如,nextLine方法将输入一行。

System.out.print("What is your name? ");

//输入行中有可能包含空格

String name = in.nextline();

//String name = in.next(); //读取一个单词(以空白符作为分隔符)

//String name = in.nextInt(); //读取整数

Scanner类定义在java.util包中。必须在.java文件开头包含import java.util.*

因为输入是可见的,所以Scanner类不适用于从控制台读取密码。而Console类可以实现这个目的。要想读取一个密码,可以采用下列代码:

// 读取一个密码

Console cons = System. console();

String username = cons, readLine("User name:" ) ;

//为了安全起见,返回的密码存放在一维字符数组中,而不是字符串中。

//在对密码进行处理之后,应该马上用一个填充值覆盖数值元素

char[] passwd = cons. readPassword(" Password: ");

采用Console对象处理输入不如采用Scanner方便。每次只能读取一行输入,而没有

能够读取一个单词或一个数值的方法。

3.7.2 格式化输出

9d703d9c9c4d7e119a6c7947bccf582f.png

ede6d545dda2de03e8d947522c8ede6f.png

d4cb66da88b244181520d57e72acb820.png

3.7.3 文件输入与输出

要想对文件进行读取,就需要一个用File对象构造一个Scanner对象,如下所示:

Scanner in = new Scanner(Paths.get("myfile.txt"), "UTF-8");

如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加一个额外的反斜杠:

”c:\mydirectory\myfile.txt”

要想写入文件,就需要构造一个PrintWriter对象。在构造器中,只需要提供文件名:

PrintWriter out = new PrintWriter("myfile.txt", "UTF-8");

3.8 控制流程

3.8.1 块作用域

块(即复合语句)是指由一对大括号括起来的若干条简单的Java语句。

块确定了变量的作用域。

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

不能在嵌套的两个块中声明同名的变量。

3.8.2 条件语句

3.8.3 循环

while

do while

3.8.4 确定循环

for

如果在for语句内部定义一个变量,这个变量就不能在循环体之外使用。

for循环语句只不过是while循环的一种简化形式。

3.8.5 多重选择:switch语句

3.8.6 中断控制流程语句

break

带标签的break:跳出多重嵌套的循环语句。

read_data: //标签必须放在希望跳出的最外层循环之前,并且必须紧跟一个冒号。

{//循环

code...

break read_data;

}

continue:将控制转移到最内层循环的首部。(带标签的continue语句,将跳到与标签匹配的循环首部。)

如果将continue;语句用于for循环中,就可以跳到for循环的“更新”部分(即++部分)

3.9 大数值

java.math包中:BigInteger和BigDecimal。这两个类可以处理包含任意长度数字序列的数值。

BigInteger:实现了任意精度的整数运算;

BigDecimal:实现了任意精度的浮点数运算。

不能使用算数运算符(+、- and so on)处理大数值。只能使用特定的方法:

add

substract

multiply

divide

compareTo

valueOf //将普通的数值-->大数值

3.10 数组

int[] a; //声明 or int a[];

int[] a = new int[n]; //创建数组,长度为n,下标从0开始

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

数组列表(arraylist):在运行过程中扩展数组的大小。

3.10.1 for each循环

依次处理数组中的每个元素(其他类型的元素集合亦可)而不必为指定下标值而分心。

这种增强的for循环的语句格式为:

//collection这一集合表达式必须是一个数组或者是一个实现了Iterable 接口的类对象

for (variable : collection) statement

//打印数组中的所有值

Arrays.toString();

3.10.2 数组初始化以及匿名数组

//1、创建数组对象并同时赋予初始值

int[] smallPrimes = { 2,3, 5, 7, 11, 13};

//2、匿名数组

new int[] { 17, 19, 23, 29, 31, 37 }

// 使用上述这种语法形式可以在不创建新变量的情况下重新初始化一个数组。

smallPrimes = new int[] { 17, 19, 23, 29, 31, 37 };

// 这是下列语句的简写形式:

int[] anonymous = { 17, 19, 23, 29, 31, 37 };

smallPrimes = anonymous;

Java中,允许数组长度为0。数组长度为0与null不同。

3.10.3 数组拷贝

// 拷贝

int[] 1uckyNumbers = smallPrimes;

luckyNumbers[5] = 12; // now smal1Primes[5] is also 12

//如果希望将一个数组的所有值拷贝到一个新的数组中去就要使用Arrays类的copyOf()方法

//第2个参数是新数组的长度。

int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers,1uckyNumbers.length);

//这个方法通常用来增加数组的大小:

1uckyNumbers = Arrays.copyOf(1uckyNumbers, 2 *luckyNumbers.1ength);

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

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

//不同于

int a[100]; // C++

//而等同于

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

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

3.10.4 命令行参数

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

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,")

// print the other command-line arguments

for (int i = 1; i < args.length; i++)

System.out,print(" " + args[i]);

System.out.println("!");

}

}

如果使用下面这种形式运行这个程序:

java Message -g cruel world

args数组将包含下列内容:

args[0]: "-g"

args[1]: "cruel'

args[2]: "world"

这个程序将显示下列信息:

Goodbye, cruel world!

在Java应用程序的main方法中,程序名并没有存储在args数组中。例如,当使用下列命令运行程序时java Message -h world,

args[0]是“-h”, 而不是“ Message”或“java ”。

3.10.5 数组排序

//sort使用了优化的快速排序算法。快速排序对大多数数据集合来说都是效率比较高的。

sort()

binarySearch() //二分法搜索算法

fill() //将数组的所有数据元素设为v

3.10.6 多维数组

数组的数组

//声明

double[][] balances;

//初始化1

balances = new double[NYEARS][NRATES];

//初始化2

int[][] magicSquare =

{

{16,3, 2, 13},

{5, 10,11, 8},

{9,6,7,12},

{4, 15, 14, 1}

};

//快速地打印一个二维数组的数据元素列表,可以调用:

Systerm.out.print1n(Arrays.deepToString(a));

//输出格式为:

[[16, 3, 2, 13], [5, 10, 11, 8],[9, 6, 7, 12],[4, 15, 14, 1]

3.10.7 不规则数组

数组的每一行有不同的长度。

//创建不规则数组

//1.首先分配一个具有所含行数的数组

int[] odds = new int[NMAX + 1][];

//2.接下来,分配这些行。

for (int n =0; n <= NMAX; n++)

odds[n] = new int[n + 1];

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值