20145330第六周《Java学习笔记》###

.

这周算是很忙碌的一周。因为第六周陆续很多实验都开始进行,开始要准备和预习的科目日渐增多,对Java分配的时间不知不觉就减少了,然而第十和十一章内容相对有很多,所以效率是一件很重要的事情。

第十章 输入与输出

  • Java将输入输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象。

    • 比喻来说,数据就好比水,串流就好比水管,通过水管的衔接,水由一端流向另一端
    • 如果想要将数据从来源取出,可以使用输入串流。
    • 如果想要将数据写入目的地,可以使用输出串流。
  • 标准输入输出
    • System.in: 标准输入,默认关联到键盘(终端输入)
    • System.out: 标准输出,默认关联到显示器(终端输出)
    • System.err: 标准错误,默认关联到显示器(终端输出)
    • 输入输出重定向:setIn,setOut,setErr
  • 来源与目的都不知道的情况下,可以设计一个通用的dump()方法,如果要将某个文档读入并另存为另一个文档,则可以这么使用:

import java.io.*; public class StreamIO {
public static void dump(InputStream src, OutputStream dest)
throws IOException {
try (InputStream input = src; OutputStream output = dest) {
byte[] data = new byte[1024];
int length;
while ((length = input.read(data)) != -1) {
output.write(data, 0, length);
}
}
}
}

import java.io.*; public class Copy {
public static void main(String[] args) throws IOException {
StreamIO.dump(
new FileInputStream(args[0]),
new FileOutputStream(args[1])
);
}
}

  • 这个程序可以由命令行自变量指定读取的文档来源与写出的目的地
  • 如果要从HTTP服务器读取某个网页,另存为文档,也可以使用这里设计的dump()方法,例如:

import java.io.*;
import java.net.URL; public class Download {
public static void main(String[] args) throws IOException {
URL url = new URL(args[0]);
InputStream src = url.openStream();
OutputStream dest = new FileOutputStream(args[1]);
StreamIO.dump(src, dest);
}
}

  • 串流继承架构

    • 标准输入输出

      • 可以使用systemsetIn()方法指定InputStream实例,重新指定便准输入来源。

import java.io.*;
import java.util.*; public class StandardIn {
public static void main(String[] args) throws IOException {
System.setIn(new FileInputStream(args[0]));
try (Scanner file = new Scanner(System.in)) {
while (file.hasNextLine()) {
System.out.println(file.nextLine());
}
}
}
}

- 除了 system.in 与 system.out 之外,还有个system.err 为PrintStream 实例,成为标准错误输出串流,它是用来立即显示错误信息。
  • FileInputStream与FileOutputStream

    • FileInputStream是InputStream的子类,可以指定文件名创建实例,一旦创建文档就开启,接着就可以用来读取数据。
    • FileOutputStream是OutputStream的子类,可以指定文件名创建实例,一旦创建文档就开启,接着就可以用来读出数据。
    • FileInputStream与FileOutputStream在读取、写入文档时,是以字节为单位,通常会使用一些高阶类加以打包,进行一些高阶操作。
  • ByteArrayInputStream与ByteArrayOutputStream

    • ByteArrayInputStream是InputStream的子类,可以指定byte数组创建实例,一旦创建就可将byte数组当作数据源进行读取。
    • ByteArrayOutputStream同理
  • 串流处理装饰器

    • BufferedInputStream与BufferedOutputStream

      • BufferedInputStream与BufferedOutputStream主要在内部提供缓冲区功能,操作上与InputStream与OutputStream并没有太大差别。例如,改写前面的IO.dump()为BufferedIO.dump()方法:

import java.io.*; public class BufferedIO {
public static void dump(InputStream src, OutputStream dest)
throws IOException {
try(InputStream input = new BufferedInputStream(src);
OutputStream output = new BufferedOutputStream(dest)) {
byte[] data = new byte[1024];
int length;
while ((length = input.read(data)) != -1) {
output.write(data, 0, length);
}
}
}
}
  • DataInputStream与DataOutputStream

    • 实际应用例子,下面的Member类可以调用save()储存Member实例本身的数据:

