Java学习-基本的程序设计结构

Evernote Export
一、Java中所有的浮点数值计算都遵循IEEE754规范,有三个特殊的表示溢出和出错的特殊浮点值:正无穷大Double.POSITIVE_INFINITY;负无穷大Double.NEGATIVE_INFINITY;NaN(不是一个数字)Double.NaN。实际应用中很少遇到,检查一个特定值是否是NaN不能这样:
if(x==Double.NaN)//is never true
所有非数值的值都认为是不懂的,可以使用 Double.isNaN方法
if(Double.isNaN(x))

二、浮点数值不适合禁止出现舍入误差的金融计算,主要原因浮点数是采用二进制系统表示,而在二进制系统中无法精确的表示分数1/10。如果需要在数值计算中不含有舍入误差,就应该使用BigDecimal类。

三、从JDK5.0以来,代码点是指与一个编码表中的某个字符对应的代码值。在Unicode标准 中代码点采用十六进制书写,并加上U+前缀。Unicode的代码点可以分为17个代码级别。第一个代码级别称为”基本的多语言级别“。代码点从U+0000到U+FFFF,其余的16个附加级别,代码点从U+10000到U+10FFFF,其中包括一些辅助字符。UTF-16编码采用不同长度的编码表示所有Unicode代码点,在基本的多语言级别中,每个字符使用16位表示,通常称为代码单元,而辅助字符采用一对连续的代码单元表示。这样构成的编码一定落在基本的多语言级别中空闲的2048字节内,通常被称为”替代区域“[U+D800~U+DBFF用于第一个代码单元;U+DC00~U+DFFF用于第二个代码单元]。这样的设计可以从中迅速知道一个代码单元是一个字符的编码,还是一个辅助字符的第一或者第二部分。

四、Java中,利用 关键字final声明常量。

五、对于浮点数的算术运算,实现可移植性是相当困难的,double类型使用64位存储一个double数值,而有些处理器用80位的浮点寄存器,这些寄存器增加了中间过程的计算进精度。Java程序设计语言承认了最优性能与理想结果之间存在的冲突,并给予改进,默认情况下,虚拟机设计者允许将中间计算结果采用扩展的精度,但是对于使用 strictfp关键字标记的方法必须使用严格的浮点计算来产生理想的结果。默认情况下,允许使用扩展的指数,不允许使用扩展的尾数,因此这两种方式的区别仅仅在于词用默认的方式不会产生溢出,而采用严格的计算会产生溢出。

六、自增运算符和自减运算符,前缀方式先加1,后缀方式使用变量原来的值。

七、Java中没有幂运算,借助Math类的pow方法。”double y=Math.pow(x,a)“。Math类提供了一些常用的三角函数: Math.sin、Math.cos、Math.tan、Math.atan、Math.atan2;还有指数函数以及他的反函数-对数: Math.exp、Math.log;Java还提供了两个用于表示Π和e常量的近似数: Math.PI;Math.E.

八、Java字符串就是Unicode字符序列,String类的substring方法可以从i个较大的字符串提取出一个子串,substring方法的第二个参数是不想复制的第一个位置。substring有一个优点,容易计算子串的长度。字符串s.substring(a,b)的长度为b-a。Java语言允许使用+号链接两个字符串。当将一个字符串与一个字符串拼接时,后者被转换成字符串。

九、Java中String类对象称为不可变字符串,编译器可以让字符串共享,Java字符串更像char*指针。检查字符串是否相等
s.equals(t)//s、t相等返回true,否则返回false。s、t可以是字符串常量也可以是字符串变量
一定不能使用==运算符检测两个字符串是否相等,这个字符串只能确定两个字符串是否放置在同一个位置。如果字符串放置在同一个位置上,他们必然相等,但是,完全有可能将内容相同的多个字符串的拷贝放置在不同的位置。如果虚拟机始终将相同的字符串共享,就可以使用==运算符检测是否相等。但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的。

十、字符数据类型是一个采用UTF-16编码表示Unicode代码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。 length 方法将返回采用UTF-16编码表示的给定字符串所需要的 代码单元数量 。要想得到实际的长度,即 代码点数量 ,可以调用 codePointCount() 。调用 s.charAt(n)将返回位置n的代码单元 ,n介于0~s.length()-1之间。要想获得第i个代码点,使用
int index=greeting.offsetBycode(0,i);
int cp=greeting.codePontAt(index);
如果想要遍历一个字符串,并且依次查看每一个代码点,可以使用下列语句
int cp=sentence.codePointAt(i);//codePointAt可以辨别一个代码单元是辅助字符的第一部分还是第二部分,并能够返回正确的结果。
if(Character. isSupplementaryCodePoint(cp))i+=2;//判断i代码点是不是辅助字符
else i++;

