第3章 Java的基本程序设计结构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NCUscienceZ/article/details/83315226

1、下面是用于表示溢出和出错情况的三个特殊的浮点数值 :
• 正无穷大
• 负无穷大
• NaN
( 不是一个数字 )
例如 , 一 正整数除以 0 的结果为正无穷大 。 计算 0 / 0 或者负数的平方根结果为 NaN 。

2、常量 Double _ POSITIVE _ INFINITY 、 Double . NEGATIVEJNFINITY 和 Double . NaN
( 以及相应的 Float 类型的常量 ) 分别表示这三个特殊的值,但在实际应用中很少遇到 。
特别要说明的是 , 不能这样检测一个特定值是否等于 Double . NaN :
if ( x = Double . NaN ) / / is never true
所有 “ 非数值 ” 的值都认为是不相同的 。
然而 , 可以使用 Double . isNaN 方法 :
if ( Double . isNaN ( x ) ) / / check whether x is " not a number "

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

4、char 类型的值可以表示为十六进制值, 其范围从 \ u 0000 到 \ Uffff。

5、 C++注释:在 C + + 中 , 数值甚至指针可以代替 boolean 值。 值 0 相当于布尔值 false ,非0 值相当于布尔值 true , 在 Java 中则不是这样 , 因此, Java 程序员不会遇到下述麻烦 :
if ( x = 0 ) / / oops . … meant x = 0
在 C + + 中这个测试可以编译运行,其结果总是 false : 而在 Java 中 , 这个测试将不
能通过编译, 其原因是整数表达式 x = 0 不能转换为布尔值 。

6、 强制类型转换的语法格式是在圆括号中给出想要转换的目标类型 , 后面紧跟待转换的变量名 。 例如 :
double x * 9.997 ;
int nx = ( int ) x ;
这样 , 变量 nx 的值为 9。 强制类型转换通过截断小数部分将浮点值转换为整型 。
如果想对浮点数进行舍人运算 , 以便得到最接近的整数 ( 在很多情况下 , 这种操作更有用 ), 那就需要使用 Math.round
方法 :
double x z 9.997 ;
int nx = ( int ) Math . round ( x ) ;
现在 , 变量 nx 的值为 10。
当调用 round 的时候 , 仍然需要使用强制类型转换 ( int ) 。 其原因
是 round 方法返回的结果为 long 类型 , 由于存在信息丢失的可能性 , 所以只有使用显式的强制类型转换才能够将 long 类型转换成 int 类型 。

7、另外, 还有 >>和 << 运算符将位模式左移或右移 。 需要建立位模式来完成位掩码时
, 这两个运算符会很方便 :
int fourthBitFromRight = ( n & ( 1 « 3 ) ) » 3 ;
最后,>>> 运算符会用 0 填充高位, 这与 》不同, 它会用符号位填充高位 。 不存在
<<<运算符。

8、字符串专题:
(1)、子串提取:
String 类的 substring 方法可以从一个较大的字符串提取出一个子串 。 例如 :
String greeting = " Hello " ;
String s = greeting . substring ® , 3 ) ;
创建了一个由字符 “ Hel ” 组成的字符串 。substring 方法的第二个参数是不想复制的第一个位置 。 这里要复制位置为 0、 1和 2 ( 从0 到 2 , 包括 0 和 2 ) 的字符。 在 substring 中从 0 开始计数 , 直到 3 为止 , 但不包含 3 。
substring 的工作方式有一个优点 : 容易计算子串的长度 。 字符串 s . substring ( a , b ) 的长度为 b - a。 例如 , 子串 “Hel ” 的长度为 3 - 0 = 3。
(2)、判等:一定不要使用 = 运算符检测两个字符串是否相等 ! 这个运算符只能够确定两个字串
是否放置在同一个位置上 。 当然 , 如果字符串放置在同一个位置上 , 它们必然相等
。 但是 ,
完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上

