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('
');
			}
		}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

参考资料

原文地址:https://www.cnblogs.com/m3182218/p/5348067.html