字符串API(Java.lang.string)
char charAt(int index)//返回给定位置的代码单元。除非对底层的代码单元感兴趣,否则不需要调用这个方法
int codePointAt(int index)//返回从给定位置开始或结束的代码点
int offsetByCodePoints(int startIndex,int cpCount)//返回从startIndex代码点开始,位移cpCount后的代码点索引
int compareTo(String other)//按照字典顺序,如果字符串位于other之前,返回一个负数;如果字符串位于other之后,返回一个正数;如果两个字符串相等,返回0.
boolean endsWith(String suffix)//如果字符串以suffix结尾,返回true
boolean equals(Object other)//如果字符串与other相等,返回true
boolean equalsIgnoreCase(String other)//如果字符串与other相等,返回true
int indexOf(String str);int indexOf(String str,int fromIndex);int indexOf(int cp);int indexOf(int cp,int fromIndex)//返回与字符串str或代码点cp匹配的第一个子串的开始位置。这个位置从索引0或fromIndex开始计算。如果在原始串中不存在str,返回-1
int lastIndexOf(String str);int lastIndexOf(String str,int fromIndex);int  lastIndexOf(int cp);int lastIndexOp(int cp,int fromIndex)//返回与字符串str或代码点cp匹配的最后一个子串的开始位置。这个位置从原始串尾端或fromIndex开始计算。
int length()//返回字符串的长度
int codePointCount(int startIndex,int endIndex)//返回startIndex和endIndex-1之间的代码点数量。没有配成对的待用字符将计入代码点
String replace(CharSequence oldString,CharSequence newString)//用newString来代替oldString,返回一个新字符串,可以用string、stringBuilder作为参数
boolean startsWith(String prefix)//如果以prefix开始返回true
String substring(int beginIndex);String substring(int beginIndex,int endIndex)//返回一个新字符串。这个字符串包含原始字符串中从beginIndex到串尾或endIndex-1的所有代码单元
String toLowerCase()//返回一个新字符串,将源字符串所有大写改成小写
String toUpperCase()//返回一个新字符串,这个字符串将小写改成大写
String trim()//返回新字符串,删除了头部和尾部的空格

十一、需要有较短的字符串构建字符串,采用字符串链接的方式效率低,因为每次链接,会构建一个新的String对象,又消耗时间,又浪费空间,使用 StringBuilder可以避免这样的问题发生。如果需要用许多小段的字符串构建一个字符串,那么应该按照下列步骤进行。 首先,构建一个空的字符串构建器:”StringBuilder builder= new StringBuilder()“。当 每次需要添加一部分内容时,就调用append方法。”builder.append(ch);builder.append(str)“在需要 构建字符串时就调用toString方法,将可以得到的一个String对象,其中包括了构建器中的字符序列。”String completedString=builder.toString();“。这个类的前身是StringBuffer,其效率有些低,但允许采用多线程的方式执行添加或删除字符的操作。

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

十二、标准输入流:System.in;标准输出流:System.out。要想通过控制台进行输入,首先需要构造一个Scanner对象,并与”标准输入流“关联。
Scanner in = new Scanner(System.in);
Scanner类不适用于从控制台读取密码,java se6引入了console类来实现这个目的
Console cons=System.console();
String username=cons.readLine("User name:");
char[] passwd= cons.readPassword("password:");

API(Java.util.scanner)
Scanner(InputStream in)//创建一个Scanner对象
String nextLine()//读取下一行的内容
String next()//读取输入的下一个单词
int nextInt()
double nextDouble()//读取并转换下一个表示整数或浮点数的字符序列
boolean hasNext()//检测输入是否还有其他单词
boolean hasNextInt()
boolean hasNextDouble()//检测是否还有表示整数或浮点数的下一个字符序列
API(Java.lang.System)
stitic console()//如果有可能进行交互操作,就通过控制台窗口为监护的用户返回一个Console对象,否则返回null。对于任何一个通过控制台窗口启动的程序,都可以使用Console对象。否则,其可用性将与所使用的系统有关
API(Java.io.Console)
static char[] readPassword(String prompt,Object ...args)
static String readLine(String prompt,Object...args)//显示字符串prompt并且读取用户输入,知道输入行结束。arg参数可以用来提供输入格式。

十三、
用于printf的转换

d
十进制整数
x
十六进制整数
o
八进制整数
f
定点浮点数
e
指数浮点数
g
通用浮点数
a
十六进制浮点数
s
字符串
c
字符
b
布尔
h
散列码
tx
日期时间
%
百分号
n
与平台有关的行分割符




用于printf的标志

+
打印正负数的符号
空格
在正数之前添加空格
0
数字前面补0
-
左对齐
将负数括在括号内
添加分组分隔符
#(对于f格式)
包含小数点
#(对于x或0格式)
添加前缀0x或0
$
给定被格式化的参数索引
<
格式化前面说明的数值




对于实现了Formattable接口的对象都将掉哦那个formatTo方法;否则将调用toString方法,它将兑现转换成字符串。可以使用静态的String.format方法创建一个格式化的字符串,而不打印输出。

时间日期转换符