可以使用 equals 方法检测两个字符串是否相等 。 对于表达式 :
s . equal s ( t )
如果字符串 s 与字符串 t 相等 , 则返回 true ; 否则 , 返回 false。 需要注意 , s 与 t
可以是字符串变量 , 也可以是字符串字面量 。 例如 , 下列表达式是合法的 :
" Hello " . equals ( greeting )
要想检测两个字符串是否相等, 而不区分大小写 , 可以使用 equalsIgnoreCase
方法。
" Hello " . equalsIgnoreCase ( " hello " )
(3)、空串与NULL
空串 " " 是长度为 0 的字符串。 可以调用以下代码检查一个字符串是否为空:
if ( str . lengthQ = 0 )

if ( str . equals ( “” ) )
空串是一个 Java 对象 , 有自己的串长度 ( 0 ) 和内容 ( 空 )。 不过 , String变量还可以存放一个特殊的值 , 名为 null , 这表示目前没有任何对象与该变量关联 。要检查一个字符串是否为 null , 要使用以下条件 :
if ( str = = null )
有时要检查一个字符串既不是 null 也不为空串, 这种情况下就需要使用以下条件 :
if ( str ! = null & & str . lengthO ! = 0 )
首先要检查 str 不为 null。 如果在一个 mull 值上调用方法 , 会出现错误。
(4)、字符串的遍历及码点与代码单元
Java 字符串由 char 值序列组成。 从3.3 . 3 节 “ char 类型 ” 已经看到 , char 数据类型是一个采用 UTF - 16 编码表示 Unicode 码点的代码单元。 大多数的常用 Unicode 字符使用一个代码单元就可以表示 , 而辅助字符需要一对代码单元表示。length 方法将返回采用 UTF - 16 编码表示的给定字符串所需要的代码单元数量 。 例如 :
String greeting = " Hello " ;
int n = greeting . length 。 ; / / is 5 .
要想得到实际的长度, 即码点数量 , 可以调用 :
int cpCount = greeting . codePointCount ( 0 , greeting . lengthQ ) ;
调用 s . charAt ( n ) 将返回位置 n 的代码单元, n介于 0 ~ s . length ( ) - l 之间。 例如 :
char first = greeting . charAtO ) ;//first is ’ H ’
char last = greeting . charAt ( 4 ) ; / / last is ’ o ’
要想得到第 i 个码点, 应该使用下列语句
int index = greeting . offsetByCodePoints ( 0 , i ) ;
int cp = greeting . codePointAt ( index ) ;
(5)、java String API
API java . lang . string 1.0

  • char charAt ( int index )
    返回给定位置的代码单元。 除非对底层的代码单元感兴趣 ,否则不需要调用这个方法。
  • intcodePointAt ( int Index ) 5.0
    返回从给定位置开始的码点。
  • int offsetByCodePoints ( int startlndex , int cpCount ) 5.0
    返回从 startlndex 代码点开始, 位移 cpCount 后的码点索引 。
  • int compareTo ( String other )
    按照字典顺序, 如果字符串位于 other 之前 , 返回一个负数 ; 如果字符串位于other 之后, 返回一个正数 ; 如果两个字符串相等 , 返回0。
  • IntStream codePoints ( ) 8
    将这个字符串的码点作为一个流返回。 调用 toArray 将它们放在一个数组中 。
  • new String ( int [ ] codePoints , int offset , int count ) 5.0
    用数组中从 offset 开始的 count 个码点构造一个字符串。
  • boolean equals ( 0 bject other )
    如果字符串与 other 相等 , 返回 true。
  • boolean equalsIgnoreCase ( String other )
    如果字符串与 other 相等 ( 忽略大小写 ), 返回 true 。
  • boolean startsWith ( String prefix )
  • boolean endsWith ( String suffix )
    如果字符串以 suffix 开头或结尾 , 则返回 true。
  • int indexOf ( String str )
  • int indexOf ( String str , int fromlndex )
  • int indexOf ( int cp )
  • int indexOf ( int cp , int fromlndex )
    返回与字符串 str 或代码点 cp 匹配的第一个子串的开始位置。 这个位置从索引0 或fromlndex 开始计算 。 如果在原始串中不存在 str , 返回 - 1。
  • int lastIndexOf ( String str )
  • Int lastIndexOf ( Stri ng str , int fromlndex )
  • int lastindexOf ( int cp )
  • int lastindexOf ( int cp , int fromlndex )
    返回与字符串 str 或代码点 cp 匹配的最后一个子串的开始位置 。 这个位置从原始串尾端或 fromlndex 开始计算。
  • int length ( )
    返回字符串的长度 。
  • int codePointCount ( int startlndex , int endlndex ) 5.0
    返回 startlndex 和 endludex - l 之间的代码点数量。 没有配成对的代用字符将计入代码点 。
  • String replace ( CharSequence oldString , CharSequence newString )
    返回一个新字符串。 这个字符串用 newString代替原始字符串中所有的 oldString
    。 可以用 String 或 StringBuilder 对象作为 CharSequence 参数 。
  • String substring ( int beginlndex )
  • String substring ( int beginlndex , int endlndex )
    返回一个新字符串。 这个字符串包含原始字符串中从beginlndex 到串尾或 endlndex - 1的所有代码单元。
  • String toLowerCase ( )
  • String toUpperCase ( )
    返回一个新字符串 。 这个字符串将原始字符串中的大写字母改为小写 , 或者将原始字符串中的所有小写字母改成了大写字母。
  • String trim( )
    返回一个新字符串。 这个字符串将删除了原始字符串头部和尾部的空格 。
  • String join ( CharSequence delimiter , CharSequence . … elements ) 8
    返回一个新字符串 , 用给定的定界符连接所有元素 。
    (6)、构建字符串:
    有些时候 , 需要由较短的字符串构建字符串 , 例如 , 按键或来自文件中的单词。 采用字符串连接的方式达到此目的效率比较低。 每次连接字符串 ,都会构建一个新的 String 对象 ,既耗时 , 又浪费空间。 使用StringBuildei 类就可以避免这个问题的发生。
    如果需要用许多小段的字符串构建一个字符串 , 那么应该按照下列步骤进行 。 首先 , 构建一个空的字符串构建器 :
    StringBuilder builder = new StringBuilderO ;
    当每次需要添加一部分内容时 , 就调用 append 方法 。
    builder . append ( ch ) ; / / appends a single character
    bui 1 der . append ( str ) ; / / appends a string
    在需要构建字符串时就凋用 toString 方法 , 将可以得到一个 String 对象 , 其中包含了构建器中的字符序列 。
    String completedString = builder . toStringO ;
    注释 : 在 JDK 5.0 中引入 StringBuilder 类 。 这个类的前身是 StringBuffer ,
    其效率稍有些低,但允许采用多线程的方式执行添加或删除字符的操作 U 如果所有字符串在一个单线程中编辑 ( 通常都是这样 ),则应该用 StringBuilder 替代它 。 这两个类的 AP 丨是相同的 。
    (7)重中之重的java StringBuilder API(可以直接对其增删改)
    •StringBuilder ()
    构造一个空的字符串构建器。
    •int length ( )
    返回构建器或缓冲器中的代码单元数量。
    • StringBuilder appencl ( Stri ng str )
    追加一个字符串并返回 this。
    •StringBuilder append ( char c )
    追加一个代码单元并返回 this。
    •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 endlndex )
    删除偏移量从 startindex 到 - endlndex - 1 的代码单元并返回 this。
    •String toString ( )
    返回一个与构建器或缓冲器内容相同的字符串