import java.io.*; public class Member { private String number;
private String name;
private int age; public Member(String number, String name, int age) {
this.number = number;
this.name = name;
this.age = age;
} public String getNumber() {
return number;
} public void setNumber(String number) {
this.number = number;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return String.format("(%s, %s, %d)", number, name, age);
} public void save() throws IOException {
try(DataOutputStream output =
new DataOutputStream(new FileOutputStream(number))) {
output.writeUTF(number);
output.writeUTF(name);
output.writeInt(age);
}
} public static Member load(String number) throws IOException {
Member member;
try(DataInputStream input =
new DataInputStream(new FileInputStream(number))) {
member = new Member(
input.readUTF(), input.readUTF(), input.readInt());
}
return member;
}
}
  • ObjectInputStream与ObjectOutputStream

    • ObjectInputStream提供readObject()方法将数据读入为对象,ObjectOutputStream提供writeObject()方法将对象写至目的地
  • 字符处理类

    • Reader与Writer继承结构

      • 针对字符数据的读取,JavaSE提供了java.io.Reader类,其抽象化了字符数据读入的来源。
      • 针对字符数据的写入,JavaSE提供了java.io.Writer类,其抽象化了字符数据读入的目的地。
      • FileReader与FileWriter则可以对文档做读取与写入,读取或写入时默认会实用操作系统默认编码来做字符转换。

import java.io.*; public class CharUtil { public static void dump(Reader src, Writer dest) throws IOException { try(Reader input = src; Writer output = dest) {
char[] data = new char[1024];
int length;
while((length = input.read(data)) != -1) {
output.write(data, 0, length);
}
}
}
}
  • 字符处理装饰器

    • InputStreamReader与OutputStreamWriter

      • 串流处理的字节数据,实际上代表某些字符的编码数据
    • BufferedReader与BufferedWriter
      • 可对Reader、Writer提供缓冲区作用,在处理字符输入输出时,对效率也会有所帮助
    • PrintWriter
      • 除了可以对OutputStream打包之外,还可以对Writer进行打包,提供print()、printLn()、format()等方法。

import java.io.*; public class CharUtil2 { public static void dump(Reader src, Writer dest) throws IOException {
try(Reader input = src; Writer output = dest) {
char[] data = new char[1024];
int length;
while((length = input.read(data)) != -1) {
output.write(data, 0, length);
}
}
} public static void dump(InputStream src, OutputStream dest,
String charset) throws IOException {
dump(
new InputStreamReader(src, charset),
new OutputStreamWriter(dest, charset)
);
} //
public static void dump(InputStream src, OutputStream dest)
throws IOException {
dump(src, dest, System.getProperty("file.encoding"));
}
}

线程与并行API##

  • 要让目前流程暂停指定时间,可以使用java.lang.Thread的静态sleep()方法,指定的单位是毫秒,调用这个方法必须处理java.lang.InterruptedException

  • Thread与Runnable

  • 撰写多线程程序的方式:操作Runnable接口,在run()中定义额外流程;继承Thread类,在run()中定义额外流程;

  • 差别:操作Runnable接口的好处就是较有弹性,类还有机会继承其他类;若继承了Thread类,那该类就是一种Thread,通常是为了直接利用Thread中定义的一些方法,才会继承Thread来操作。

  • 如果主程序中启动了额外线程,默认会等待被启动的所有线程都执行完run()方法才中止JVM。如果一个Thread被标示为Daemon线程,在所有的非Daemon线程都结束时,JVM自动就会终止。


