以下为个人学习笔记和习题整理
课程:零基础学 Java 语言 - 浙江大学 - 翁恺 @ 中国大学 MOOC
https://www.icourse163.org/course/ZJU-1001541001
# 课堂笔记
# 字符类型 char
- 字符也是 Java 中基础的数据类型之一
- 用单引号表示的字符:
'a'
,'1'
- 用单引号表示的字符:
- Java 采用
Unicode16
表达字符,在所有的机器上,不管 CPU、操作系统和本地语言,字符类型是一致和统一的。 - 一个汉字也是 Unicode 的一个字符,所以也是 Java 的一个字符。
# 字符计算
char c = 'A'; | |
c++; | |
System.out.println(c); // 输出结果为:B | |
int i = 'Z'-'A'; | |
System.out.println(i); // 输出结果为:25 | |
System.out.println((int)c); // 输出结果为:66 |
- 一个字符加一个数字得到 Unicode 码表中的那个数之后的字符
- 两个字符的减,得到它们在表中的距离
- char 也可以和 int 之间相互赋值,输出字符在 Unicode 码表中的位置
# 大小写转换
- 字母和数字在 Unicode 表中是顺序排列的
- 大写字母和小写字母是分开排列的,不在一起
'a' - 'A'
可以得到两段之间的距离a + 'a' - 'A'
可以把一个大写字母变成小写字母a + 'A' - 'a'
可以把一个小写字母变成大写字母
# 字符大小比较
- 字符可以比较大小,依据是它们在 Unicode 表中的编号
'0' < '9'
'A' < 'Z'
'a' > 'Z'
'Z' < 'a'
# 逃逸字符
- 用来表达无法印出来的控制字符或特殊字符,它由一个反斜杠 "\" 开头,后面跟上另一个字符,这两个字符合起来,组成了一个字符。
字符 | 意义 | 字符 | 意义 |
\b | 回退一格(但不删除) | " | 双引号 |
\t | 到下一个表格位 | ’ | 单引号 |
\n | 换行 | \ | 反斜杠本身 |
\r | 回车 |
# 包裹类型
对于基本数据类型,Java 提供了对应的包裹 (wrap) 类型。
这些包裹类型将一个基本数据类型的数据转换成对象的形式,从而使得它们可以像对象一样参与运算和传递。
下表列出了基本数据类型所对应的包裹类型:
基本类型 | 包裹类型 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
- 除了 int 和 char 以外,包裹类型就是把基本类型的名字的第一个字母大写。
- 在 Java 的系统类库中,所有第一个字母大写的,都是类的名字。所以在编辑程序的时候,一定要小心大小写,以免一不小心犯错。
// 定义包裹类型变量 | |
Integer i = 10; | |
Integer i = new Integer(10); | |
Integer i = new Integer("10"); | |
// 获得包裹类型的值 | |
Integer iii = 10; | |
int i = iii; |
# 用途
当需要让一个类或对象做事情的时候,使用
.
运算符。获得该类型的最大最小值
Integer.MIN_VALUE | |
Integer.MAX_VALUE |
- 判断这个字符是否是数字
static boolean isDigit(char ch) |
- 判断这个字符是不是字母
static boolean isLetter(char ch) |
- 判断这个字符是不是字母或数字
static boolean isLetterOrDigit(char ch) |
- 判断这个字符是不是⼩写字母
static boolean isLowerCase(char ch) |
- 判断这个字符是不是⼤写字母
static boolean isUpperCase(char ch) |
- 判断这个字符是不是⼀种空格
static boolean isWhitespace(char ch) |
- 把这个字符转换成⼩写
static char toLowerCase(char ch) |
- 把这个字符转换成⼤写
static char toUpperCase(char ch) |
# 字符串
- 用双引号括起来的 0 个或多个字符就是一个字符串字面量
“hello”
“1”
“”
# 输入字符串
- 读入一个单词,单词的标志是空格、tab、换行
in.next(); |
- 读入一整行
in.nextLine(); |
# 字符串变量 String
String s; |
- String 是一个类。
- String 的变量和数组变量类似,它并不存放字符串,不是字符串的所有者,它是字符串的管理者。
# new 创建对象
String s = new String("a string"); |
- 创建了一个 String 的对象
- 用 "a string" 初始化这个对象
- 创建管理这个对象的变量 s
- 让 s 管理这个对象
Error: Failed to launch the browser process! spawn /Applications/Google Chrome.app/Contents/MacOS/Google Chrome ENOENT TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
String s = "hello"; |
- 编译器创建一个 String 类的对象交给 s 来管理
# 变量赋值
Error: Failed to launch the browser process! spawn /Applications/Google Chrome.app/Contents/MacOS/Google Chrome ENOENT TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
- 字符串变量中,a、b 是管理者,不是所有者。b=a 是 b 和 a 都管理 a 的字符串。
- int 变量中,a、b 是所有者,b=a 是改变本身。
# 内容比较 equals
- 比较是否同一个
if( input == "bye" ) { | |
... | |
} |
equals
比较内容是否相同
if( input.equals("bye") ) { | |
... | |
} |
# 字符串连接 +
- 用加号 (+) 可以连接两个字符串
"hello" + "world"
→"helloworld"
- 当
+
的一边是字符串而另一边不是时,会将另一边表达为字符串,然后做连接"I’m " + 18
→"I’m 18"
1 + 2 + "age"
→"3age"
"age" + 1 + 2
→"age12"
# 字符串运算 .
- 字符串是对象,对它的所有操作都是通过
.
这个运算符来进行的
字符串.操作 |
对
.
左边的这个字符串,做右边的那个操作左边的字符串可以是变量,也可以是常量
Java 的字符串是一种特殊的
不可变
对象,所有的字符串操作都是产生一个新的字符串,而不是对原来的字符串的修改。
String s = "abc"; | |
System.out.println(s.toUpperCase()); // ABC | |
System.out.println(s); // abc |
# 大小比较 compareTo
s1.compareTo(s2) | |
s1.compareToIgnoreCase(s2)// 可以不区分大小写地比较大小 |
- 如果 s1 比 s2 小,那么结果是负的
- 如果 s1 和 s2 相等,那么结果是 0
- 如果 s1 比 s2 大,那么结果是正的
# 获得长度 length ()
String name = "Hellola"; | |
name.length(); // 输出: 7 | |
String str1 = "one"; | |
str1.length(); // 输出:3 | |
String str2 = ""; | |
str2.length(); // 输出: 0 | |
String str3; | |
str2.length(); // Error! 因为 str3 没有管理任何 String 对象 |
# 访问字符串里的字符 charAT
s.charAT(index) |
- 返回在 index 上的单个字符
- index 的范围是
0
到length()-1
- 第一个字符的 index 是 0,和数组一样
- 但是不能用 for-each 循环来遍历字符串
# 得到子串 substring
s.substring(n) |
- 得到从 n 号位置到末尾的全部内容
s.substring(b,e) |
- 得到从 b 号位置到 e 号位置之前的内容
# 寻找字符 indexOf
s.index0f(c) |
- 得到 c 字符所在的位置,-1 表示不存在
s.index0f(c,n) |
- 从 n 号位置开始寻找 c 字符
s.index0f(t) |
- 找到字符串 t 所在的位置
s.lastIndex0f(c) | |
s.lastIndex0f(c,n) | |
s.lastIndex0f(t) |
- 从右边开始找,各部分参数同上
# 以 x 起始或结束 startsWith endsWith
s.startsWith(t) | |
s.endsWith(t) |
# 去除两端空格 trim
s.trim() |
# 内容替换 replace
s.replace(c1,c2) |
# 大小写转换 toLowerCase toUpperCase
s.toLowerCase() | |
s.toUpperCase() |
# 编程题
# 题目 1. 单词长度(5 分)
题目内容
你的程序要读入一行文本,其中以空格分隔为若干个单词,以.
结束。你要输出这行文本中每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如 “it's” 算一个单词,长度为 4。注意,行中可能出现连续的空格。输入格式
输入在一行中给出一行文本,以.
结束,结尾的句号不能计算在最后一个单词的长度内。输出格式
在一行中输出这行文本对应的单词的长度,每个长度之间以空格隔开,行末没有最后的空格。输入样例
It's great to see you here.输出样例
4 5 2 3 3 4
# 解题代码
import java.util.Scanner; | |
public class Main { | |
public static void main(String[] args) { | |
Scanner in = new Scanner(System.in); | |
String s = in.next();// 字符串输入 | |
String comma = ""; | |
int len; // 字符串长度 | |
while ( true ) { | |
len = s.length(); | |
if (s.endsWith(".") ) { | |
len -= 1; | |
if (len > 0) { | |
System.out.print(comma + len); | |
} | |
break; | |
} | |
System.out.print(comma + len); | |
s = in.next();// 下一个字符串输入 | |
comma = " "; // 下一个字符串前有空格 | |
} | |
} | |
} |
# 题目 2. GPS 数据处理(5 分)
题目内容
NMEA-0183 协议是为了在不同的 GPS(全球定位系统)导航设备中建立统一的 BTCM(海事无线电技术委员会)标准,由美国国家海洋电子协会(NMEA-The National Marine Electronics Associa-tion)制定的一套通讯协议。GPS 接收机根据 NMEA-0183 协议的标准规范,将位置、速度等信息通过串口传送到 PC 机、PDA 等设备。NMEA-0183 协议是 GPS 接收机应当遵守的标准协议,也是目前 GPS 接收机上使用最广泛的协议,大多数常见的 GPS 接收机、GPS 数据处理软件、导航软件都遵守或者至少兼容这个协议。
NMEA-0183 协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有 $GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL 等。
其中 $GPRMC 语句的格式如下:
$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
这里整条语句是一个文本行,行中以逗号
,
隔开各个字段,每个字段的大小(长度)不一,这里的示例只是一种可能,并不能认为字段的大小就如上述例句一样。字段 0:$GPRMC,语句 ID,表明该语句为 Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐最小定位信息
字段 1:UTC 时间,hhmmss.sss 格式
字段 2:状态,A = 定位,V = 未定位
字段 3:纬度 ddmm.mmmm,度分格式(前导位数不足则补 0)
字段 4:纬度 N(北纬)或 S(南纬)
字段 5:经度 dddmm.mmmm,度分格式(前导位数不足则补 0)
字段 6:经度 E(东经)或 W(西经)
字段 7:速度,节,Knots
字段 8:方位角,度
字段 9:UTC 日期,DDMMYY 格式
字段 10:磁偏角,(000 - 180)度(前导位数不足则补 0)
字段 11:磁偏角方向,E = 东 W = 西
字段 16:校验值这里,
*
为校验和识别符,其后面的两位数为校验和,代表了$
和*
之间所有字符(不包括这两个字符)的异或值的十六进制值。上面这条例句的校验和是十六进制的 50,也就是十进制的 80。提示:
^
运算符的作用是异或。将$
和*
之间所有的字符做^
运算 (第一个字符和第二个字符异或,结果再和第三个字符异或,依此类推) 之后的值对 65536 取余后的结果,应该和*
后面的两个十六进制数字的值相等,否则的话说明这条语句在传输中发生了错误。注意这个十六进制值中是会出现 A-F 的大写字母的。另外,如果你需要的话,可以用Integer.parseInt(s)
从 String 变量 s 中得到其所表达的整数数字;而Integer.parseInt(s, 16)
从 String 变量 s 中得到其所表达的十六进制数字。现在,你的程序要读入一系列 GPS 输出,其中包含 $GPRMC,也包含其他语句。在数据的最后,有一行单独的
END
表示数据的结束。你的程序要从中找出 $GPRMC 语句,计算校验和,找出其中校验正确,并且字段 2 表示已定位的语句,从中计算出时间,换算成北京时间。一次数据中会包含多条 $GPRMC 语句,以最后一条语句得到的北京时间作为结果输出。
你的程序一定会读到一条有效的 $GPRMC 语句。
输入格式
多条 GPS 语句,每条均以回车换行结束。最后一行是 END 三个大写字母。输出格式
6 位数时间,表达为:hh:mm:ss
其中,hh 是两位数的小时,不足两位时前面补 0;mm 是两位数的分钟,不足两位时前面补 0;ss 是两位数的秒,不足两位时前面补 0。输入样例
$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
END输出样例
10:48:13
# 解题代码
import java.util.Scanner; | |
public class Main { | |
public static void main(String[] args) { | |
Scanner in = new Scanner(System.in); | |
String str = in.next();// 字符串输入 | |
String substr = ""; | |
Integer check, hh = 0, mm = 0, ss = 0; | |
int code = 0; | |
while ( !str.equals("END") ) { | |
if ( !str.startsWith("$GPRMC")) { | |
str = in.next();// 下一个字符串输入 | |
continue; | |
} | |
// 将 $ 和 * 之间所有的字符做 ^ 运算 | |
substr = str.substring(1, str.indexOf("*")); | |
// 获得 * 后的校验符的十六进制数 | |
check = Integer.parseInt(str.substring(str.indexOf("*")+1), 16); | |
for(int i = 0; i < substr.length(); i++) { | |
code ^= substr.charAt(i); | |
} | |
if (code % 65536 == check) { // 数据合法 | |
String[] strs = str.split(","); | |
if (strs[2].equals("A")) { // 已定位 | |
hh = Integer.parseInt(strs[1].substring(0, 2)); | |
mm = Integer.parseInt(strs[1].substring(2, 4)); | |
ss = Integer.parseInt(strs[1].substring(4, 6)); | |
// 输出北京时间 | |
hh = ( hh + 8 ) % 24; | |
if ( hh < 10 ) { | |
System.out.print("0"); | |
} | |
System.out.print(hh+":"+mm+":"+ss); | |
} | |
} | |
str = in.next();// 下一个字符串输入 | |
} | |
} | |
} |