c
完整的日期和时间
F
ISO 8601日期
D
美国格式的日期(月/日/年)
T
24小时时间
r
12小时时间
R
24小时时间没有秒
Y
4位数字的年
y
年的后两位
C
年的前两位
B
月的完整拼写
b或h
月的缩写
m
两位数字的月
d
两位数字的日
e
两位数字的月(前面不补0)
A
星期几的完整拼写
a
星期几的缩写
j
三位数的年中的日子
H
两位数的小时
k
两位数的小时(前面不补0)
I
两位数的小时(0~12)
l
两位数字的小时(0~12,不补0)
M
两位数字的分钟
S
两位数字的秒
L
三位数的毫秒
N
九位数的毫微秒
P
上午或下午的大写标志
p
上午或下午的小写标志
z
从GMT起,RFC822数字位移
Z
时区
s
从格林威治时间起的秒数
Q
从格林威治时间起的毫秒数


可以采用-一个格式化的字符串指出要被格式化的参数索引,索引必须 跟在%后,并以$为终止 ”System.out.println("%1$s %2$tB %2$te %2$tY","Due date:",new Date());“

十四、要想 对文件进行读取,就需要一个 用File对象构造一个Scanner对象”Scanner in = new Scanner(new File("myfile.txt"));“。如果文件名中有反斜杠,要在之前再加一个反斜杠,要 想写入文件,就需要 构造一个PrintWriter对象。当指定一个相对文件名时,文件位于java虚拟机启动路径的相对位置。如果在命令行方式下用”java Myprog“来启动程序,启动路径就是命令解释器的当前路径。可以使用
String dir = System.getProperty("user.dir");
找到路径的位置。

API(Java.util.Scanner)
Scanner(File f)
Scanner(String data)//构造一个从给定字符串读取数据的Scanner
API(java.io.PrintWriter)
PrintWriter(File f)
PrintWriter(String fileName)//构造一个将数据写入给定文件的PrintWriter
API(java.io.File)
File(String filename)//用指定文件名构造File对象

十五、Java提供了一种带标签的break语句,标签必须放在希望跳出的最外层循环之前,并且紧跟一个:号

十六、如果基本的整数和浮点数精度不能满足要求,可以使用java.math包中的两个很有用的类:BigInteger和BigDecimal。这两个类可以处理包含任意长度数字序列的数值。BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。使用静态的valueOf方法可以将普通的数值转换为大数值:BigInteger a = BigInteger.vauleOf(x);不过不能用算术运算符来处理大数值。
API(java.math.BigInteger)
BigInteger add(BigInteger other)
BigInteger subtract(BigInteger other)
BigInteger multiply(BigInteger other)
BigInteger divide(BigInteger other)
BigInteger mod(BigInteger other)
int compareTo(BigInteger other)//相等返回0,小于返回负数
static BigInteger valueOf(long x)
API(java.math.BigDecimal)
BigDecimal add(BigDecimal other)
BigDecimal subtract(BigDecimal other)
BigDecimal multiply(BigDecimal other)
BigDecimal divide(BigDecimal other,RoundingMode mode)//roundingMode是舍入方式,RoundingMode.HALF_UP是四舍五入方式
int compareTo(BigDecimal other)
static BigDecimal valueOf(long x)
static BigDecimal valueOf(long x,int scale)//返回值为x或x/10^scale的一个大实数

十七、用new创建数组,要想获得数组中的元素个数,可以使用array.length。
十八、for(variable:collection)statement。collection这一集合表达式必须是一个数组或者实现了 Iterable接口的类对象。有个比较简单的方式打印数组中的数值,利用Arrays类的toString方法。 调用Arrays.toString(a)返回一个包含数组元素的字符串。如果要拷贝一个数组,用 Arrays类的copyOf方法。对数组进行排序,可以用 Arrays类中的sort方法,该方法使用了优化的快速排序算法,这个算法对于大多数数据集合效率比较高。

API(java.util.Arrays)
static String toString(type[] a)
static type copyOf(type[] a,int length)
static type copyOf(type[] a,int start,int end)//返回与a类型相同的一个数组,其长度为length或者end-start,数组元素为a的值
static void sort(type[] a)
static int binarySearch(type[] a,type v)
static int binarySearch(type[] a,int start,int end,type v)//采用二分搜索查找法找v,找到返回下标志,否则返回一个负数值r。r-1为v应该插入的位置
static void fill(type[] a ,type v)//将数组的所有数据都设置为v
static boolean equals(type[] a,type[] b)//如果两个数组大小相同,并且下标相同的元素都对应相等
API(java.lang.System)
static void arraycopy(Object from,int fromIndex,Object to,int toIndex,int count)//将第一个数组中的元素拷贝到第二个数组中

十九、for each循环语句不能自动处理二维数组的每一个元素。他是按照行,也就是一维数组处理的,要想访问二维数组a的所有元素,需要使用两个嵌套的循环
for(double[] row:a)
    for(double value:row)
        do something with value
要想快速打印一个二维数组的数据元素列表,可以调用
System.out.println(Arrays.deepToString(a));

猜你喜欢

转载自blog.csdn.net/Han_L/article/details/87797968