public class DaemonDemo { public static void main(String[] args) {
Thread thread = new Thread(() -> {
while (true) {
System.out.println("Orz");
}
});
// thread.setDaemon(true);
thread.start();
}
}
  • 在调用Thread实例start()方法后,基本状态为可执行(Runnable)、被阻断(Blocked)、执行中(Running)。
  • 线程有其优先权,可使用Thread的setPriority()方法设定优先权,可设定值为1到10,默认是5,超出1到10外的设定值会抛出IllegalArgumentException。数字越大优先权越高,排班器越优先排入CPU,如果优先权相同,则输流执行。
  • 线程完成run()方法后,就会进入Dead,进入Dead(或已经调用过start()方法)的线程不可以再次调用start()方法,否则会抛出IllegalArgumentException。
  • 如果要停止线程,最好自行操作,让线程跑完应有的流程,而非调用Thread的stop()方法。不仅停止线程必须自行根据条件操作,线程的暂停、重启,也必须视需求操作,而不是直接调用suspend()、resume()等方法。
  • 每个线程产生时,都会归入某个线程群组,这视线程是在哪个群组中产生,如在main()主流程中产生一个线程,该线程会属于main线程群组。如果没有指定,则归入产生该子线程的线程群组,也可以自行指定线程群组,线程一旦归入某个群组,就无法更换群组。
  • 每个对象都会有个内部锁定,或称为监控锁定。被标示为synchronized的区块将会被监控,任何线程要执行synchronized区块都必须先取得指定的对象锁定。
  • 如果在方法上标示synchronized,则执行方法必须取得该实例的锁定。synchronized不只可声明在方法上,也可以描述句方式使用。不正确的使用可能会造成死结。

class Resource { private String name;
private int resource; Resource(String name, int resource) {
this.name = name;
this.resource = resource;
} String getName() {
return name;
} synchronized int doSome() {
return ++resource;
} synchronized void cooperate(Resource resource) {
resource.doSome();
System.out.printf("%s 整合 %s 的资源%n",
this.name, resource.getName());
}
} public class DeadLockDemo { public static void main(String[] args) {
Resource resource1 = new Resource("resource1", 10);
Resource resource2 = new Resource("resource2", 20); Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
resource1.cooperate(resource2);
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
resource2.cooperate(resource1);
}
}); thread1.start();
thread2.start();
}
}
  • Java的synchronized提供的是可重入同步,也就是线程取得某对象锁定后,若执行过程中又要执行synchronized,尝试取得锁定的对象又是同一个,则可以直接执行。
  • 执行synchronized范围的程序代码期间,若调用锁定对象的wait()方法,线程会释放对象锁定,并进入对象等待集合而处于阻断状态,其他线程可以竞争对象锁定,取得锁定的线程可以执行synchronized范围的程序代码。
  • 放在等待集合的线程不会参与CPU排班,wait()可以指定等待时间,时间到之后线程会再次加入排班,如果指定时间0或不指定,则线程会持续等待,直到被中断(调用interrupt()或是告知notify())可以参与排班。
  • 在使用高级并行API时,Lock接口的操作对象可实现synchronized的功能。

import java.util.Arrays; public class ArrayList {
private Object[] list;
private int next; public ArrayList(int capacity) {
list = new Object[capacity];
} public ArrayList() {
this(16);
} public void add(Object o) {
if(next == list.length) {
list = Arrays.copyOf(list, list.length * 2);
}
list[next++] = o;
} public Object get(int index) {
return list[index];
} public int size() {
return next;
}
}
  • 在使用高级并行API时,Condition接口的操作对象可实现Object的wait()、notify()、notifyAll()功能。在使用高级并行API时,Future接口的操作对象可以让你在未来取得执行结果。

教材学习中的问题

  • 撰写单线程序、多线程程序的方式差别:操作Runnable接口的好处就是较有弹性,类还有机会继承其他类;若继承了Thread类,那该类就是一种Thread,通常是为了直接利用Thread中定义的一些方法,才会继承Thread来操作。

代码托管截图



学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 300/500 2/4 18/38
第三周 500/1000 3/7 22/60
第四周 300/1300 2/9 30/90
第五周 300/1600 1/10 20/110
第六周 250/1850 2/12 20/130

参考资料###

  • 《Java学习笔记》