9、标准流输入(关于缓冲区回车问题稍后再研究):
API java . util . Scanner 5.0

•Scanner ( InputStream in )
用给定的输人流创建一个 Scanner 对象。
•String nextLine ( )
读取输入的下一行内容。
•String next ( )
读取输入的下一个单词 ( 以空格作为分隔符 )。
•int nextlnt ( )
•double nextDouble ( )
读取并转换下一个表示整数或浮点数的字符序列 。
•boolean hasNext ( )
检测输人中是否还有其他单词。
•boolean hasNextInt ( )
•boolean hasNextDouble ( )
检测是否还有表示整数或浮点数的下一个字符序列 。

10.格式化输出(关于格式化输出与字符串高级处理部分,部分此书讲的并不足够详细,稍后自己扩展。):
(1)、非常庆幸java SE5.0以后沿用了C语言的printf()格式化控制输出手段。
(2)、可以使用 s 转换符格式化任意的对象 , , 对于任意实现了 Formattable 接口的对象都将调用 formatTo 方法 ; 否则将调用 toString 方法 , 它可以将对象转换为字符串 。

11、java时间类与文件暂时先略。

12、高精度福音,java大数值类:
(1)、 那么可以使用 java . math 包中的两个很有用的类 : Biglnteger 和 BigDecimaL 这两个类可以处理包含任意长度数字序列的数值。Biglnteger 类实现了任意精度的整数运算 , BigDecimal 实现了任意精度的浮点数运算 。
(2)、使用静态的 valueOf 方法可以将普通的数值转换为大数值 :
Biglnteger a = Biglnteger . valueOf ( 100 )
(3)、遗憾的是, 不能使用人们熟悉的算术运算符 ( 如 : + 和 *) 处理大数值。
而需要使用大数值类中的 add 和 multiply 方法 。
Biglnteger c = a . add ( b ) ; / / c = a + b
Biglnteger d = c . nultipiy ( b . add ( Biglnteger . valueOf ( 2 ) ) ) ; // d = c * ( b + 2 )
(4)、java 大数值类API:
API java . math . Biglnteger 1.1
•Biglnteger add ( Biglnteger other )
•Biglnteger subtract ( Biglnteger other )
•Biglnteger multipiy ( Biginteger other )
•Biglnteger divide ( Biglnteger other )
•Biglnteger mod ( Biglnteger other )
返冋这个大整数和另一个大整数 other的和、 差 、积 、 商以及余数 。
•int compareTo ( Biglnteger other )
如果这个大整数与另一个大整数 other 相等 , 返回 0 ; 如果这个大整数小于另一个大整数 other , 返回负数 ; 否则 , 返回正数 。
•static Biglnteger valueOf ( long x )
返回值等于 x 的大整数 。

