“核心技术:基本程序设计结构”的版本间差异

来自Wikioe
跳到导航 跳到搜索
第323行: 第323行:
String completedString = builder.toString();
String completedString = builder.toString();
</syntaxhighlight>
</syntaxhighlight>


* 在 JDK 5.0 中引入了 StringBuilder 类,其前身是 StringBuffer(其效率稍低,但允许多线程执行),如果所有字符串在一个单线程中编辑,则应该使用 StringBuilder。
* 在 JDK 5.0 中引入了 StringBuilder 类,其前身是 StringBuffer(其效率稍低,但允许多线程执行),如果所有字符串在一个单线程中编辑,则应该使用 StringBuilder。

2020年10月16日 (五) 14:13的版本


数据类型

类型 存储需求 默认值 取值范围
整型
int 4字节 0 -2 147 483 648 - 2 147 483 647
  1. Integer.MIN_VALUE=-2147483648
  2. Integer.MAX_VALUE=2147483647
short 2字节 0 -32 768 - 32767
  1. Short.MIN_VALUE=-32768
  2. Short.MAX_VALUE=32767
long 8字节 0L -9 223 372 036 854 775 808 - 9 223 372 036 854 775 807
  1. Long.MIN_VALUE=-9223372036854775808
  2. Long.MAX_VALUE=9223372036854775807
byte 1字节 0 -128 - 127
  1. Byte.MIN_VALUE=-128
  2. Byte.MAX_VALUE=127
浮点
float 4字节 0.0f 大约 +- 3.402 823 47E+38F(有效位数为6、7位)
  1. Float.MIN_VALUE=1.4E-45
  2. Float.MAX_VALUE=3.4028235E38
double 8字节 0.0d 大约 +- 1.797 693 134 862 315 70E+308(有效位数为15位)
  1. Double.MIN_VALUE=4.9E-324
  2. Double.MAX_VALUE=1.7976931348623157E308
字符
char 2字节 'u0000' \u0000 - \uffff
布尔
boolean 1位 false true | false
  • 常量“Double.POSITIVE_INFINITY”、“Double.NEGATIVE_INFINITY”、“Double.NAN”分别表示“正无穷大”、“负无穷大”、“NaN(不是一个数字)”;

取值范围

  • 整数用原码,负数用补码表示

以int为例,在java中占4字节,即32位:

  1. 其中第一位为符号位(0正,1负)
  2. 所以负数范围为:-2^31 = -2147483648
  3. 整数的范围为:2^31-1 = 2147483647 (减去全为0时的情况,0无正负)

即:-2147483648 - 2147483647 (-2^31 — 2^31-1)

关于0.2 + 0.1 不等于 0.3

使用自然类型计算小数的时候,会出现:“0.2+0.1=0.30000000000000004”,而“0.1+0.6=0.7”的情况:

小数计算1.jpg
小数计算2.jpg

其原因如下:

计算机存储、计算或者展示,都需要转换2进制。

在现实世界中,数字主要有整数和小数两种,整数包括正整数、负整数以及零。
计算机中表示整数的方式有很多,如原码、反码以及补码等。

在计算机中存储的整数则分为有符号数和无符号数。
对于无符号数,采用哪种编码方式都无所谓,对于有符号数的编码方式,常用的是补码。

那么,一个十进制数字想要获得其二进制的补码,需要先通过一定的算法得到他对应的原码。
  1. 十进制整数转换为二进制,可以采用“除2取余,逆序排列”,或者xxx法(列出“...128,64,32,26,8,4,2,1”,根据十进制数在对应位置1或0);
  2. 十进制小数转换为二进制:则采用“乘2取整,顺序排列”的方法;

如,0.625的二进制转换如下:
0.625的二进制.jpg
而0.1的二进制:
0.1的二进制.jpg
可以得知:0.1的二进制转换中出现了无限循环的情况,也就是(0.1)10 = (0.000110011001100…)2,而不能把0.1转换为确定的二进制数
计算机无法用二进制精确的表示0.1


IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)

但仅是用近似值表示小数,并非真实值,如果使用float、double等类型进行小数计算,仍然会丢失数值。并没有解决问题。
所以:为了解决这样的精度问题,Java中提供了BigDecimal来进行精确运算。

  • BigDecimal 并不是Java的数据类型,而是一个Java对象!

变量

  • 变量名:以字母开头,并由字母和数字构成的序列;(字母包括:'A'-'Z'、'a'-'z'、'_'、'$'、'ä')
  • 不能使用java保留字作为变量名;
  • 变量名对大小写敏感;

常量 

  • java 中利用关键字“final”指示常量;(表示变量只能被赋值一次)
  • 习惯上,常量名使用全大写;
  • 如果需要某个常量在一个类的多个方法中使用,则将其设置为类常量,用“static final”修饰;

运算符

常用运算:

  1. “+”:加
  2. “-”:减
  3. “*”:乘
  4. “/”:除
  5. “%”:取余(取模)


  • 使用“stricfp”关键字标记的方法、类,其中的所有指令都要使用严格的浮点计算;【?没用过】

数学函数与常量

  • 使用java.lang.Math
  • 如果要得到一个完全可预测的结果,应该使用“StrictMath”【?】

Math 类中提供了各种数学函数:

  1. 平方根:“double y = Math.sqrt(x);”
  2. 幂运算:“double y = Math.pow(x, a);”
  3. 三角函数:
    Math.sin
    Math.cos
    Math.tan
    Math.atan
    Math.atan2
  4. 指数函数、自然对数、以10为底的对数:
    Math.exp
    Math.log
    Math.log10
  5. 常量π、e的近似值:(近似值!)
    Math.PI
    Math.E

数值类型间的强制转换

  1. 如果其中一个为double,则另一个会被转换为double;
  2. 否则,如果如果其中一个为float,则另一个会被转换为float;
  3. 否则,如果如果其中一个为long,则另一个会被转换为long;
  4. 否则,两操作数都会被转换为int;

强制类型转换

强制类型转换(cast):用于类似由double向int、float这类,可能会丢失信息的转换。
如:

double x = 9.997;
int nx = (int)x;

如果需要对浮点数进行舍入运算,以便得到最接近的整数,则用“Math.round”(其返回值为long):

double x = 9.997;
int nx = (int)Math.round(x);

关系运算

  1. “<”:小于
  2. “>”:大于
  3. “<=”:小于等于
  4. “>=”:大于等于
  5. “&&”:逻辑与
  6. “||”:逻辑或
  7. “!”:逻辑非
  8. “?:”:三目运算


  • “&&”、“||”是按照“短路”方式来求值的(即:如果第一个操作数能确定表达式的值,则不再计算第二个表达式)
    如:“expression1 && expression2”:如果“expression1”为false,则不再计算“expression2”
    如:“expression1 || expression2”:如果“expression1”为true,则不再计算“expression2”

位运算

  1. “&”:and
  2. “|”:or
  3. “^”:xor(亦或,相同为真,相异为假)
  4. “~”:not
  5. “>>”:右移
  6. “<<”:左移
  7. “>>>”:用0填充高位


  • 这些运算符,按照位模式处理;(把操作数的二进制数,按照从右至左,对每一位进行运算)
  • 移位运算符的右操作数要完成模32的运算(若左操作数为long,则右操作数模64)【???what???】
    如:“1<<35”等同于“1<<3”或8()
    【猜测:对于4字节(32位)的类型来说,位移超过了32位,就会从另一侧出来(就像转动一个环?)】

枚举类型

枚举类型:用于取值在一个有限的集合范围内。


定义:

enum Size{SMALL, MEDIUM, LARGE, EXTRA_LARGE};

声明:

Size s = Size.MEDIUM;

字符串

Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类“String”,每个双引号中的字符串都是String类的一个实例。
从概念上讲,Java字符串就是Unicode字符序列。

子串