20145330第六周《Java学习笔记》的更多相关文章

  1. 《第六周java学习笔记》

    教材知识点总结 Java 把 String 类定义为 final 类. new 运算符首先分配内存空间并在内存空间中放入字符序列,然后计算出引用.(new String(char a[],int st ...

  2. 20165236 第六周Java学习总结

    20165236 第六周Java学习总结 一. 第八章内容: 1.String 类: String对象.常量对象:字符串并置: 常用方法: length,equals,startsWith,compa ...

  3. 20145307陈俊达第六周JAVA学习总结

    20145307陈俊达第六周JAVA学习总结 知识点梳理 第十章节 S1 ·若要将数据从来源中取出,可以使用输入串流:若要将数据写入目的地,可以使用输出串流.在java中,输入串流代表对象为java. ...

  4. 第六周java学习总结

    学号 20175206 <Java程序设计>第六周学习总结 教材学习内容总结 第七章: 主要内容 内部类 匿名类 异常类 断言 重点和难点 重点:内部类和异常类的理解 难点:异常类的使用 ...

  5. 20145231第二周Java学习笔记

    20145231 <Java程序设计>第2周学习总结 教材学习内容总结 本周的学习采用的依然是先看课本,再看视频,然后实践敲代码,最后根据学习笔记总结完成博客. 第三章:基础语法 知识点比 ...

  6. 2017-04-21周Java学习笔记

    2017-04-21-周Java学习笔记... -------------------------------------- 计算机起源于:战争中的炮弹轨道计算.Unix操作系统是使用C语言编写的操作 ...

  7. 2019年8月5日~8月11日 第六周JAVA学习总结

    本周主要进行了对JAVA基础的学习和PTA代码的编写,平均每天花在学习上的时间约3个小时,花在代码上的时间约2个小时,花在解决问题上的时间约1.5个小时. 下周打算继续JAVA的学习,完成java面向 ...

  8. 201521123105 第六周Java学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 1.clone方法1.1 Object对象 ...

  9. 20165319第五周java学习笔记

    教材内容总结 1.String类和StringBuffer类都覆盖了toString方法,都是返回字符串. 所以带不带toString效果是一样的. 2.instanceOf运算符可以用来判断某个对象 ...

  10. 第六周LINUX学习笔记

    DNS服务 DNS:Domain Name Service //协议     实现:BIND(Berkeley Internet Name Domain)     监听端口:        UDP:5 ...

随机推荐

  1. 利用YaHoo YUI实现Javascript CSS 压缩 分类: C# 2014-07-13 19:07 371人阅读 评论(0) 收藏

    网站优化时,往往需要对js文件,css文件进行压缩,以达到减少网络传输数据,减少网页加载时间:利用YaHoo的YUI可以实现Javascript,CSS,压缩,包括在线的js压缩和程序压缩,发现C#也 ...

  2. vim实现全选功能

    转自:http://blog.csdn.net/csh159/article/details/7533872 曾经也在找看看有没有快捷的方法全选,但是网上很多都是重复,并且错误的,比如: 1,$y,这 ...

  3. VS2010 打开 VS2012 的项目

    用 VS2010 打开 VS2012 项目,只需两步. 1. 修改解决方案文件(*.sln) 使用记事本打开 *.sln 文件,将里面的 Microsoft Visual Studio Solutio ...

  4. Effective C++ 之 0 导读(Introduction)

    Effective C++ 导读 (Introduction) 术语(terminology) 声明式 (declaration) 是告诉编译器某个东西的名称和类型(type),但略去细节.以下都是声 ...

  5. url地址中 "&" "/"等符号的转义处理(转)

    URL出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,如何是好? 解决办法:将这些字符转化成服务器可以识别的字符,对应关系如下: URL中的特殊字 ...

  6. Android中常用的五种数据存储方式

    第一种: 使用SharedPreferences存储数据 适用范围: 保存少量的数据,且这些数据的格式非常简单:字符串型.基本类型的值.比如应用程序的各种配置信息(如是否打开音效.是否使用震动效果.小 ...

  7. LoadRunner中截取字符串

    LoadRunner中截取字符串 /*strchr和strrchr的区别*/ char *strTest1="citms citms"; char *strTest2,*strTe ...

  8. 去掉开始菜单中新装程序的红色标记【Windows】

    右键开始,属性,开始菜单,自定义,去掉突出新程序.完成.

  9. JAVA第三周作业

    一:枚举 package homework; public class EnumTest { public static void main(String[] args) { Size s=Size. ...

  10. vs2010 安装MVC 3.0

    下载链接如下: MVC 3安装包:http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid=d2928bc1-f48c-4e95-a ...