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. ArcGIS中的三种查询

    ArcGIS runtime SDK for WPF/Silverlight中的三种常用的查询:QueryTask.FindTask.IdentifyTask都是继承自ESRI.ArcGIS.Clie ...

  2. IBM Rational AppScan 无法记录登录序列 分类: 数据安全 2015-03-18 16:46 158人阅读 评论(0) 收藏

    为了测试漏洞,我在本地部署了一个站点,为http://localhost/app,并且有登录页面. 但是尝试多次,都无法记录登录页面.此时尝试了在hosts文件中,自定义了一个域名 127.0.0.1 ...

  3. mysql编译时报的一个警告warning: type-punning to incomplete type might break strict-aliasing rules,可能是bug

    cmake的时候报了一个警告: /softdb/mysql-5.5.37/storage/innobase/handler/ha_innodb.cc:11870: warning: type-punn ...

  4. Sql Server 基础知识

    Sql Server 基础知识: http://blog.csdn.net/t6786780/article/details/4525652 Sql Server 语句大全: http://www.c ...

  5. loj 1406(状态压缩)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1406 思路:首先可以预处理出在每个顶点的状态的合法状态vis[u][state], 然 ...

  6. 智能车学习(十三)——角度控制

    一.手册代码以及图示 二.流程说明 1.角度计算函数说明 //===================================================================== ...

  7. API和系统调用实现同一方法

    “平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 一.基 ...

  8. javascript 时间倒计时

    新加入一个项目的集中开发,遇到一个需要倒计时的需求,经过测试,有以下几种方案,分享出来: 方案一: 页面Html: <span style="font-size:18px;" ...

  9. java net编程

    转自:http://www.cnblogs.com/linzheng/archive/2011/01/23/1942328.html 一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台 ...

  10. cf #365b 巧妙的统计

     Mishka and trip time limit per test 1 second memory limit per test 256 megabytes input standard inp ...