20145227 《Java程序设计》第5周学习总结
20145227 《Java程序设计》第5周学习总结
教材学习内容总结
第八章 异常处理
8.1 语法与继承结构
1、使用try 、catch
- java中所有错误都会被打包为对象,可以尝试(try)捕捉(catch)代表错误的对象后做一些处理。
- 下面的是一个正确的小程序。代码如下:
import java.util.Scanner;
public class Average{
public static void main(String[] args){
Scanner console=new Scanner(System.in);
double sum=0;
int count=0;
while(true){
int number=console.nextInt();
if(number==0){
break;
}
sum+=number;
count++;
}
System.out.printf("average %.2f%n",sum/count);
}
}
-
正确输入时结果截图:
-
当输入错误时可以使用try、catch语法,JVM会尝试执行try区块中的程序代码。如果发生错误,执行流程会跳离错误发生点,然后比较catch括号中声明的类型,是否符合被抛出的错误对象类型,如果是的话,就执行catch区块中的程序代码。如果还在while循环中,还可继续下一个循环流程。
-
代码如下:
import java.util.*;
public class Average3{
public static void main(String[] args){
Scanner console=new Scanner(System.in);
double sum=0;
int count=0;
while(true){
try{
int number=console.nextInt();
if(number==0){
break;
}
sum+=number;
count++;
}catch (InputMismatchException ex){
System.out.printf("略过非整数输入:%s%n",console.next());
}
}
System.out.printf("average %.2f%n",sum/count);
}
}
- 结果截图
2、学会使用throw,throws:
- 当方法设计流程出现异常,不知道如何处理时,可以用throws FileNotFoundException抛出异常,让调用方法的客户端来处理。
- throw总是出现在函数体中,用来抛出一个异常。程序会在throw语句后立即终止。
- 以实际例子来说明。代码如下:
import java.io.*;
import java.util.Scanner;
public class FileUtil{
public static String readFile(String name)throws FileNotFoundException{
StringBuilder text=new StringBuilder();
try{
Scanner console=new Scanner(new FileInputStream(name));
while(console.hasNext()){
text.append(console.nextLine())
.append('\n');
}
}catch(FileNotFoundException ex){
ex.printStackTrace();
throw ex;
}
return text.toString();
}
}
8.2 异常与资源管理
1、使用finally
- 无论try区块中有无发生异常,若撰写有finally区块,则finally区块一定会被执行。如果程序撰写的流程先return了,而且也有finally区块,finally区块会先执行完后,再将值返回。例如下面这个范例会先显示finally、、、,然后再显示1 。
- 代码如下:
public class FinallyDemo{
public static void main(String[] args){
System.out.println(test(true));
}
static int test(boolean flag){
try{
if(flag){
return 1;
}
}finally{
System.out.println("finally...");
}
return 0;
}
}
- 结果截图:
2、自动尝试关闭资源
- 在JDK7之后,新增了尝试关闭资源语法,想要尝试自动关闭资源的对象,是撰写在try之后的括号中。
- 若一个异常被catch后的处理过程引发另一个异常,通常会抛出第一个异常作为响应,addSuppressed()方法是JDK7在java.lang.Throwable中新增的方法,可将第二个异常记录在第一个异常之中,JDK7中与之对应的是个体getSuppressed()方法,可返回Throwable[],代替先前被addSuppressed()记录的各个异常对象。
3、java.lang.AutoCloseable接口
-
JDK7的尝试关闭资源语法可套用的对象,必须操作java.lang.AutoCloseable接口,这是JDK7新增的接口。尝试关闭资源语法也可以同时关闭两个以上的对象资源,只要中间以分号相隔。在try的括号中,越后面撰写的对象资源会越早被关闭。
-
同时关闭两个以上的对象资源,代码如下:
import static java.lang.System.out;
public class AutoClosableDemo2{
public static void main(String[] args){
try(ResourceSome some=new ResourceSome();
ResourceOther other=new ResourceOther()){
some.doSome();
other.doOther();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
class ResourceSome implements AutoCloseable{
void doSome(){
out.println("做一些事");
}
@Override
public void close() throws Exception{
out.println("资源Some被关闭");
}
}
class ResourceOther implements AutoCloseable{
void doOther(){
out.println("做其他事");
}
@Override
public void close() throws Exception{
out.println("资源Other被关闭");
}
}
- 结果截图:
第九章 Collection和Map
9.1 使用Collection收集对象
1.认识Collection架构:
- 收集对象的行为,像是新增对象的add()方法、移除对象的remove()方法等,都是定义在java.util.Collection中,既然可以收集对象,也要能逐一取得对象,这就是java.lang.Iterable定义的行为,它定义了iterator()方法返回java.util.Iterator操作对象,可以让你逐一取得收集的对象。
- 收集对象的共同行为定义在Collection中,然而收集对象会有不同的需求,如果希望收集时记录每个对象的索引顺序,并可依索引取回对象,这样的行为定义在java.util.List接口中。如果希望收集的对象不重复,具有集合的行为,则由java.util.Set定义。如果希望收集对象时,以队列排列。收集的对象加入至尾端,取得对象时从前端,则可以使用java.util.Queue。如果希望对Queue的两端进行加入、移除等动作,则可以使用java.util.Deque。
2.具有索引的List:
- List是一种Collection,作用是收集对象,并以索引方式保留收集的对象顺序,其操作类之一是java.util.ArrayList。
- 代码如下
import java.util.*;
import static java.lang.System.out;
public class Guest {
public static void main(String[] args) {
List names = new ArrayList();
collectNameTo(names);
out.println("访客名单:");
printUpperCase(names);
}
static void collectNameTo(List names){
Scanner console = new Scanner(System.in);
while(true){
out.print("访客名称:");
String name = console.nextLine();
if(name.equals("quit")){
break;
}
names.add(name);
}
}
static void printUpperCase(List names){
for(int i = 0;i<names.size();i++){
String name=(String) names.get(i);
out.println(name.toUpperCase());
}
}
}
- 结果截图:
- java.util.LinkedList也操作了List接口,那么什么时候使用ArrayList,什么时候用LinkedList呢?简而言之,ArrayList适合排序的时候用,可得到较好的速度表现。而LinkedList采用了链接结构,当需要调整索引顺序时,比较适用。
3.内容不重复的Set:
- 同样是收集对象,在收集过程中若有相同对象,则不再重复收集,若有这类需求,可以使用Set接口的操作对象,String的Split()方法,可以指定切割字符串的方式。一般用hashcode()与equals()来判断对象是否相同。
- 以实例来说明,代码如下:
import java.util.*;
public class WordCount {
public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
System.out.print("请输入英文:");
Set words = tokenSet(console.nextLine());
System.out.printf("不重复单字有 %d 个:%s%n",words.size(),words);
}
static Set tokenSet(String line)
{
String[] tokens = line .split(" ");
return new HashSet(Arrays.asList(tokens));
}
}
- 结果截图
4.支持队列操作的Queue
- Queue继承自Collection,所以也具有Collection的add()、remove()、element()等方法,然而Queue定义了自己的offer()、poll()与peek()等方法。最主要的差别在于,add()、remove()、element()等方法操作失败时会抛出异常,而offer()、poll()、peek()等方法操作失败时会返回特定值。
- 以实际例子来说明。代码如下:
import java.util.*;
interface Request
{
void execute();
}
public class RequestQuene
{
public static void main (String[] args)
{
Queue requests = new LinkedList();
offerRequestTo(requests);
process(requests);
}
static void offerRequestTo(Queue requests)
{
for (int i = 1; i < 6;i++)
{
Request request = new Request()
{
public void execute()
{
System.out.printf("处理数据 %f%n",Math.random());
}
};
requests.offer(request);
}
}
static void process (Queue requests)
{
while(requests.peek() != null)
{
Request request = (Request) requests.poll();
request.execute();
}
}
}
- 结果截图:
5.使用泛型
- 在使用Collection收集对象时,由于事先不知道被收集对象的形态,因此内部操作时,都是使用object来参考被收集的对象,取回对象时也是以object类型返回。所以若想针对某类定义的行为操作,必须告诉编译程序,让对象重新扮演该类型。JDK5之后增加了泛型语法。
6.Comparable与Comparator
- 在收集对象之后,对对象进行排序是常有的动作,不过不用亲自动手,java.util.Collection提供有sort()方法,由于必须要有索引才能进行排序,因此Collection的sort()方法接受List操作对象。
9.2 键值对应的Map
1.常用Map操作类
- 常用的Map操作类为java.util.HashMap与java.util.TreeMap,其继承自抽象类java.util.AbstractMap。建立Map操作对象时,可以使用泛型语法指定键与值的类型。如果使用TreeMap建立键值对应,则键的部分将会排序,条件是作为键的对象必须操作Comparable接口,或者是在建立TreeMap时指定操作Comparator接口的对象。
- 代码如下:
import java.util.*;
import static java.lang.System.out;
public class Messages {
public static void main(String[] args){
Map<String,String> messages=new HashMap<>();
messages.put("Justin","Hello!Justin的信息!");
messages.put("Monica","给Monica的悄悄话!");
messages.put("Irene","Irene的可爱猫喵喵叫!");
Scanner console=new Scanner(System.in);
out.print("取得谁的信息");
String message=messages.get(console.nextLine());
out.println(message);
out.println(messages);
}
}
- 结果截图
2.访问Map键值
- Map虽然与Collection没有继承上的关系,但它们却是彼此的API。如果想取得Map中所有的键,可以调用Map的keySet() 返回Set对象,由于键是不重复的,所以用Set操作返回是理所当然的做法。如果想取得Map中所有的值,则可以使用values()返回Collection对象。
- 代码如下
import java.util.*;
import static java.lang.System.out;
public class MapKeyValue {
public static void main(String[] args){
Map<String,String> map=new HashMap<>();
map.put("one","一");
map.put("two","二");
map.put("three","三");
out.println("显示键");
map.keySet().forEach(key -> out.println(key));
out.println("显示值");
map.values().forEach(key -> out.println(key));
}
}
-
结果截图
-
代码托管截图
- 新增代码行数
教材学习中的问题和解决过程
这周学习了第八章和第九章的内容。第八章和第九章主要就是介绍一些类的应用,我先把教材上的内容看了一遍,总结了书上总共介绍了多少种API,每一种API的架构是什么,每一种API的作用与注意事项是什么。看完之后有了一个大概的知识框架,然后又按照书上的代码都实践了一遍,加深了对教材内容的理解。写完博客后,感觉对这两章的内容理解得更加透彻了。
代码调试中的问题和解决过程
在编译AutoClosableDemo.java的时候,一开始出现了下图的错误:
后来发现我把后面的AutoCloseableDemo写成了前面的AutoClosableDemo,仅仅只是缺少一个e,结果却有很大差异。
其他(感悟、思考等,可选)
学习java已经五个星期了,这周学习了java第八章第九章的内容。从上周开始很多同学就开始对java感到疲倦了,我也不例外,进入了一个倦怠期。以前我总是把Java的学习推到周末,导致整个周末的时间全用在java上面了,就感觉到很厌烦。这周我在前面几天敲出了代码,把那些例子都运行实践了一遍,看了一遍教材。到了周末就只需要写博客了,这次周末就只花了一个晚上的时间来写博客,效率提高了很多。但是到现在为止,我还是只会跟着教材上的例子去敲代码、去实践,但要是让我自己敲代码做一个小项目我却是做不到的。这是我学习过程中很大的一个问题。我希望能通过自己的努力不依赖教材自己独立编写出一些小项目。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 200/400 | 1/3 | 20/40 | |
第三周 | 500/900 | 1/4 | 30/70 | |
第四周 | 1072/1972 | 1/5 | 30/100 | |
第五周 | 953/2925 | 1/6 | 40/140 |