查看“核心技术:基本程序设计结构”的源代码
←
核心技术:基本程序设计结构
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:JavaCore]] == 数据类型 == {| class="wikitable" ! 类型 !! 存储需求 !! 默认值 !! 取值范围 |- ! colspan="4"| 整型 |- | int | 4字节 | 0 | -2 147 483 648 - 2 147 483 647 # Integer.MIN_VALUE=-2147483648 # Integer.MAX_VALUE=2147483647 |- | short | 2字节 | 0 | -32 768 - 32767 # Short.MIN_VALUE=-32768 # Short.MAX_VALUE=32767 |- | long | 8字节 | 0L | -9 223 372 036 854 775 808 - 9 223 372 036 854 775 807 # Long.MIN_VALUE=-9223372036854775808 # Long.MAX_VALUE=9223372036854775807 |- | byte | 1字节 | 0 | -128 - 127 # Byte.MIN_VALUE=-128 # Byte.MAX_VALUE=127 |- ! colspan="4"| 浮点 |- | float | 4字节 | 0.0f | 大约 +- 3.402 823 47E+38F(有效位数为6、7位) # Float.MIN_VALUE=1.4E-45 # Float.MAX_VALUE=3.4028235E38 |- | double | 8字节 | 0.0d | 大约 +- 1.797 693 134 862 315 70E+308(有效位数为15位) # Double.MIN_VALUE=4.9E-324 # Double.MAX_VALUE=1.7976931348623157E308 |- ! colspan="4"| 字符 |- | char | 2字节 | 'u0000' | \u0000 - \uffff |- ! colspan="4"| 布尔 |- | boolean | 1位 | false | <nowiki>true | false</nowiki> |} * 常量“Double.POSITIVE_INFINITY”、“Double.NEGATIVE_INFINITY”、“Double.NAN”分别表示“正无穷大”、“负无穷大”、“NaN(不是一个数字)”; === 取值范围 === * 整数用原码,负数用补码表示 以int为例,在java中占4字节,即32位: # 其中第一位为符号位(0正,1负) # 所以负数范围为:-2^31 = -2147483648 # 整数的范围为: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”的情况: :[[File:小数计算1.jpg|800px]] :[[File:小数计算2.jpg|800px]] 其原因如下:<br/> <pre> 计算机存储、计算或者展示,都需要转换2进制。 在现实世界中,数字主要有整数和小数两种,整数包括正整数、负整数以及零。 计算机中表示整数的方式有很多,如原码、反码以及补码等。 在计算机中存储的整数则分为有符号数和无符号数。 对于无符号数,采用哪种编码方式都无所谓,对于有符号数的编码方式,常用的是补码。 那么,一个十进制数字想要获得其二进制的补码,需要先通过一定的算法得到他对应的原码。 </pre> # 十进制整数转换为二进制,可以采用“除2取余,逆序排列”,或者xxx法(列出“...128,64,32,26,8,4,2,1”,根据十进制数在对应位置1或0); # 十进制小数转换为二进制:则采用“乘2取整,顺序排列”的方法; 如,0.625的二进制转换如下:<br/> [[File:0.625的二进制.jpg|600px]] <br/> 而0.1的二进制:<br/> [[File:0.1的二进制.jpg|600px]] <br/> 可以得知:0.1的二进制转换中出现了无限循环的情况,也就是(0.1)10 = (0.000110011001100…)2,而不能把0.1转换为确定的二进制数<br/> 即'''计算机无法用二进制精确的表示0.1'''<br/> <pre> IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现) </pre> 但仅是用近似值表示小数,并非真实值,如果使用float、double等类型进行小数计算,仍然会丢失数值。并没有解决问题。<br/> 所以:为了解决这样的精度问题,Java中提供了'''BigDecimal'''来进行精确运算。 * BigDecimal 并不是Java的数据类型,而是一个Java对象! == 变量 == * 变量名:以字母开头,并由字母和数字构成的序列;(字母包括:'A'-'Z'、'a'-'z'、'_'、'$'、'ä') * 不能使用java保留字作为变量名; * 变量名对大小写敏感; === 常量 === * java 中利用关键字“final”指示常量;(表示变量只能被赋值一次) * 习惯上,常量名使用全大写; * 如果需要某个常量在一个类的多个方法中使用,则将其设置为类常量,用“static final”修饰; == 运算符 == 常用运算: # “+”:加 # “-”:减 # “*”:乘 # “/”:除 # “%”:取余(取模) * 使用“stricfp”关键字标记的方法、类,其中的所有指令都要使用严格的浮点计算;【?没用过】 === 数学函数与常量 === * 使用java.lang.Math * 如果要得到一个完全可预测的结果,应该使用“StrictMath”【?】 Math 类中提供了各种数学函数: # 平方根:“double y = Math.sqrt(x);” # 幂运算:“double y = Math.pow(x, a);” # 三角函数: #: Math.sin #: Math.cos #: Math.tan #: Math.atan #: Math.atan2 # 指数函数、自然对数、以10为底的对数: #: Math.exp #: Math.log #: Math.log10 # 常量π、e的近似值:(近似值!) #: Math.PI #: Math.E === 数值类型间的强制转换 === # 如果其中一个为double,则另一个会被转换为double; # 否则,如果如果其中一个为float,则另一个会被转换为float; # 否则,如果如果其中一个为long,则另一个会被转换为long; # 否则,两操作数都会被转换为int; === 强制类型转换 === 强制类型转换(cast):用于类似由double向int、float这类,可能会丢失信息的转换。<br/> 如: <syntaxhighlight lang="java"> double x = 9.997; int nx = (int)x; </syntaxhighlight> 如果需要对浮点数进行舍入运算,以便得到最接近的整数,则用“Math.round”(其返回值为long): <syntaxhighlight lang="java"> double x = 9.997; int nx = (int)Math.round(x); </syntaxhighlight> === 关系运算 === # “<”:小于 # “>”:大于 # “<=”:小于等于 # “>=”:大于等于 # “&&”:逻辑与 # “||”:逻辑或 # “!”:逻辑非 # “?:”:三目运算 * “&&”、“||”是按照“短路”方式来求值的(即:如果第一个操作数能确定表达式的值,则不再计算第二个表达式) *: 如:“expression1 && expression2”:如果“expression1”为false,则不再计算“expression2” *: 如:“expression1 || expression2”:如果“expression1”为true,则不再计算“expression2” === 位运算 === # “&”:and # “|”:or # “^”:xor(亦或,相同为真,相异为假) # “~”:not # “>>”:右移(用符号位填充高位) # “<<”:左移 # “>>>”:无符号右移(用0填充高位) * 这些运算符,按照位模式处理;(把操作数的二进制数,按照从右至左,对每一位进行运算) * 移位运算符的右操作数要完成模32的运算(若左操作数为long,则右操作数模64)【'''如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模'''】 *: 如:“1<<35”等同于“1<<3”或8() *: 【猜测:对于4字节(32位)的类型来说,位移超过了32位,就会从另一侧出来(就像转动一个环?)】 ==== 位移示例 ==== [[负数的二进制]] 7右移2位: <syntaxhighlight lang="java"> 00000000 00000000 00000000 00000111//7的二进制 右移两位后 00000000 00000000 00000000 00000001//最左边用符号位填充 转换十进制为: 1 </syntaxhighlight> 7无符号右移2位: <syntaxhighlight lang="java"> 00000000 00000000 00000000 00000111//7的二进制 右移两位后 00000000 00000000 00000000 00000001//最左边用0填充 转换十进制为: 1 </syntaxhighlight> -7右移2位: <syntaxhighlight lang="java"> 11111111111111111111111111111001//-7的二进制 右移两位后 11111111111111111111111111111110//最左边用符号位填充 转换十进制为: -2 </syntaxhighlight> -7无符号右移2位: <syntaxhighlight lang="java"> 11111111111111111111111111111001//-7的二进制 右移两位后 00111111111111111111111111111110//最左边用0填充 转换十进制为: 1073741822 </syntaxhighlight> 7左移2位: <syntaxhighlight lang="java"> 00000000 00000000 00000000 00000111//7的二进制 右移两位后 00000000 00000000 00000000 00011100//最右边用0填充 转换十进制为: 28 </syntaxhighlight> -7左移2位: <syntaxhighlight lang="java"> 11111111111111111111111111111001//-7的二进制 右移两位后 11111111111111111111111111100100//最右边用0填充 转换十进制为: -28 </syntaxhighlight> * 位移只能用于整型 * >>> 不能用于负数的右移(如上,高位补0,移成整数了) * >> 不能用于大于整型范围的操作数(运算符除“/”也不行,只能用“>>>”): *: 操作数大于整型范围时,最高位(符号位)可能为1(即变成了负数),用“>>”导致高位用 1 补足,成为负数; === 枚举类型 === 枚举类型:用于取值在一个有限的集合范围内。 定义: <syntaxhighlight lang="java"> enum Size{SMALL, MEDIUM, LARGE, EXTRA_LARGE}; </syntaxhighlight> 声明: <syntaxhighlight lang="java"> Size s = Size.MEDIUM; </syntaxhighlight> == 字符串 == Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类“String”,每个双引号中的字符串都是String类的一个实例。<br/> 从概念上讲,Java字符串就是Unicode字符序列。 === 子串 === 从较大的字符串中提取出一个字串: <syntaxhighlight lang="java"> String greeting = "Hello"; String s = greeting.subString(1,3); // s="ell"; </syntaxhighlight> * 从1开始到3为止(不包括第三位,即第1、2位),长度为3-1=2。 === 拼接 === * Java允许使用“+”连接(拼接)两个字符串。 把多个字符串放在一起,用一个定界符分隔: <syntaxhighlight lang="java"> String all = String.join(" / ", "S", "M", "L", "XL"); // all="S / M / L / XL" </syntaxhighlight> === 不可变字符串 === Java没有提供修改字符串的方法,如果需要修改字符串中的字符,需要截取字串再进行拼接。<br/> 所以,Java文档中将String对象称为“不可变字符串”。 以“greeting="Hello"”为例,“Hello”存在于常量池中,其内容不会改变。只能修改greeting将其指向新的字符串。 ==== String、StringBuffer 和 StringBuilder ==== # String:位于常量池中(不可修改); # StringBuffer:位于缓冲区(可修改),慢,安全; # StringBuilder:位于Java堆上(可以修改),快,不安全; === 检测字符串是否相等 === * 判断字符串是否相等,应该用“s.equals(t)”(比较值),而非“==”(比较引用地址) * 如需要不区分大小写进行比较,则用“equalsIgnoreCase”。 === 空串 与 Null串 === 空串: # 空串是一个java对象,有自己的长度(0)和内容(空) # 可以用“if(str.length()==0)”或“if(str.equals(""))”判断是否空串 Null: # null表示当前没有任何对象与该变量关联 # 可以用“if(str == null)”判断是否为空 有时候需要判断既不是null,也非空串:<br/> “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字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。 # “greeting.length()”:返回的是代码单元的数量 # “greeting.codePointCount(0, greeting.length())”:实际长度(码点数量) # “greeting.charAt(3)”:返回位置3的代码单元 # “int index=greeting.offsetByCodePoint(0,i)”“int cp=greeting.codePointAt()”:得到第i个码点 # “int[] codePoints = str.codePoints().toArray();”:将String转化为码点数组,用于遍历 # “String str = new String(codePoints, 0, codePoints.length());”:将码点数组转化为String === String API === 常用: # “int compare(String other)”:按照字典顺序,比较字符串(负数:位于other之前;正数:位于other之后;0:两个字符串相等) # “boolean equals(Object other)”: # “boolean euqalsIgnoreCase(String other)”: # “boolean startWith(String prefix)”:如果string以prefix开头,返回true # “boolean endWith(String sufffix)”: # “int indexOf(...)”: # “int lastIndexOf(...)”: # “int length()”: # “String replace(CharSequence oldString, CharSequence newString)”:返回一个新串。用newString代替原始串中所有oldString。可以用String或StringBuilder作为CharSequence参数。 # “String suString(...)”: # “String toLowerCase()”: # “String toUpperCase()”: # “String trim()”: # “String join(...)”: === 构建字符串 === 在使用多个短字符串拼接构建新字符串的过程中,每一次拼接都会生成一个String对象,耗时且浪费空间。 StringBuilder 类旧用于避免此问题: <syntaxhighlight lang="java"> StringBuilder builder = new StringBuilder(); //拼接字符串ch、str形成新串 builder.append(ch); builder.append(str); //构建字符串时,使用toString String completedString = builder.toString(); </syntaxhighlight> * 在 JDK 5.0 中引入了 StringBuilder 类,其前身是 StringBuffer(其效率稍低,但允许多线程执行),如果所有字符串在一个单线程中编辑,则应该使用 StringBuilder。 == 输入输出 == === 标准输入输出 === 标准输出流:(控制台窗口) <syntaxhighlight lang="java"> System.out.pringtln(); </syntaxhighlight> 标准输入流: <syntaxhighlight lang="java"> // 构造 Scanner 对象,并于“标准输入流”(System.in)关联 Scanner in = new Scanner(System.in); // 读取输入行 String name = in.nextLine(); // 读取字符串(以空格符作为分隔) String firstName = in.next(); // 读取整数 int age = in.nextInt(); //读取浮点数 double salary = in.nextDouble(); </syntaxhighlight> * Scanner 位于 java.util 包中。(当使用的类定义不在 java.lang 包时,需要 import 相关包) Scanner 不适用于从控制台读取密码(输入可见),所以 Java SE 6 引入了 “Console”类: <syntaxhighlight lang="java"> Console cons = System.console(); String username = cons.readLine("User name: "); char[] passwd = cons.readPassword("Password: "); </syntaxhighlight> * Console 每次只能读取一行,不能读取一个单词或数值; * 密码应该存在一维字符数组中,而非字符串中。 * 对密码处理完成之后,应该马上用一个填充值覆盖数组元素。 === 格式化输入输出 === Java SE 5.0 沿用了 C 语言库函数中的 “printf”方法: <syntaxhighlight lang="java"> System.out.printf("%8.2f", x); </syntaxhighlight> {| class="wikitable" ! 转换符 !! 类型 !! 示例 !! | !! 转换符 !! 类型 !! 示例 |- | d | 十进制整数 | 158 | <nowiki>|</nowiki> | s | 字符串 | Hello |- | x | 十六进制整数 | 9f | <nowiki>|</nowiki> | c | 字符 | H |- | o | 八进制整数 | 237 | <nowiki>|</nowiki> | b | 布尔 | True |- | f | 定点浮点数 | 15.9 | <nowiki>|</nowiki> | h | 散列码 | 42628b2 |- | e | 指数浮点数 | 1.59e+01 | <nowiki>|</nowiki> | tx 或 Tx | 日期时间(T强制大写) | (已过时,改用“java.time”类 |- | g | 通用浮点数 | — | <nowiki>|</nowiki> | % | 百分号 | % |- | a | 十六进制浮点数 | 0x1.fccdp3 | <nowiki>|</nowiki> | n | 与平台相关的分隔符 | — |} === 文件输入输出 === 要对文件进行读取,就要用“File”对象构造一个“Scanner”对象: <syntaxhighlight lang="java"> Scanner in = new Scanner(Path.get("myfile.txt"), "UTF-8"); </syntaxhighlight> * 需要对反斜杠“\”进行转义“\\” 然后就可以利用 Scanner 对象的方法对文件进行读取 要写入文件,就需要构造一个“PrintWriter”对象(构造其中只需要文件名): <syntaxhighlight lang="java"> PrintWriter out = new PrintWriter("myfile.txt", "UTF-8"); </syntaxhighlight> * 如果该文件不存在,则创建 然后可以使用 PrintWriter 的 print、printf、println 等方法对文件进行写入 == 流程控制 == java 的流程控制结构与 c、c++ 基本一样。 === 块 === 块(block),由大括号括起来的若干条简单的Java语句。 * 块确定了变量的作用域:同一个块、嵌套的块中,不能声明同名的变量 === 条件 === if else === 循环 === # while # do while # for * 变形的 for 循环,类似于 C# 中的foreach: * <syntaxhighlight lang="java"> for( variable : collection ) </syntaxhighlight> === 多重选择 === switch case 标签可以是: # 类型为 char、byte、short、int 的常量表达式 # 枚举常量 # 从 Java SE 7 开始,还可以是'''字符串字面量'''(如:"yes") === 中断控制 === Java提供了一种“'''带标签的break'''”,用于跳出多重嵌套的循环:<br/> (标签放在希望跳出的最外层循环之前,其后带“:”) <syntaxhighlight lang="java"> ... read_date: while(){ ... for(...){ ... if(){ ... break read_date; } } ... } ... </syntaxhighlight> * 标签可以用到任何语句块中,不局限于循环 '''continue''',用于中断正常的控制流程(越过当前循环体的剩余部分),而转移到当前循环的首部。 * 带标签的 continue,会天跳到与标签匹配的循环首部 == 大数值 == * 位于 java.math 包中 包括了“BigInteger”(整数运算)和“BigDecimal”(浮点运算),可以处理任意长度的数字序列的数值。<br/> # 使用静态的“valueOf”方法,可以将普通数值转换为大数值: #: <syntaxhighlight lang="java"> BigInteger a = BigInteger.valueOf(100); </syntaxhighlight> # 不能使用基本的算数运算来处理大数据,而应使用大数值类中的add、multiply等方法: #: <syntaxhighlight lang="java"> BigInteger c = a.add(b); // c = a + b BigInteger d = c.multiply(b.add(BigInteger.valueOf(2))); // d = c * (b + 2) </syntaxhighlight> BigInteger 方法:(大整数) # “BigInteger add(BigInteger other)”:与另一个BigInteger的和; # “BigInteger subtract(BigInteger other)”:...差; # “BigInteger multiply(BigInteger other)”:...积; # “BigInteger divide(BigInteger other)”:...商; # “BigInteger mod(BigInteger other)”:...余数; # “int compareTo(BigInteger other)”:与另一个BigInteger比较(0:相等;正数:这个大;负数:另一个大); # “static BigInteger valueOf(long x)”:返回值等于x的大整数; BigDecimal 方法:(大实数) # “BigDecimal add(BigDecimal other)”:...; # “BigDecimal subtract(BigDecimal other)”:...; # “BigDecimal multiply(BigDecimal other)”:...; # “BigDecimal divide(BigDecimal other, RoundingMode mode)”:...; #: 计算商必须给出摄入方式,如“RoundingMode.HALF_UP”(四舍五入) # “BigDecimal mod(BigDecimal other)”:...; # “int compareTo(BigDecimal other)”:...; # “static BigDecimal valueOf(long x)”:...; # “static BigDecimal valueOf(long x)”:返回值为x/10^scale的大实数; == 数组 == # “int[] a;”:声明数组; #: 与“int a[]”同 # “a = new int[100];”:初始化数组; #: “new int[]”用于创建数组 初始化时: # 若为数字数组,所有元素初始化为0; # boolean,false # object,null * 数组创建之后大小不再改变 # 若在使用中需要扩展大小,应用数据列表(array list) === for each 循环=== <syntaxhighlight lang="java"> for(variable : collection) statement </syntaxhighlight> * collection 必须是一个数组,或实现了“Iterable”接口的对象(如:ArrayList) *: Iterable:迭代接口;Iterator:对象内容的迭代器; * 在不需要遍历元素,或需要使用元素下标的情况下,仍然推荐使用传统for循环 如: <syntaxhighlight lang="java"> for (int element : a) { System.out.println(element); } </syntaxhighlight> === 数组初始化 及 匿名数组 === 创建同时赋予初始值 <syntaxhighlight lang="java"> int a = {1,2,3,4,5,6,7,8,9}; </syntaxhighlight> 匿名数组: <syntaxhighlight lang="java"> new int[] {1,2,3,4,5,6,7,8,9} </syntaxhighlight> * 可以在不创建新变量的情况下初始化一个数组 === 数组拷贝 === 将一个数组变量拷贝给另一个数组变量,则,两个数组变量将引用同一个数组: <syntaxhighlight lang="java"> int b = Arrays.copyOf(a, a.length); </syntaxhighlight> 如果需要在拷贝时增加新数组的大小: <syntaxhighlight lang="java"> int b = Array.copyOf(a, a.length * 2); //大小扩大一倍 </syntaxhighlight> === 数组排序 === 对数值型数组进行排序: <syntaxhighlight lang="java"> int a = new int[10000]; ... Arrays.sort(a); // 优化的快速排序 </syntaxhighlight> === Arrays常用方法 === # “static String toString(type[] a)”:; # “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)”:; # “static void fill(type[] a, type v)”:; # “static boolean equals(type[] a, type[] b)”:如果两个数组大小相同,且下标对应的元素相等,则返回true; === 多维数组 === 快速打印一个二维数组的元素列表: <syntaxhighlight lang="java"> System.out.println(Arrays.deepToString(a)); //输出格式为:[[1,2,3],[4,5,6],[7,8,9]] </syntaxhighlight>
返回至“
核心技术:基本程序设计结构
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息