从较大的字符串中提取出一个字串:

String greeting = "Hello";
String s = greeting.subString(13);   // s="ell";
  • 从1开始到3为止(不包括第三位,即第1、2位),长度为3-1=2。

拼接 

  • Java允许使用“+”连接(拼接)两个字符串。

把多个字符串放在一起,用一个定界符分隔:

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

不可变字符串

Java没有提供修改字符串的方法,如果需要修改字符串中的字符,需要截取字串再进行拼接。
所以,Java文档中将String对象称为“不可变字符串”。


以“greeting="Hello"”为例,“Hello”存在于常量池中,其内容不会改变。只能修改greeting将其指向新的字符串。


检测字符串是否相等

  • 判断字符串是否相等,应该用“s.equals(t)”(比较值),而非“==”(比较引用地址)
  • 如需要不区分大小写进行比较,则用“equalsIgnoreCase”。

空串 与 Null串

空串:

  1. 空串是一个java对象,有自己的长度(0)和内容(空)
  2. 可以用“if(str.length()==0)”或“if(str.equals(""))”判断是否空串


Null:

  1. null表示当前没有任何对象与该变量关联
  2. 可以用“if(str == null)”判断是否为空


有时候需要判断既不是null,也非空串:
“if(str != null && str.length() != 0)”

  • 必须先判断null(逻辑运算符的短路方式),否则如果对null调用length会出错

码点与代码单元

代码点(Code Point):在 Unicode 代码空间中的一个值,取值 0x0 至 0x10FFFF,代表一个字符。

代码单元(Code Unit):在具体编码形式中的最小单位。比如 UTF-16 中一个 code unit 为 16 bits,UTF-8 中一个 code unit 为 8 bits。

  • 一个 code point 可能由一个或多个 code unit(s) 表示
  • 在Java中,char类型描述了UTF-16编码中的一个代码单元


java字符串由char值序列组成,char类型是一个采用UTF-16编码表示Unicode码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

  1. “greeting.length()”:返回的是代码单元的数量
  2. “greeting.codePointCount(0, greeting.length())”:实际长度(码点数量)
  3. “greeting.charAt(3)”:返回位置3的代码单元
  4. “int index=greeting.offsetByCodePoint(0,i)”“int cp=greeting.codePointAt()”:得到第i个码点


  1. “int[] codePoints = str.codePoints().toArray();”:将String转化为码点数组,用于遍历
  2. “String str = new String(codePoints, 0, codePoints.length());”:将码点数组转化为String

String API

常用:

  1. “int compare(String other)”:按照字典顺序,比较字符串(负数:位于other之前;正数:位于other之后;0:两个字符串相等)
  2. “boolean equals(Object other)”:
  3. “boolean euqalsIgnoreCase(String other)”:
  4. “boolean startWith(String prefix)”:如果string以prefix开头,返回true
  5. “boolean endWith(String sufffix)”:
  6. “int indexOf(...)”:
  7. “int lastIndexOf(...)”:
  8. “int length()”:
  9. “String replace(CharSequence oldString, CharSequence newString)”:返回一个新串。用newString代替原始串中所有oldString。可以用String或StringBuilder作为CharSequence参数。
  10. “String suString(...)”:
  11. “String toLowerCase()”:
  12. “String toUpperCase()”:
  13. “String trim()”:
  14. “String join(...)”:

构建字符串

在使用多个短字符串拼接构建新字符串的过程中,每一次拼接都会生成一个String对象,耗时且浪费空间。


StringBuilder 类旧用于避免此问题:

StringBuilder builder = new StringBuilder();

//拼接字符串ch、str形成新串
builder.append(ch);
builder.append(str);

//构建字符串时,使用toString
String completedString = builder.toString();
  • 在 JDK 5.0 中引入了 StringBuilder 类,其前身是 StringBuffer(其效率稍低,但允许多线程执行),如果所有字符串在一个单线程中编辑,则应该使用 StringBuilder。

输入输出

流程控制

大数值

数组