API java . math . BigDecimal 1.1
•BigDecimal add ( BigDecimal other )
•BigDecimal subtract ( BigDecimal other )
•BigDecimal multipiy ( BigDecimal other )
•BigDecimal divide ( BigDecimal other RoundingMode mode ) 5.0
返回这个大实数与另一个大实数 other 的和 、 差 、 积 、 商。 要想计算商 ,
必须给出舍入方式 ( rounding mode )。 RoundingMode . HALF_UP 是在学校中学习的四舍五入方式( 即 , 数值 0 到 4 舍去, 数值5 到 9 进位 )。 它适用于常规的计算 。 有关其他的舍入方式请参看 ApI 文档。
•int compareTo ( BigDecimal other )
如果这个大实数与另一个大实数相等 , 返回 0 ; 如果这个大实数小于另一个大实数 ,
返回负数 ; 否则, 返回正数 。
•static BigDecimal valueOf ( long x )
•static BigDecimal valueOf ( long x , int scale )
返回值为 X 或 x / 10 scale 的一个大实数 。

13、数组:
(1)、代码风格:可以使用下面两种形式声明数组
int [] a ;

int a [] ;
大多数 Java 应用程序员喜欢使用第一种风格
,因为它将类型 int [] ( 整型数组 ) 与变量名分开了 。
(2)、数组初始化:创建一个数字数组时 , 所有元素都初始化为 0。 boolean 数组的元素会初始化为false, 对象数组的元素则初始化为一个特殊值 null , 这表示这些元素还未存放任何对象。 初学者对此可能有些不解。 例如 ,
String [ ] names = new String [ 10 ] ;
会创建一个包含 10 个字符串的数组 , 所有字符串都为 null。 如果希望这个数组包含空串 , 可以为元素指定空串 :
for ( int i = 0 ; i < 10 ; i + + ) names [ i ] = “”;
(3)、for each循环:
for ( int element : a )
System . out . println ( element ) :
打印数组 a 的每一个元素 , 一个元素占一行。
(4)、数组拷贝:
在 Java 中, 允许将一个数组变量拷贝给另一个数组变量。 这时 ,两个变量将引用同一 个数组 :
int[ ] luckyNumbers = small Primes ;
luckyNumbers [ S ] = 12 ; // now small Primes [ 5 ] is also 12
如果希望将一个数组的所有值拷贝到一个新的数组中去 ,就要使用 Arrays 类的 copyOf 方法 :
int [ ] copiedLuckyNumbers = Arrays . copyOf ( luckyNumbers , luckyNumbers . length ) ;
第 2 个参数是新数组的长度 。 这个方法通常用来增加数组的大小 :
luckyNumbers = Arrays . copyOf ( luckyNumbers , 2 * luckyNumbers . length ) ;
如果数组元素是数值型, 那么多余的元素将被赋值为 0 ;
如果数组元素是布尔型, 则将赋值为 false。 相反 , 如果长度小于原始数组的长度 , 则只拷贝最前面的数据元素 。
(5)、数组排序:
要想对数值型数组进行排序 , 可以使用 Arrays 类中的 sort 方法 :
int [] a = new int [ 10000 ] ;
Arrays . sort ( a )
这个方法使用了优化的快速排序算法。
(6)、重中之中的数组API
•static String toString ( type [] a ) 5.0
返回包含 a 中数据元素的字符串 , 这些数据元素被放在括号内 , 并用逗号分隔 。
参数 : a 类型为 int 、 long、 short 、 char 、 byte 、 boolean 、 float或 double 的数组。
•static type copyOf ( type [] a , int length ) 6
• static type copyOfRange ( type [] a , int start , int end ) 6
返回与 a 类型相同的一个数组 , 其长度为 length 或者 end - start , 数组元素为 a 的值。
参数 :
a 类型为 int 、 long 、 short 、 char 、 byte、 boolean 、 float或 double 的数组。
start 起始下标 ( 包含这个值 )。
end 终止下标 ( 不包含这个值 )。 这个值可能大于a . length。 在这种情况下 , 结果为 0 或 false。
length 拷贝的数据元素长度 c 如果 length 值大于 a . length , 结果为 0 或 false ;否则 ,数组中只有前面 length 个数据元素的拷贝值。
• static void sort ( type [ 2 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 ) 6
采用二分搜索算法查找值 v。 如果查找成功 ,则返回相应的下标值 ; 否则 , 返回一个
负数值 r。 - r - 1是为保持 a 有序 v 应插入的位置。
参数 :
a 类型为 int 、 long 、 short 、 char 、 byte 、 boolean 、 float 或 double 的有序数组。
start 起始下标 ( 包含这个值 )。
end 终止下标 ( 不包含这个值 )。
v 同 a 的数据元素类型相同的值。
•static void fi 11 ( 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 的两个数组 。

14、java随机数生成:
Math . rand 0 m 方法将返回一个0 到 1 之间 ( 包含 0、不包含 1 ) 的随机浮点数。 用
乘以这个浮点数 , 就可以得到从 0 到 n - l 之间的一个随机数。
int r = ( int ) ( Math . random 0 * n ) ;

15、java多维数组本质“数组的数组”:
Java 实际上没有多维数组, 只有一维数组 。 多维数组被解释为 “ 数组的数组 。
balances = new double [ NYEARS ][ NRATES ] :
表达式 balancesf[ i ] 引用第 i 个子数组, 也就是二维表的第i 行 。 它本身也是一个数组 ,
balances [ i ] [ j ] 引用这个数组的第 j 项 。
由于可以单独地存取数组的某一行 , 所以可以让两行交换。
doubleQ temp = balances [ i ] :
balances [ i ] = balances [ i + 1 ] ;
balances [ i + 1 ] = temp ;

16、C + + 注释 :
在 C + + 中 , Java 声明
doublet [ ][ ] balances = new double [ 10 ] [ 6 ] ; // 3 ava
不同于
double balances [ 10 ] [ 6 ] ; / / C + +
也不同于
double ( * balances ) [ 6 ] = new double [ 10 ] [ 6 ] ; / / C + +
而是分配了一个包含 10 个指针的数组 :
double * * balances = new double * [ 10 ] ; // C + +
然后 , 指针数组的每一个元素被填充了一个包含 6 个数字的数组 :
for ( i = 0 ; i < 10 ; i + + )
balances [ i ] = new double [ 6 ] ;
庆幸的是 , 当创建 new double [ 10 ][ 6 ] 时 , 这个循环将自动地执行 。
当需要不规则的数组时 , 只能单独地创建行数组 。

猜你喜欢

转载自blog.csdn.net/NCUscienceZ/article/details/83315226