Java 入门第三季,java入门第三季
Java 入门第三季,java入门第三季
- Java 入门第三季
- 异常与异常处理
- 1 Java 异常简介
- 2 Java 中使用 trycatchfinally 实现异常处理
- 3 Java中通过案例学习 trycatchfinally
- 4 练习题
- 5 Java 中的异常抛出以及自定义异常
- 6 练习题
- 6 Java 中的异常链
- 8 练习题
- 9 经验总结
- 认识 Java 中的字符串
- 1 什么是 Java 中的字符串
- 2 Java 中字符串的不变性
- 3 Java 中 String 类的常用方法
- 4 Java 中的 String 类常用方法
- 5 认识 Java 中的 StringBuilder 类
- 6 Java 中的 StringBuilder 类的常用方法
- 7 单选练习题
- Java 中必须了解的常用类
- 1 Java 中的包装类
- 3 Java 中基本类型和包装类之间的转换
- 3 单选练习题
- 4 Java 中基本类型和字符串之间的转换
- 5 单选练习题
- 6 使用 Date 和 SimpleDateFormat 类表示时间
- 7 Calendar 类的应用
- 8 使用 Math 类操作数据
- Java 中的集合框架
- 1 Java 中的集合框架概述
- 2 Collection 接口 List 接口简介
- 3 学生选课
- 4 学生选课应用泛型管理课程
- 5 学生选课通过 Set 集合管理课程
- Java 中的集合框架中
- 1 Map HashMap 简介
- 2 学生选课使用 Map 添加学生删除 Map 中的学生修改 Map 中的学生
- Java 中的集合框架下
- 1 学生选课判断 List 中课程是否存在
- 2 学生选课判断 Set 中课程是否存在
- 3 学生选课获取 List 中课程的位置
- 4 学生选课判断 Map 中是否包含指定的 key 和 value
- 5 应用 Collectionssort 实现 List 排序
- 6 学生选课尝试对学生序列排序
- 7 Comparable Comparator 简介
- 8 学生选课 实现学生序列排序
- 异常与异常处理
Java 入门第三季
1 异常与异常处理
1.1 Java 异常简介
运行时异常由 Java 虚拟机自动捕获自动抛出
检查时异常需要你手动添加捕获和处理语句
1.2 Java 中使用 try…catch…finally 实现异常处理
try 抛出异常会发生什么?
1. 抛出异常的方法会终止执行
2. 程序的控制权讲被移交给 catch 块中的异常处理程序
try 会抛出很多种类型的异常该怎么办?
多重catch语句中,异常类型必须子类在前父类在后
1.3 Java中通过案例学习 try…catch…finally
package com.anoscxy;
public class TryCatchTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
TryCatchTest tct = new TryCatchTest();
int result = tct.test();
System.out.println("test()方法,执行完毕!返回值为:"+result);
int result2 = tct.test2();
System.out.println("test2()方法,执行完毕!返回值为:"+result2);
int result3 = tct.test3();
System.out.println("test3()方法,执行完毕!返回值为:"+result3);
}
/**
* divider(除数)
* result(结果)
* try...catch 捕获 while 循环
* 每次循环,divider 减 1,result = result + 100、divider
* 如果:捕获异常,打印输出"抛出异常!"
* 否则:返回 result
* @return
*/
public int test() {
int divider = 10;
int result = 100;
try {
while (divider > -1) {
divider--;
result = result + 100 / divider;
}
return result;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
System.out.println("循环抛出异常!");
return -1;
}
}
public int test2() {
int divider = 10;
int result = 100;
try {
while (divider > -1) {
divider--;
result = result + 100 / divider;
}
return result;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
System.out.println("循环抛出异常!");
return result = 999;
}finally {
/**
* finally 语句块是在 try 语句块和 catch 语句块中的 return 语句执行完之后返回到调用者之前执行的
*/
System.out.println("这是finally!");
System.out.println("我是Result!我的值是:"+result);
}
}
public int test3() {
int divider = 10;
int result = 100;
try {
while (divider > -1) {
divider--;
result = result + 100 / divider;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
System.out.println("循环抛出异常!");
}finally {
/**
* finally 语句块是在 try 语句块和 catch 语句块中的 return 语句执行完之后返回到调用者之前执行的
*/
System.out.println("这是finally!");
System.out.println("我是Result!我的值是:"+result);
}
System.out.println("test3执行完了!");
/*
* 如果try...catch...finally语句块之内没有return语句,就会调用这三个语句块之外的return语句
*/
return 1111;
}
}
输出:
java.lang.ArithmeticException: / by zero
at com.anoscxy.TryCatchTest.test(TryCatchTest.java:31)
at com.anoscxy.TryCatchTest.main(TryCatchTest.java:8)
循环抛出异常!
test()方法,执行完毕!返回值为:-1
java.lang.ArithmeticException: / by zero
at com.anoscxy.TryCatchTest.test2(TryCatchTest.java:48)
at com.anoscxy.TryCatchTest.main(TryCatchTest.java:10)
循环抛出异常!
这是finally!
我是Result!我的值是:999
test2()方法,执行完毕!返回值为:999
java.lang.ArithmeticException: / by zero
at com.anoscxy.TryCatchTest.test3(TryCatchTest.java:71)
at com.anoscxy.TryCatchTest.main(TryCatchTest.java:12)
循环抛出异常!
这是finally!
我是Result!我的值是:381
test3执行完了!
test3()方法,执行完毕!返回值为:1111
1.4 练习题
(A)
解析:
try 语句块不可以独立存在,必须与 catch 或者 finally 块同存
1.5 Java 中的异常抛出以及自定义异常
某方法调用了会抛出异常的方法时的处理方法有两种?
1. 当调用者可以处理异常时,用try…catch语句块尝试捕获并处理异常
2. 当调用者不能处理异常时,添加throws声明将异常抛给更上层的调用者去处理
会抛出异常的方法:声明抛出的异常
处理方法一:当调用者可以处理异常时,用try…catch语句块尝试捕获并处理异常
处理方法二:当调用者不能处理异常时,添加throws声明将异常抛给更上层的调用者去处理
package com.anoscxy;
public class DrunkException extends Exception {
public DrunkException() {
}
public DrunkException(String message) {
// TODO Auto-generated constructor stub
super(message);
}
}
1.6 练习题
(C)
解析:
Exception 是异常类,自定义异常要继承于 Exception 类或者其子类
1.6 Java 中的异常链
新的异常中包含原始异常的所有信息,根据这点可以追溯最初异常发生的位置
异常链的两种写法:
方法一:通过调用新异常的initCause方法去引用原始异常从而实现了异常链的功能
package com.anoscxy;
public class ChainTest {
public static void main(String[] args) {
ChainTest ct = new ChainTest();
try {
ct.test2();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public void test1() throws DrunkException {
// TODO Auto-generated method stub
throw new DrunkException("喝车别开酒!");
}
public void test2() {
try {
// TODO Auto-generated method stub
test1();
} catch (Exception e) {
// TODO: handle exception
RuntimeException newExc = new RuntimeException("司机一滴酒,亲人两行泪!");
newExc.initCause(e); // 通过调用新异常的initCause方法去引用原始异常从而实现了异常链的功能
throw newExc;
}
}
}
方法二:老异常传入新异常的构造方法中,从而实现了异常链的功能
public void test2() {
try {
// TODO Auto-generated method stub
test1();
} catch (Exception e) {
// TODO: handle exception
RuntimeException newExc = new RuntimeException(e);
// newExc.initCause(e); // 通过调用新异常的initCause方法去引用原始异常从而实现了异常链的功能
throw newExc;
}
}
1.8 练习题
(D)
解析:
捕获到的异常,可以在当前方法的 catch 块中处理,也可抛出给调用者去处理
1.9 经验总结
2 认识 Java 中的字符串
2.1 什么是 Java 中的字符串
2.2 Java 中字符串的不变性
2.3 Java 中 String 类的常用方法 Ⅰ
结合代码来熟悉一下方法的使用:
public static void main(String[] args) {
String str = "学习 JAVA 编程";
System.out.println("字符串长度:"+str.length());
char c = '编';
System.out.println("字符串‘编’的位置:"+str.indexOf(c));
System.out.println("字符串‘JAVA’的位置:"+str.indexOf("JAVA"));
System.out.println("字符串'imooc'的位置:"+str.indexOf("imooc"));
String[] arr = str.split(" ");
System.out.print("按空格拆分成数组:"+Arrays.toString(arr));
System.out.println();
System.out.println("获取位置[3,7]之间的字符串:"+str.substring(3,7));
}
运行结果:
字符串长度:10
字符串‘编’的位置:8
字符串‘JAVA’的位置:3
字符串'imooc'的位置:-1
按空格拆分成数组:[学习, JAVA, 编程]
获取位置[3,7]之间的字符串:JAVA
友情提示:
任务
亲,让我们赶紧来做个练习吧。
功能:判断 Java 文件名是否正确,判断邮箱格式是否正确。其中:合法的文件名应该以 .java 结尾;合法的邮箱名中至少要包含 “@” , 并要求 “@” 在 “.” 之前
请参考注释,在编辑器中的第 16、19、22、36 行中将代码填写完整
运行结果:
public class HelloWorld {
public static void main(String[] args) {
// Java文件名
String fileName = "HelloWorld.java";
// 邮箱
String email = "laurenyang@imooc.com";
// 判断.java文件名是否正确:合法的文件名应该以.java结尾
/*
参考步骤:
1、获取文件名中最后一次出现"."号的位置
2、根据"."号的位置,获取文件的后缀
3、判断"."号位置及文件后缀名
*/
//获取文件名中最后一次出现"."号的位置
int index = fileName.lastIndexOf(".");
// 获取文件的后缀
String prefix = fileName.substring(index+1,fileName.length());
// 判断必须包含"."号,且不能出现在首位,同时后缀名为"java"
if (index!=-1&&index!=0&&prefix.equals("java") ) {
System.out.println("Java文件名正确");
} else {
System.out.println("Java文件名无效");
}
// 判断邮箱格式是否正确:合法的邮箱名中至少要包含"@", 并且"@"是在"."之前
/*
参考步骤:
1、获取文件名中"@"符号的位置
2、获取邮箱中"."号的位置
3、判断必须包含"@"符号,且"@"必须在"."之前
*/
// 获取邮箱中"@"符号的位置
int index2 = email.indexOf("@");
// 获取邮箱中"."号的位置
int index3 = email.indexOf('.');
// 判断必须包含"@"符号,且"@"必须在"."之前
if (index2 != -1 && index3 > index2) {
System.out.println("邮箱格式正确");
} else {
System.out.println("邮箱格式无效");
}
}
}
2.4 Java 中的 String 类常用方法 Ⅱ
我们继续来看 String 类常用的方法,如下代码所示:
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "学习 JAVA 编程";
System.out.println("转换为小写:"+str.toLowerCase());
System.out.println("获取索引为1位置的字符:"+str.charAt(1));
byte[] b = str.getBytes();
System.out.println("转换为字节数组:");
for(int i=0;i<b.length;i++) {
System.out.print(b[i]+" ");
}
System.out.println();
String str2 = new String("学习 JAVA 编程");
System.out.println("str 和 str2 的内存地址相同?" + (str == str2));
System.out.println("str 和 str2 的内容相同?"+str.equals(str2));
}
运行结果:
获取索引为1位置的字符:习
转换为字节数组:
-27 -83 -90 -28 -71 -96 32 74 65 86 65 32 -25 -68 -106 -25 -88 -117
str 和 str2 的内存地址相同?false
str 和 str2 的内容相同?true
那么,“==” 和 equals() 有什么区别呢?
==: 判断两个字符串在内存中首地址是否相同,即判断是否是同一个字符串对象
equals(): 比较存储在两个字符串对象中的内容是否一致
PS:字节是计算机存储信息的基本单位,1 个字节等于 8 位, gbk 编码中 1 个汉字字符存储需要 2 个字节,1 个英文字符存储需要 1 个字节。所以我们看到上面的程序运行结果中,每个汉字对应两个字节值,如“学”对应 “-47 -89” ,而英文字母 “J” 对应 “74” 。同时,我们还发现汉字对应的字节值为负数,原因在于每个字节是 8 位,最大值不能超过 127,而汉字转换为字节后超过 127,如果超过就会溢出,以负数的形式显示。(关于编码,我们在后面课程中会详细介绍,小小期待哦~~)
任务
亲,让我们赶紧来做个练习巩固一下吧。
功能:统计指定字符串中字符 ‘a’ 出现的次数
分析:可以通过循环遍历字符串中的每一个字符,判断是否是字符 a ,如果是,则累加统计出现的次数
请在编辑器中的第 10、13 行中将代码填写完整
运行结果:字符a出现的次数:8
public static void main(String[] args) {
// 定义一个字符串
String s = "aljlkdsflkjsadjfklhasdkjlflkajdflwoiudsafhaasdasd";
// 出现次数
int num = 0;
// 循环遍历每个字符,判断是否是字符 a ,如果是,累加次数
for (int i=0;i<s.length();i++)
{
// 获取每个字符,判断是否是字符a
if (s.charAt(i) == 'a') {
// 累加统计次数
num++;
}
}
System.out.println("字符a出现的次数:" + num);
}
2.5 认识 Java 中的 StringBuilder 类
在Java中,除了可以使用 String 类来存储字符串,还可以使用 StringBuilder 类或 StringBuffer 类存储字符串,那么它们之间有什么区别呢?
String 类具有是不可变性。如
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "hello";
System.out.println(str + "world");
System.out.println(str);
}
运行结果:
helloworld
hello
从运行结果中我们可以看到,程序运行时会额外创建一个对象,保存 “helloworld”。当频繁操作字符串时,就会额外产生很多临时变量。使用 StringBuilder 或 StringBuffer 就可以避免这个问题。至于 StringBuilder 和StringBuffer ,它们基本相似,不同之处,StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此一般情况下,如果需要创建一个内容可变的字符串对象,应优先考虑使用 StringBuilder 类。
那么如何定义 StringBuilder 类的对象呢? 我们来看下面的代码:
public static void main(String[] args) {
StringBuilder str1=new StringBuilder();
StringBuilder str2=new StringBuilder("imooc");
System.out.println(str2);
}
运行结果:
imooc
任务
在编辑器中定义了一个 StringBuilder 对象,用来存储字符串。认识一下他吧!!
public static void main(String[] args) {
// 创建一个StringBuilder对象,用来存储字符串
StringBuilder hobby=new StringBuilder("爱慕课");
System.out.println(hobby);
}
2.6 Java 中的 StringBuilder 类的常用方法
StringBuilder 类提供了很多方法来操作字符串:
public static void main(String[] args) {
StringBuilder str = new StringBuilder("hello");
str.append(" imooc");
str.append(520);
System.out.println("字符串长度:"+str.length());
System.out.println("插入前:"+str);
str.insert(11,"!");
String str2 = str.toString();
System.out.println("插入后:"+str2);
}
运行结果:
字符串长度:14
插入前:hello imooc520
插入后:hello imooc!520
任务
功能:将一个由英文字母组成的字符串转换成指定格式—从右边开始每三个字母用逗号分隔的形式。
请在编辑器中的第 4、10 行将代码填写完整
运行效果: j,aew,kjl,dfx,mop,zdm
public static void main(String[] args) {
// 创建一个空的StringBuilder对象
StringBuilder str = new StringBuilder();
// 追加字符串
str.append("jaewkjldfxmopzdm");
// 从后往前每隔三位插入逗号
for(int i=str.length()-3;i>0;i=i-3){
str.insert(i,',');
}
// 将StringBuilder对象转换为String对象并输出
System.out.print(str.toString());
}
2.7 单选练习题
(B)
解析
在需要频繁对字符串进行修改操作时使用 StringBuilder 的效率比 String 要高,所以选项 B 的说法不正确,选择 B
3 Java 中必须了解的常用类
3.1 Java 中的包装类
相信各位小伙伴们对基本数据类型都非常熟悉,例如 int、float、double、boolean、char 等。基本数据类型是不具备对象的特性的,比如基本类型不能调用方法、功能简单。。。,为了让基本数据类型也具备对象的特性, Java 为每个基本数据类型都提供了一个包装类,这样我们就可以像操作对象那样来操作基本数据类型。
基本类型和包装类之间的对应关系:
包装类主要提供了两大类方法:
1. 将本类型和其他基本类型进行转换的方法
2. 将字符串和本类型及包装类互相转换的方法
我们将在后面的小节逐步讲解,表着急哦~~
任务
我们以 Integer 包装类为例,来看下包装类的特性。
Integer 包装类的构造方法:
如下代码所示:
public static void main(String[] args) {
Integer m = new Integer(5);
Integer n = new Integer("8");
System.out.println("m="+m.intValue());
System.out.println("n="+n.intValue());
}
Integer包装类的常用方法:
编辑器中列举了 Integer 类型和基本数据类型之间的转换,结合运行结果先认识一下吧!
public static void main(String[] args) {
int score1 = 86;
Integer score2 = new Integer(score1);
double score3 = score2.doubleValue();
float score4 = score2.floatValue();
int score5 = score2.intValue();
System.out.println("double 类型:"+score3);
System.out.println("float 类型:"+score4);
System.out.println("int 类型:"+score5);
}
运行结果:
double类型:86.0
float类型:86.0
int类型:86
3.3 Java 中基本类型和包装类之间的转换
基本类型和包装类之间经常需要互相转换,以 Integer 为例(其他几个包装类的操作雷同哦):
public static void main(String[] args) {
Integer a = new Integer(3);
int b = a +5;
System.out.println(b);
}
在 JDK1.5 引入自动装箱和拆箱的机制后,包装类和基本类型之间的转换就更加轻松便利了。
那什么是装箱和拆箱呢?我们分别来看下
装箱:把基本类型转换成包装类,使其具有对象的性质,又可分为手动装箱和自动装箱
public static void main(String[] args) {
int i = 10;
Integer x = new Integer(i); // 手动装箱
Integer y = i; // 自动装箱
}
拆箱:和装箱相反,把包装类对象转换成基本类型的值,又可分为手动拆箱和自动拆箱
public static void main(String[] args) {
Integer j = new Integer(8);
int m = j.intValue(); // 手动拆箱
int n = j; // 自动拆箱
}
任务
在编辑器中完成了基本类型和包装类之间的转换,即装箱和拆箱的操作。
请参考注释将 8、11、19、22 代码补充完整
运行结果为:
public static void main(String[] args) {
// 定义double类型变量
double a = 91.5;
// 手动装箱
Double b = new Double(a);
// 自动装箱
Double c = a;
System.out.println("装箱后的结果为:" + b + "和" + c);
// 定义一个Double包装类对象,值为8
Double d = new Double(87.0);
// 手动拆箱
double e = d.doubleValue();
// 自动拆箱
double f = d;
System.out.println("拆箱后的结果为:" + e + "和" + f);
}
运行结果:
装箱后的结果为:91.5和91.5
拆箱后的结果为:87.0和87.0
3.3 单选练习题
解析:
基本类型 int 无法直接转换为包装类 Long 类型,所以选项 C 说法不正确,选择 C
3.4 Java 中基本类型和字符串之间的转换
在程序开发中,我们经常需要在基本数据类型和字符串之间进行转换。
其中,基本类型转换为字符串有三种方法:
1. 使用包装类的 toString() 方法
2. 使用String类的 valueOf() 方法
3. 用一个空字符串加上基本类型,得到的就是基本类型数据对应的字符串
public static void main(String[] args) {
int c = 10;
String str1 = Integer.toString(c);
String str2 = String.valueOf(c);
String str3 = c + "";
}
再来看,将字符串转换成基本类型有两种方法:
1. 调用包装类的 parseXxx 静态方法
2. 调用包装类的 valueOf() 方法转换为基本类型的包装类,会自动拆箱
public static void main(String[] args) {
String str = "8";
int d = Integer.parseInt(str);
int e = Integer.valueOf(str);
}
PS:其他基本类型与字符串的相互转化这里不再一一列出,方法都类似
任务
在编辑器中完成了基本类型和字符串之间的转换。
运行结果为:
请将 6、12 行代码填写完整
public static void main(String[] args) {
double m = 78.5;
//将基本类型转换为字符串
String str1 = Double.toString(m); ;
System.out.println("m 转换为String型后与整数20的求和结果为: "+(str1+20));
String str = "180.20";
// 将字符串转换为基本类型
Double a = Double.parseDouble(str);
System.out.println("str 转换为double型后与整数20的求和结果为: "+(a+20));
}
m 转换为String型后与整数20的求和结果为: 78.520
str 转换为double型后与整数20的求和结果为: 200.2
3.5 单选练习题
解析
基本类型是不能调用方法的,而其包装类具有很多方法,所以选项 B 的说法不正确,选择 B
3.6 使用 Date 和 SimpleDateFormat 类表示时间
在程序开发中,经常需要处理日期和时间的相关数据,此时我们可以使用 java.util 包中的 Date 类。这个类最主要的作用就是获取当前时间,我们来看下 Date 类的使用:
public static void main(String[] args) {
Date d = new Date();
System.out.println(d);
}
使用 Date 类的默认无参构造方法创建出的对象就代表当前时间,我们可以直接输出 Date 对象显示当前的时间,显示的结果如下:
其中, Wed 代表 Wednesday (星期三), Jun 代表 June (六月), 11 代表 11 号, CST 代表 China Standard Time (中国标准时间,也就是北京时间,东八区)。
从上面的输出结果中,我们发现,默认的时间格式不是很友好,与我们日常看到的日期格式不太一样,如果想要按指定的格式进行显示,如 2014-06-11 09:22:30 ,那该怎么做呢?
此时就到了 java.text 包中的 SimpleDateFormat 类大显身手的时候了!!可以使用 SimpleDateFormat 来对日期时间进行格式化,如可以将日期转换为指定格式的文本,也可将文本转换为日期。
public static void main(String[] args) {
Date d = new Date();
// 创建SimpleDateFormat对象,指定目标格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 调用format()方法,格式化时间,转换为指定格式字符串
String today = sdf.format(d);
System.out.println(today);
}
代码中的 “yyyy-MM-dd HH:mm:ss” 为预定义字符串, yyyy 表示四位年, MM 表示两位月份, dd 表示两位日期, HH 表示小时(使用24小时制), mm 表示分钟, ss 表示秒,这样就指定了转换的目标格式,最后调用 format() 方法将时间转换为指定的格式的字符串。
运行结果:2017-12-22 14:04:55
public static void main(String[] args) {
String day = "2014年02月14日 10:30:25";
SimpleDateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
try {
Date date = df.parse(day);
System.out.println("当前时间:"+date);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
代码中的 “yyyy年MM月dd日 HH:mm:ss” 指定了字符串的日期格式,调用 parse() 方法将文本转换为日期。
运行结果:当前时间:Fri Feb 14 10:30:25 CST 2014
一定要注意哦:
1. 调用 SimpleDateFormat 对象的 parse() 方法时可能会出现转换异常,即 ParseException ,因此需要进行异常处理
2. 使用 Date 类时需要导入 java.util 包,使用 SimpleDateFormat 时需要导入 java.text 包
任务
亲, Date 类和 SimpleDateFormat 类的使用您掌握了吗?让我们来检验下吧。
功能:实现将日期转换为指定格式的文本,将文本转换为日期请在编辑器中的第 15、18、27 行中将代码填写完整
运行结果:
public static void main(String[] args) throws ParseException {
// 使用format()方法将日期转换为指定格式的文本
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 创建Date对象,表示当前时间
Date now = new Date();
// 调用format()方法,将日期转换为字符串并输出
System.out.println(sdf1.format(now));
System.out.println(sdf2.format(now));
System.out.println(sdf3.format(now));
// 使用parse()方法将文本转换为日期
String d = "2014-6-1 21:05:36";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 调用parse()方法,将字符串转换为日期
Date date = sdf.parse(d);
System.out.println(date);
}
输出
2017年12月22日 14时32分32秒
2017/12/22 14:32
2017-12-22 14:32:32
Sun Jun 01 21:05:36 CST 2014
3.7 Calendar 类的应用
Date 类最主要的作用就是获得当前时间,同时这个类里面也具有设置时间以及一些其他的功能,但是由于本身设计的问题,这些方法却遭到众多批评,不建议使用,更推荐使用 Calendar 类进行时间和日期的处理。
java.util.Calendar 类是一个抽象类,可以通过调用 getInstance() 静态方法获取一个 Calendar 对象,此对象已由当前日期时间初始化,即默认代表当前时间,如 Calendar c = Calendar.getInstance();
那么如何使用 Calendar 获取年、月、日、时间等信息呢?我们来看下面的代码:
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DATE);
int hour = c.get(Calendar.HOUR);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
System.out.println("当前时间:"+year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second);
}
其中,调用 Calendar 类的 getInstance() 方法获取一个实例,然后通过调用 get() 方法获取日期时间信息,参数为需要获得的字段的值, Calendar.Year 等为 Calendar 类中定义的静态常量。
运行结果: 当前时间:2017-11-22 2:40:45
Calendar 类提供了 getTime() 方法,用来获取 Date 对象,完成 Calendar 和 Date 的转换,还可通过 getTimeInMillis() 方法,获取此 Calendar 的时间值,以毫秒为单位。如下所示:
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
Date date = c.getTime();
Long time = c.getTimeInMillis();
System.out.println("当前时间:"+date);
System.out.println("当前毫秒数:"+time);
}
运行结果:
当前时间:Fri Dec 22 14:44:22 CST 2017
当前毫秒数:1513925062040
任务
亲, Calendar 类的使用您掌握了吗?让我们来检验下吧。
代码编辑器中实现获取 Calendar 对象,并转换为指定格式的时间。请将第 9、12 行代码补充完整
运行结果:
public static void main(String[] args) {
// 创建Calendar对象
Calendar c = Calendar.getInstance();
// 将Calendar对象转换为Date对象
Date date = c.getTime();
// 创建SimpleDateFormat对象,指定目标格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 将日期转换为指定格式的字符串
String now = sdf.format(date);
System.out.println("当前时间:" + now);
}
输出
当前时间:2017-12-22 14:47:49
3.8 使用 Math 类操作数据
Math 类位于 java.lang 包中,包含用于执行基本数学运算的方法, Math 类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.方法名,如: Math.round();
常用的方法:
通过案例我们来认识一下他们的使用吧!!
public static void main(String[] args) {
double a = 12.81;
int b = (int)a;
System.out.println("强制类型转换:"+b);
long c = Math.round(a); // 调用round方法,进行四舍五入
System.out.println("四舍五入:"+c);
double d = Math.floor(a); // 调用floor方法。返回小于参数的最大整数
System.out.println("floor:"+d);
double e = Math.ceil(a); // 调用ceil方法,返回大于参数的最小整数
System.out.println("ceil:"+e);
double x = Math.random(); // 调用random方法,返回[0,1)之间的随机数浮点数
System.out.println("随机数:"+x);
int y = (int)(Math.random()*99); // 产生[0,99)之间的随机整数
System.out.println("产生[0,99)之间的随机整数:"+y);
}
运行结果:
强制类型转换:12
四舍五入:13
floor:12.0
ceil:13.0
随机数:0.5453799978883686
产生[0,99)之间的随机整数:22
PS: Math 类还提供了许多其他方法,各位小伙伴们可以注意关注 wiki ,查阅更多信息
任务
功能:定义一个包含 10 个元素的整型数组,通过随机产生 10 以内的随机数,给数组中的每个元素赋值,并输出结果。
运行结果: 0 3 3 2 6 3 2 7 0 9
注:由于数组元素值为随机产生,所以运行结果不固定,此运行结果仅作为示例
请在编辑器中的第 6、11、17 行中将代码填写完整
public static void main(String[] args) {
// 定义一个整型数组,长度为10
int[] nums = new int[10];
//通过循环给数组赋值
for (int i = 0; i < nums.length; i++) {
// 产生10以内的随机数
int x = (int)(Math.random()*10);
nums[i] = x;// 为元素赋值
}
// 使用foreach循环输出数组中的元素
for (int num : nums) {
System.out.print(num + " ");
}
}
输出
9 2 4 0 4 8 4 1 1 8
4 Java 中的集合框架
4.1 Java 中的集合框架概述
Collection:存储的是单身汪
接口: List:序列、Queue:队列、Set:集、
实现类: ArrayList:数组序列、LinkedList:链表、HashSet:哈希集
接口: Map:存储的是一对一对的夫妇
实现类: HashMap:哈希表
ArrayList、HashSet、HashMap使用频率最高
4.2 Collection 接口 & List 接口简介
4.3 学生选课
备选课程类
/**
* 备选课程类
* @author BG235144
*
*/
public class ListTest {
/**
* 用于存放备选课程的List
*/
public List coursesToSelect;
public ListTest() {
this.coursesToSelect = new ArrayList();
}
/**
* 用于往coursesToSelect中添加课程的方法,
* List中的元素是有序可重复的
*/
public void testAdd() {
/**
* 创建一个课程对象,并通过add方法添加到List当中去
*/
Course cr1 = new Course("1","数据结构");
coursesToSelect.add(cr1);
/**
* 对象存入集合中都会变成Object类型,
* 取出时需要类型转换
*/
Course temp = (Course) coursesToSelect.get(0);
System.out.println(temp);
Course cr2 = new Course("2","c语言");
coursesToSelect.add(0, cr2);
Course temp2 = (Course)coursesToSelect.get(0);
System.out.println(temp2);
coursesToSelect.add(cr1);
/**
* 对象存入集合中都会变成Object类型,
* 取出时需要类型转换
*/
Course temp0 = (Course) coursesToSelect.get(2);
System.out.println(temp0);
// Course cr3 = new Course("3","test");
/**
* bug:java.lang.IndexOutOfBoundsException: Index: 4, Size: 2,
* 数组越界
*/
// coursesToSelect.add(4,cr3);
Course[] course = {new Course("3","离散数学"), new Course("4","汇编语言")};
coursesToSelect.addAll(Arrays.asList(course));
Course cr3 = (Course)coursesToSelect.get(3);
Course cr4 = (Course)coursesToSelect.get(4);
System.out.println(cr3 + "\n" + cr4);
Course[] course2 = {new Course("5","高等数学"), new Course("6","汇编大学英语")};
coursesToSelect.addAll(2,Arrays.asList(course2));
Course cr5 = (Course)coursesToSelect.get(2);
Course cr6 = (Course)coursesToSelect.get(3);
System.out.println(cr5+"\n"+cr6);
}
/**
* 取得List中的元素的方法,
*/
public void testGet() {
int size = coursesToSelect.size();
System.out.println("有如下课程待选:");
for(int i=0;i<size;i++) {
Course cr = (Course)coursesToSelect.get(i);
System.out.println(cr);
}
}
/**
* 通过迭代器来遍历List
*/
public void testIterator() {
/**
* 通过集合的iterator方法,取得迭代器的实例
*/
Iterator it = coursesToSelect.iterator();
System.out.println("有如下课程待选(通过迭代器访问):");
while(it.hasNext()) { // 如果还有元素就返回true
Course cr = (Course)it.next();
System.out.println(cr);
}
}
/**
* 通过for each方法访问集合元素
*/
public void testForEach() {
System.out.println("有如下课程待选(通过for each访问):");
for(Object obj:coursesToSelect) {
Course cr = (Course)obj;
System.out.println(cr);
}
}
/**
* 修改List中的元素
* @param args
*/
public void testModify() {
System.out.println("有如下课程待选(通过set修改):");
coursesToSelect.set(4, new Course("7","毛概"));
testForEach();
}
/**
* 删除List中的元素
* @param args
*/
public void testRemove() {
/**
* remove(Object)
*/
// Course cr = (Course)coursesToSelect.get(4);
// System.out.println("我是课程:"+cr.id+"我即将被删除");
// coursesToSelect.remove(cr);
// System.out.println("成功删除课程:"+cr.id);
/**
* remove(id)
*/
// System.out.println("我是课程:"+4+",我即将被删除");
// coursesToSelect.remove(4);
// System.out.println("成功删除课程:"+4);
/**
* removeAll(list)
*/
System.out.println("即将删除4位置和5位置上的课程!");
Course[] courses = {(Course)coursesToSelect.get(4),(Course)coursesToSelect.get(5)};
coursesToSelect.removeAll(Arrays.asList(courses));
System.out.println("成功删除课程4位置和5位置上的课程:");
testForEach();
}
/**
* 往List中添加一些奇怪的东西
* @param args
*/
public void testType() {
System.out.println("能否往List中添加一些奇怪的东西呢?");
coursesToSelect.add("我不是课程,我只是一个无辜的字符串!");
testForEach();
}
public static void main(String[] args) {
ListTest lt = new ListTest();
lt.testAdd();
/**
* bug:Exception in thread "main" java.lang.ClassCastException:
* java.lang.String cannot be cast to com.amoscxy.Course
*/
lt.testType();
System.out.println();
lt.testGet();
System.out.println();
lt.testIterator();
System.out.println();
lt.testForEach();
System.out.println();
lt.testModify();
System.out.println();
lt.testRemove();
}
}
学生类
/**
* 学生类
* @author BG235144
*
*/
public class Student {
public String id;
public String name;
public Set course;
public Student(String id, String name) {
this.id = id;
this.name = name;
this.course = new HashSet();
}
}
课程类
/**
* 课程类
* @author BG235144
*
*/
public class Course {
public String id;
public String name;
public Course(String id, String name) {
this.id = id;
this.name = name;
}
public Course() {
}
@Override
public String toString() {
return "Course [id=" + id + ", name=" + name + "]";
}
}
public class ChildCourse extends Course{
public String id;
public String name;
public ChildCourse(String id, String name) {
this.id = id;
this.name = name;
}
public ChildCourse() {
}
@Override
public String toString() {
return "Course [id=" + id + ", name=" + name + "]";
}
}
4.4 学生选课—应用泛型管理课程
public class TestGeneric {
/**
* 带有泛型---Course的List类型属性
*/
public List<Course> courses;
public TestGeneric() {
this.courses = new ArrayList<Course>();
}
/**
* 测试添加
*/
public void testAdd() {
Course cr1 = new Course("1","大学语文");
courses.add(cr1);
/**
* 泛型集合中,
* 不能添加泛型规定的类型及其子类型以外的对象,
* 否则会报错
*/
// courses.add("能否添加一些奇怪的东西呢?");
Course cr2 = new Course("2","Java基础");
courses.add(cr2);
testForEach();
}
/**
* 测试循环遍历
*/
public void testForEach() {
for(Course cr:courses) {
System.out.println(cr);
}
}
/**
* 泛型集合可以添加泛型的子类型的对象实例
*/
public void testChild() {
System.out.println("泛型集合可以添加泛型的子类型的对象实例:");
ChildCourse ccr = new ChildCourse();
ccr.id = "3";
ccr.name = "我是子类型的课程对象实例";
courses.add(ccr);
testForEach();
}
/**
* 泛型必须是引用类型,
* 如果要使用基本类型,可以用它们的包装类
*/
public void testBasicType() {
System.out.println("基本类型不能用于泛型,如果要用,就用它们的包装类:");
/**
* 基本类型不能用于泛型
*/
// List<int> list = new List<int>();
List<Integer> list = new ArrayList<Integer>();
list.add(1);
System.out.println("基本类型的包装类作为泛型:"+list.get(0));
}
/**
*
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TestGeneric tg = new TestGeneric();
tg.testAdd();
System.out.println();
tg.testChild();
System.out.println();
tg.testBasicType();
}
}
4.5 学生选课—通过 Set 集合管理课程
Set中,添加某个对象,无论添加多少次,最终只会保留一个该对象(的引用),并且,保留的是第一次添加的那一个
// 打印输出学生所选的课程
public void testForEachForSet(Student student) {
/**
* 遍历Set中的每一个元素只能用foreach或者iterator方法,
* 不能用get方法,
* 因为Set中的元素是无序的,
* 因此只能用foreach循环或iterator循环将元素一个一个迭代出来,
* 每一次迭代出来的结果都是不一样的
*
*/
for(Course cr:student.courses) {
System.out.println(cr);
}
}
5 Java 中的集合框架(中)
5.1 Map & HashMap 简介
5.2 学生选课—使用 Map 添加学生、删除 Map 中的学生、修改 Map 中的学生
public class MapTest {
/**
* 用来承装学生类型对象
* @param args
*/
public Map<String,Student> students;
/**
* 在构造器中初始化students属性
* @param args
*/
public MapTest() {
this.students = new HashMap<String,Student>();
}
/**
* 测试添加:输入学生ID,判断是否被占用,
* 若未被占用,则输入姓名,创建新学生对象,并且添加到Students中
* @param args
*/
public void testPut() {
// 创建一个Scanner对象,用来获取输入的学生ID和姓名
Scanner console = new Scanner(System.in);
int i = 0;
while(i < 3) {
System.out.println("请输入学生ID:");
String ID = console.next();
// 判断该ID是否被占用
Student st = students.get(ID);
if(st == null) {
// 提示输入学生姓名
System.out.println("请输入学生姓名:");
String name = console.next();
// 创建新的学生对象
Student newStudent = new Student(ID,name);
// 通过调用student的put方法,添加ID-学生映射
students.put(ID, newStudent);
System.out.println("成功添加学生:"+students.get(ID).name);
i++;
}else {
System.out.println("该学生ID已被占用!");
continue;
}
}
}
/**
* 测试Map的keySet方法
* @param args
*/
public void testKeySet() {
/**
* Map的keySet方法,返回的是所有key的Set集合
*/
Set<String> keySet = students.keySet();
// 取得students的容量
System.out.println("总共有:"+students.size()+"个学生!");
// 遍历keySet,取得每一个键,再调用get方法取得每个键对应的value
for(String stuID:keySet) {
Student st = students.get(stuID);
if(st!=null) {
System.out.println("学生:"+st.name);
}
}
}
/**
* 测试删除Map中的映射
* @param args
*/
public void testRemove() {
// 获取从键盘输入的待删除学生ID字符串
Scanner console = new Scanner(System.in);
while(true) {
// 提示输入待删除的学生的ID
System.out.println("请输入要删除的学生的ID!");
String ID = console.next();
// 判断该ID是否有对应的学生对象
Student st = students.get(ID);
if(st==null) {
// 提示输入的ID并不存在
System.out.println("该ID不存在!");
continue;
}
students.remove(ID);
System.out.println("成功删除学生:"+st.name);
break;
}
}
/**
* 通过entrySet方法来遍历Map
* @param args
*/
public void testEntrySet() {
// 通过entrySet方法,返回Map中的所有键值对
Set<Entry<String,Student>> entrySet = students.entrySet();
for(Entry<String,Student> entry:entrySet) {
System.out.println("取得键:"+entry.getKey());
System.out.println("对应的值为:"+entry.getValue().name);
}
}
/**
*
* @param args
*/
public void testModity() {
// 请输入要修改的学生ID
System.out.println("请输入要修改的学生ID:");
Scanner console = new Scanner(System.in);
while(true){
String stuID = console.next();
Student student = students.get(stuID);
if(student == null) {
System.out.println("该ID不存在!请重新输入!");
continue;
}
System.out.println("当前该学生ID,所对应的学生为:"+student.name);
System.out.println("请输入新的学生姓名:");
String name = console.next();
Student newStudent = new Student(stuID,name);
students.put(stuID, newStudent);
System.out.println("修改成功!");
break;
}
}
public static void main(String[] args) {
MapTest mt = new MapTest();
mt.testPut();
mt.testKeySet();
mt.testRemove();
mt.testEntrySet();
mt.testModity();
mt.testEntrySet();
}
}
6 Java 中的集合框架(下)
6.1 学生选课—判断 List 中课程是否存在
/**
* 测试List的contains方法
* @param args
*/
public void testListContains() {
Course course = (Course)coursesToSelect.get(0);
System.out.println("取得课程:"+course.name);
System.out.println("备选课程中是否包含课程:"+course.name
+","+coursesToSelect.contains(course)); // true
// 创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course(course.id,course.name);
System.out.println("新创建课程:"+course2.name);
System.out.println("备选课程中是否包含课程:"+course2.name
+","+coursesToSelect.contains(course2)); // false
}
List的contains(obj)的实现原理
Course 类中重写equals方法
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Course other = (Course) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
/**
* 测试List的contains方法
* @param args
*/
public void testListContains() {
Course course = (Course)coursesToSelect.get(0);
System.out.println("取得课程:"+course.name);
System.out.println("备选课程中是否包含课程:"+course.name
+","+coursesToSelect.contains(course)); // true
// 创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course(course.id,course.name);
System.out.println("新创建课程:"+course2.name);
System.out.println("备选课程中是否包含课程:"+course2.name
+","+coursesToSelect.contains(course2)); // true
}
判断是否包含多个元素
6.2 学生选课—判断 Set 中课程是否存在
/**
* 测试Set的contains方法
* @param args
*/
public void testSetContains() {
System.out.println("请输入学生已选的课程名称:");
Scanner console = new Scanner(System.in);
String name = console.next();
// 创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course();
course2.name = name;
System.out.println("新创建课程:"+course2.name);
System.out.println("备选课程中是否包含课程:"+course2.name
+","+student.courses.contain(course2)); // false
}
Set的contains方法实现原理
重写Course的hashCode方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/**
* 测试Set的contains方法
* @param args
*/
public void testSetContains() {
System.out.println("请输入学生已选的课程名称:");
Scanner console = new Scanner(System.in);
String name = console.next();
// 创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course();
course2.name = name;
System.out.println("新创建课程:"+course2.name);
System.out.println("备选课程中是否包含课程:"+course2.name
+","+student.courses.contain(course2)); // true
}
6.3 学生选课—获取 List 中课程的位置
用 indexOf(Object) 方法来获取某元素的索引位置
if(coursesToSelect.contains(course2)) {
System.out.println("课程:"+course2.name+"的索引位置为:"
+"coursesToSelect.indexOf(course2)");
}
indexOf(Object)和lastIndexOf(Object)方法的工作原理
6.4 学生选课—判断 Map 中是否包含指定的 key 和 value
Student 中重写 equals(Object) 方法
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Student))
return false;
Student other = (Student) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
在 Map 中,用 containsKey() 方法,来判断是否包含某个 Key 值,用 ContainsValue() 方法,来判断是否包含某个 Value 值
/**
* 测试Map中,是否包含某个Key值或者某个Value值
* @param args
*/
public void testContainsKeyOrValue() {
/**
* 在 Map 中,用 containsKey() 方法,来判断是否包含某个 Key 值,
* 用 ContainsValue() 方法,来判断是否包含某个 Value 值
*/
System.out.println("请输入学生id:");
Scanner sid = new Scanner(System.in);
System.out.println("请输入学生姓名:");
Scanner sname = new Scanner(System.in);
String id = sid.next();
String name = sname.next();
System.out.println("您输入的学生ID为:"+id+",在学生映射表中是否存在:"
+students.containsKey(id));
if(students.containsKey(id)) {
System.out.println("对应的学生为:"+students.get(id).name);
}
System.out.println("您输入的学生Value为:"+name+",在学生映射表中是否存在:"
+students.containsValue(name));
if(students.containsValue(new Student(null,name))) {
System.out.println("包含学生:"+name);
}else {
System.out.println("不包含学生:"+name);
}
}
6.5 应用 Collections.sort() 实现 List 排序
6.6 学生选课—尝试对学生序列排序
6.7 Comparable & Comparator 简介
6.8 学生选课— 实现学生序列排序
实现 Comparable 接口 和 compareTo 方法
/**
* 学生类
* @author BG235144
*
*/
public class Student implements Comparable<Student>{
public String id;
public String name;
public Set<Course> courses;
public Student(String id, String name) {
this.id = id;
this.name = name;
this.courses = new HashSet<Course>();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Student))
return false;
Student other = (Student) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int compareTo(Student o) {
// TODO Auto-generated method stub
return this.id.compareTo(o.id);
}
}
就可以对其它类型泛型的 List 进行排序,以 Student 为例
Collections.sort(studentList);
排序规则
实现 Comparator 接口
就可以对其它类型泛型的 List 进行排序,以 Student 为例
Collection.sort(studentList, new studentComparator());
以及它们的增删改查方法
相关文章
- 暂无相关文章
用户点评