Java 总结
Java 一二讲
匿名数组
//将a赋值{-1, 0, 1};
int[] a;
//不能a = {-1, 0, 1};
a = new int[]{-1, 0, 1}; //匿名数组
二维数组
int[][] a = {{1},
{1, 2},
{1, 2, 3}};
//访问
for(int[] e1 : a){
for(int x : e1){}
}
拼接数字
byte b1 = (byte)(0xaa), b2 = (byte)(0xbb), b3 = (byte)(0xcc), b4 = (byte))0xdd;
int i = b1 << 24 | (b2 << 16) & 0x00ff0000 | (b3 << 8) & 0x0000ff00 | b4 & 0x000000ff;
数逆序
public static int reverse(int n, int m){
return n == 0 ? m : reverse(n / 10, m * 10 + n % 10);
}
Java 第四讲
数组 Arrays
fill(array, value);
sort(array);
arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
Arrays.binarySearch(int[] a, int key);
//插入位置 -(pos) - 1
String
java.lang.String 类代表的是只读的不可以修改的字符序列 。
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
String s4 = new String("Hello");
s1 == s2; // true
s2 == s3; // false
s3 == s4; // false
判断字符串值是否相等,不允许使用
==
, 需要使用equals
- 类的构造器必须有,没有构造器,自动生成一个默认无参构造器。
- 有构造器,则不会创建构造器。
Java 第五讲
static
public class TA{
static int sa = 10;
int vb = 20;
TA self = this;
void f(){ // 对象的方法成员
//最本质区别:可使用this
TA.sa = 50;
this.vb = 260;
vb = 270; // this.vb = 270;
}
void f(TA t){
TA.sa = 100;
vb = 100; // this.vb = 100;
t.vb = 200;
}
static void g(){ // 类的方法成员
//最本质:不可使用this(不存在)
TA.sa = 100;
sa = 200; // TA.sa = 200;
vb = 300; // error
TA t = new TA();
t.vb = 300;
}
static void g(TA t){
sa = 100; // TA.sa = 100;
t.vb = 200;
}
public static void main(String[] args){
TA.sa = 100;
sa = 300; // TA.sa = 300;
TA t1 = new TA();
}
}
重载,重写,隐藏
public class TB{
void f(){
S.o.p("null");
}
void f(byte b){
S.o.p("byte!");
}
void f(long l){
S.o.p("long!");
}
void f(double d){
S.o.p("double");
}
void g(Object o){ //宽
S.o.p("Object!");
}
void g(int[] a){ //窄
S.o.p("int[]!");
}
static void h(){
}
static void h(){
}
public static void main(String[] args){
TB t = new TB();
t.f((byte)2); // byte!
t.f((char)2); // long!
// char -> int -> long -> float -> double
t.g(null); // 先窄后宽
}
}
继承:
public class Point{
private x, y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
public Point(){} //若无,子类报错
}
public class Point3D{
private z;
public Point3D(int x, int y, int z){
super(x, y);
this.z = 0;
}
public Point3D(){
this(0, 0, 0);
}
public Point3D(int x){
//自动加上:super(); 默认构造器, 若父类无默认构造器,则报错。
this.z = 20;
}
}
public class FA{
public void f(){
S.o.p("FA -> f()");
}
}
public class SubB extends FA{
public void f(){
S.o.p("SubB -> f()");
}
}
public class Test{
public static void main(String[] args){
FA fa = new FA();
fa.f(); //FA -> f()
SubB sb = new SubB();
s.f(); //SubB -> f()
//向上转型:
FA fa1 = new SubB();
fa1.f(); //SubB -> f()
}
}
方法重写只针对非
static
方法。
static
方法没有重写,只有隐藏和重载。参数名和参数列表完全相同,返回值:基本类型必须相同;引用类型要相容。
super.f()
调用的是重写之前的方法。
Test
public class FA{
int x = 10;
static int y = 20;
public void f(){
S.o.p("FA->f()");
}
public static void g(){
S.o.p("FA->g()");
}
}
public class FB extends FA{
int x = 100;
static int y = 200;
public void f(){
S.o.p("FB->f()");
}
public static void g(){ //隐藏
S.o.p("FB->g()");
}
}
public class Test{
public static void main(String[] args){
FA fa = new FB();//
S.o.p("x = " + fa.x); // 10;
fa.f(); //FB->f()
fa.g(); //FA->g()
S.o.p("y = " + fa.y) // 20;
}
}
Java 第六讲
public,protected,private,默认
package java1;
public class CA1{
private int x = 1; //只能在本类自身内部才有访问它!
int y = 2; //属于同一个包的类都可访问它!
protected int z = 3;//属于同一个包或不同包但必需是子类都可以访问
//(不同包的子类是通过继承的方式来访问的!)
public int w = 4; // 任何类都可以访问它!(无论是不是同一个包)
public void f();
}
package java2;
public class CB2 extends CA1{
public void f(CA1 o){
/**
访问o.×出错!因为x只能在CA1本类自身内部访问,在外部不允许访问!
访问o.y出!因为y只能在属于同一个包的类中访问!
访问o.z出错!不同包的话,必需是子类且是继承的数据或方法。
访问this.z正常!因为是继承的z。
**/
S.o.p("x = " + o.x +
"y = " + o.y +
"z = " + o.z +
"继承的z = " + this.z +
"继承的z = " + super.z +
"w = " + o.w);
}
}
重写
- 重写是针对对象的方法,要求非
static
方法。- 是static方法,没有重写,只有重载或者隐藏。
- 条件:方法名和方法参数必须一样。
- 返回值类型:基本数据类型则必须一样;若是引用,必须相容。(父类:Object类,子类:String类)
向上转型
A a = new B();
除了子类重写父类的方法,其他都是父类A的成员。
单例模式
public class Singleton{
private Singleton(){}
private static Singleton obj = new Singleton();
public static getObj(){
return obj;
}
}
- 恶汉式单例模式
- 懒汉式单例模式
- DCL单例模式,双重锁机制
- 反射可以破坏单例模式
- 反射不可以破坏枚举的单例模式
Java 第七讲:
接口:
- 类之间只能单一继承(只有一个父类。)
- 类没有明确extends,则默认Object类
- 接口之间多重继承
- 类可以实现多个接口
抽象类:
区别:
-
抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。
-
默认的方法实现
抽象类可以有默认的方法实现完全是抽象的。接口根本不存在方法的实现。
-
抽象类可以有构造器,而接口不能有构造器
内部类:
public class Outer{
private int i = -1;
private static int j = -2;
//非staic类型
class Inner{ //内部类
private int i = 1;
public void f(int i){
Outer.this.i = this.i + i; //外部类的变量访问:外部类类名.this.变量名
S.o.p("Outer.i = " + Outer.this.i);
}
}
//static类型
//只能访问static类型的成员,没有this
static class Inner_2{
public void f(){
S.o.p("Outer.j" + Outer.j);
}
}
}
- 非static类型:
Outer.Inner oi = new Outer.Inner()
× 未指定是哪一个Outer.this
对象
生成
Inner
对象时必须指定Outer.this
对象
Outer o = new Outer()
Outer.Inner oi = o.new Inner()
-
staic类型 :
Outer.Inner_2 oi2 = new Outer.Inner_2()
局部内部类:
public class Outer{
private int i = -1;
private static int j = -2;
class Inner{ //内部类
private int i = 1;
public void f(final int i){
final int w = 20; //局部内部类可以访问方法内的final变量
class LocalClass{
private int i = 100;
public void f(){
Outer.this.i = Inner.this.i + i + this.i + w; // -1, 1, f(), 100
S.o.p("Outer.this.i = " + Outer.this.i);
}
}
}
}
}
Java 第八讲:
public class Outer{
private int i;
public void f(){}
public class Inner_1{}
public static class Inner_2{}
}
内部类:
-
不能使用Outer.this
-
static类型的内部类直接初始化:
Outer.Inner_2 oi = new Outer.Inner_2()
-
非static类型的内部类对象初始化:
Outer o = new Outer()
Outer.Inner_1 oi2 = o.new Inner_1()
局部内部类:非static类型,可以访问方法内final类型的局部变量。
public void g(){
final int m = 10;
public void f(final int x){
class Local{} // <-局部内部类
}
}
匿名内部类:
Runnable类,Thread类
public class Outer{
private int i = 40;
/*
private class MyWork implements Runnable {
@Override
public void run(){
S.o.p("i = " + i);
}
}
MyWork m = new MyWork();
Thread t = new Thread(m);
*/
//改为匿名内部类:
Thread t1 = new Thread(
new Runnable(){
@Override
public void run(){
S.o.p("i = " + i);
}
}
);
//局部匿名内部类
public void g(final int no){
/*
class MyWork1 implements Runnable{
@Override
public void run(){
S.o.p("i = " + i + " no =" + no);
}
}
MyWork1 w = new MyWork1();
new Thread(w).start();
*/
//①
new Thread(
new Runnable(){
@Override
public void run(){
S.o.p("i = " + i + " no =" + no);
}
}
).start();
// JDK8:
new Thread(
//lambda 表达式
()/*参数列表*/ -> S.o.p("i = " + i + " no =" + no);
).strat();
}
}
类的初始化块
public class CA{
private static int i = 10;
static{ // <--类的初始化块
S.o.p("i = " + i + " j = " + j);
}
private static int j = 20;
}
执行过程:
-
类代码(.class)从硬盘调到内存中时,执行类的初始化动作。
-
类的初始化动作:
按照定义的先后次序,依次进行初始化。
编译器把代码重整:
public class CA_New{
private static int i = 0;
private static int j = 0;
static {
i = 10;
S.o.p("i = " + i + " j = " + j); // -> i = 10, j = 0
j = 20;
}
}
执行次序:
- 父类的初始化 (1. 父类 硬盘 - > 内存, 2. 类的初始化)
- 自己的类的初始化(1. 自己 硬盘 - > 内存 2.类的初始化)
对象的初始化块
流程:
* 所有的类的初始化(块)
* 所有的1. 对象的初始化块和2. 构造器
public class CA{
private static int i = 10;
int k = 30;
static{ // <--类的初始化块
S.o.p("i = " + i + " j = " + j);
}
private static int j = 20;
{
S.o.p("对象初始化块:k = " + k);
}
public CA(){
S.o.p("构造器: k = " + k);
}
public static void main(String[] args){
new CA();
new CA();
}
}
/*
1.
i = 10,j = 0
对象初始化块: k = 30
构造器:k = 30
2.
对象初始化块: k = 30
构造器:k = 30
*/
Java第九讲
-
equals()方法:
//源码 public boolean equals(Object obj){ return (this == obj); }
-
hashCode() 方法:需要重写
如果
obj1.equals(obj2)
,则obj1.hashCode() == obj2.hashCode()
-
toString() 方法:需要重写
//源码: public String toString(){ reutrn getClass().getName() + "@" + Integer.toHexString(hashCode()); }
包装类
>- byte -> Byte
>- short -> Short
>- int -> Integer
>- long -> Long
>- float -> Float
>- double -> Double
>- boolean -> Boolean
>- char -> Character
- 所有的包装类都是final类型,不能创建他们的子类。
- 包装类是不可变类,同(String)类。
- 自动装箱,自动拆箱。 数值3 - > 对象3 对象3 - > 数值3
- 将字符串转换为基本值的
parseType()
方法,如Integer.parseType(args[0])
。 - 与String类的转换
Java 第十讲
正则表达式语法
字符 | 说明 |
---|---|
\ | 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,"n"匹配字符"n"。"\n"匹配换行符。序列"\\"匹配"\","\("匹配"("。 |
^ | 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与"\n"或"\r"之后的位置匹配。 |
$ | 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与"\n"或"\r"之前的位置匹配。 |
* | 零次或多次匹配前面的字符或子表达式。例如,zo* 匹配"z"和"zoo"。* 等效于 {0,}。 |
+ | 一次或多次匹配前面的字符或子表达式。例如,"zo+"与"zo"和"zoo"匹配,但与"z"不匹配。+ 等效于 {1,}。 |
? | 零次或一次匹配前面的字符或子表达式。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效于 {0,1}。 |
{n} | n 是非负整数。正好匹配 n 次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。 |
{n,} | n 是非负整数。至少匹配 n 次。例如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有 o。"o{1,}"等效于"o+"。"o{0,}"等效于"o*"。 |
{n,m} | m 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的头三个 o。'o{0,1}' 等效于 'o?'。注意:您不能将空格插入逗号和数字之间。 |
? | 当此字符紧随任何其他限定符(、+、?、{n}、{n,}、{n,m*})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o"。 |
. | 匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。 |
(pattern) | 匹配 pattern 并捕获该匹配的子表达式。可以使用 \(0…9\) 属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"("或者")"。 |
(?:pattern) | 匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用"or"字符 (|) 组合模式部件的情况很有用。例如,'industr(?:y|ies) 是比 'industry|industries' 更经济的表达式。 |
(?=pattern) | 执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 |
(?!pattern) | 执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 |
x|y | 匹配 x 或 y。例如,'z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。 |
[xyz] | 字符集。匹配包含的任一字符。例如,"[abc]"匹配"plain"中的"a"。 |
[^xyz] | 反向字符集。匹配未包含的任何字符。例如,"[abc]"匹配"plain"中"p","l","i","n"。 |
[a-z] | 字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母。 |
[^a-z] | 反向范围字符。匹配不在指定的范围内的任何字符。例如,"[a-z]"匹配任何不在"a"到"z"范围内的任何字符。 |
\b | 匹配一个字边界,即字与空格间的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。 |
\B | 非字边界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。 |
\cx | 匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回车符。x 的值必须在 A-Z 或 a-z 之间。如果不是这样,则假定 c 就是"c"字符本身。 |
\d | 数字字符匹配。等效于 [0-9]。 |
\D | 非数字字符匹配。等效于 [0-9]。 |
\f | 换页符匹配。等效于 \x0c 和 \cL。 |
\n | 换行符匹配。等效于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。等效于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。 |
\S | 匹配任何非空白字符。与 [ \f\n\r\t\v] 等效。 |
\t | 制表符匹配。与 \x09 和 \cI 等效。 |
\v | 垂直制表符匹配。与 \x0b 和 \cK 等效。 |
\w | 匹配任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。 |
\W | 与任何非单词字符匹配。与"[A-Za-z0-9_]"等效。 |
\xn | 匹配 n,此处的 n 是一个十六进制转义码。十六进制转义码必须正好是两位数长。例如,"\x41"匹配"A"。"\x041"与"\x04"&"1"等效。允许在正则表达式中使用 ASCII 代码。 |
num | 匹配 num,此处的 num 是一个正整数。到捕获匹配的反向引用。例如,"(.)\1"匹配两个连续的相同字符。 |
n | 标识一个八进制转义码或反向引用。如果 n 前面至少有 n 个捕获子表达式,那么 n 是反向引用。否则,如果 n 是八进制数 (0-7),那么 n 是八进制转义码。 |
nm | 标识一个八进制转义码或反向引用。如果 nm 前面至少有 nm 个捕获子表达式,那么 nm 是反向引用。如果 nm 前面至少有 n 个捕获,则 n 是反向引用,后面跟有字符 m。如果两种前面的情况都不存在,则 nm 匹配八进制值 nm,其中 n 和 m 是八进制数字 (0-7)。 |
\nml | 当 n 是八进制数 (0-3),m 和 l 是八进制数 (0-7) 时,匹配八进制转义码 nml。 |
\un | 匹配 n,其中 n 是以四位十六进制数表示的 Unicode 字符。例如,\u00A9 匹配版权符号 (©)。 |
S.o.p("A".matches("\\x41")); //十六进制匹配字符
[\\u4e00 - \\u9fa5] //表示一个汉字
最小最大匹配
字符串:abcabcabcabcabc
最小匹配:a.*c //任一字符0次或多次
最大匹配:a.*?c //非贪婪匹配
英文单词或汉字:
^[a-zA-Z]*|[\u4e00-\u9fa5]*$
组
在正则表达式中引用与该组相匹配的内容。
((A)(B(C)))
1. ((A)(B(C)))
2. (A)
3. (B(C))
4. (C)
//0号组代表整个正则表达式
习题
C16O12H2N5 --算分子量
"([CHON](\d)*)"
Pattern pattern = Pattern.compile("([CHON](\\d*))(\\1)*");
// 第1组:([CHON](\\d+))
// 第2组:(\\d+)
// [CHON] CHON中一个字符
// (\\d*)0个或多个数字
// (\\1)第一组
// *第一组0个或多个
Matcher matcher = pattern.matcher(s);
double sum = 0.0;
while(matcher.find()){
System.out.print(matcher.group(1).charAt(0) + " ");
System.out.println(matcher.group(2));
sum += C(matcher.group(1).charAt(0)) * Double.parseDouble(matcher.group(2));
}
用HashMap
字符压缩
aaavvcdddq222(((333)))
s.replaceAll("(.)(\\1)*", "$1");
// regx: 1号组:(.)
// (\\1) 与1号组相匹配的内容
// * 0次或多次
// $1 / [$1] 1号组
分割
String s = " copy c:/a.txt d:/e.txt ";
String[] str = s.split("\\s+", num); //num小于0表示显示末尾空串,大于零表示分割成几份
for(String e : ss){
sout("-->" + e);
}
//-->
//-->c:/a.txt
//-->d:/e.txt
//没有末尾空
//匹配数字
s = "aasfs43124fafa654gsddg6(3424)fa)";
String str = s.split("[^0-9]+");//以非数字分割
抓取
//匹配数字
s = "aasfs43124fafa654gsddg6(3424)fa)";
Pattern pattern = Pattern.compile("\\d+"); //"\\d{1,4}"1到4位数字
Matcher matcher = pattern.matcher(s);
while(matcher.find()){
String str = matcher.group();
}
//替换
appendReplacement();
appendTail();
System.out.println("请输入模板串:");
String temp = in.nextLine();
System.out.println("请输入数据源串:");
String src = in.nextLine();
String[] aim = src.split(",");
Map<String, String> map = new HashMap<>();
for(String sp : aim){
if(sp > 0){
String[] r_e = e.split(":", 2);
map.put(r_e[0], r_e[1]);
}
}
Pattern pattern = Pattern.compile("\\$\\{([\\u4e00-\\u9fa5]+?)\\}");
Matcher matcher = pattern.matcher(temp);
StringBuilder sb = new StringBuilder();
while(matcher.find()){
//System.out.println(matcher.group(1));
matcher.appendReplacement(sb, map.get(matcher.group(1)));
}
matcher.appendTail(sb);
System.out.println("结果:" + sb.toString());
Java 异常
异常处理
- 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
- 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
- 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。
语义
try{
f1();
f2();
f3();
}
catch(MyExcptyion e1){}
catch(MyException e2){}
finally{}
无论是否抛出异常,finally
语句块都会执行。
java
抛出异常的三种情况:
- 首先执行
try
块,若没有异常,则直接执行finally
块。 - 若执行f1()块抛出异常,f2(),f3()方法不会被执行,程序直接跳至第一条
catch
语句。如果抛出的异常与e1相符,执行e1语句块,不匹配跳到第二个catch语句。最后执行finally
语句。- 判断是否相匹配用语句
instanceof
。
- 判断是否相匹配用语句
- 若执行
try
块抛出异常,并且catch
语句块没有与之相匹配的异常,那么先执行finally
语句块,然后向外抛出异常。
public class KBException extends IOException{
String str;
KBException(String _str) {
this.str = _str;
}
public String toString() {
sout(str);
}
}
public class KBPress{
public static int read() throws KBException{
//throws是声明异常。
int ch;
try{
ch = System.in.read();
if(ch == 'A'){
throw new KBException ("A键已坏");
}
}
catch(IOException e){
throw new KBException(e.getMessage());
//throw是抛出异常。
}
return ch;
}
}
public class Client{
public static String[] main(String[] args){
int ch;
try{
while((ch = KBPress.read()) != -1){
sout("" + ch);
}
}catch(KBException e){
sout("" + e.getMessage());
}
}
}
try{
//异常
return 1;
}
catch(){
return 2;
}
finally{
return 3;
}
- 无论有没有异常,都要执行
finally
,所以都是return 3
;
FA -> FB
//FB继承FA
catch()语句的顺序一定是从小到大,否则FB永远不会执行
Java IO
字节流:
输入流
abstract int read() throws IOException
/*
功能:读取一个字节数据,并返回读到的数据,如果返回-1,表示读到了输入流的末尾。
*/
int read(byte[] b) throws IOException
/**
功能:从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中,并以整数形式返回实际读取的字节数,如果返回-1,表示读到了输入流的末尾。
*/
//读取尽可能多的数据
int read(byte[] b, int off, int len) throws IOException:
/**
功能:将数据读入一个字节数组,同时返回实际读取字节数,如果返回-1,表示读到了输入流的末尾。off指定在数组b中存放数据的起始偏移位置,len指定读取的最大字节数。如果返回-1,表示读到了输入流的末尾。
*/
输出流
abstract void write(int b) throws IOException:
// 将b的最低的一个字节写入此输出流,b的高位字节(3个)丢弃。
void write(byte[] b) throws IOException
// 将b.length个字节从指定的byte数组写入此输出流。
void write(byte[] b,int off,int len)throws IOException
// 将指定byte数组中从偏移量 off 开始的len个字节写入此输出流。
void flush()throws IOException
// 刷新此输出流并强制写出所有缓冲的输出字节。
void close()throws IOException
// 关闭此输出流并释放与此流有关的所有系统资源。
InputStream/OutputStream
在键盘上读入,在屏幕上输出,按ctrl+z
结束
//java换行:13 10
class Exp1{
public static void main(String[] args) throws Exception{
int ch;
while((ch = System.in.read()) != -1){
System.out.println(ch);
}
}
}
FileOutputStream/FileInputStream
处理文件
FileOutputStream(String name, boolean append) throws FileNotFoundException
//功能:创建一个向具有指定name的文件中写入数据的输出文件流。如果第二个参数为 true,则以添加方式写入字节,文件中的原有内容不会被清除。
class Exp2{
public static void main(String[] args) throws Exception{
//没有文件则添加,有文件就删除,
FileInputStream fileInputStream = new FileInputStream("F://1.jpg");
//
FileInputStream fileInputStream = new FileInputStream("F://1.jpg", true);
FileOutputStream fileOutputStream = new FileOutputStream("F://2.jpg");
int ch2;
while((ch2 = fileInputStream.read()) != -1){
fileOutputStream.write(ch2);
}
fileOutputStream.close();
fileInputStream.close();
}
}
键盘到文件:
class Exp3{
public static void main(String[] args) throws Exception{
FileOutputStream fileOutputStream = new FileOutputStream("D://1.dat");
int ch2;
while((ch2 = System.in.read()) != -1){
fileOutputStream.write(ch2);
}
fileOutputStream.flush();
fileOutputStream.close();
}
}
DataInputStream/DataOutputStream
装饰模式
class Exp3{
public static void main(String[] args) throws Exception{
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream("F://1.dat"));//装饰模式
dataOutputStream.writeInt(10);
for (int i = 0; i <= 10; i++) {
dataOutputStream.writeInt(i*3);
}
dataOutputStream.writeInt(5);
for (int i = 0; i <= 5; i++) {
dataOutputStream.writeDouble(i*3D);
}
//88字节
dataOutputStream.flush();
dataOutputStream.close();
}
}
对字节文件以基本数据类型为准读。
DataInputStream(InputStream in);
//Dis读到文件末尾
//个数未知
try{
while(true){
v = dis.readInt();
}
}catch(EOFException e){
e.printStackException();
}
- 关闭文件
public class TestDio{
putlic stattic ovid main(String[] args) throws Exception{
DataInputStream dos = new DataInputStream(new FileInputStream("f:/t.dat"));
int len = dis.readInt();
System.out.println("len:" + len);
for(int i = 1; i <= len; i++){
int v = dis.readInt();
System.out.print(" " + v);
}
len = dis.readInt();
for(int i = 1; i <= len; i++){
double d = dis.readDouble();
System.out.print(" " + d);
}
dos.close();
}
}
File
- 列出f盘目录下所有内容
- 过滤.txt文件
public class Test{
public static void main(String[] args){
File f = new File("f:/");
String[] fs = f.list();
for(String s : fs){
System.out.println(s);
}
//过滤器
fs = f.list(
//局部匿名内部类
new FilenameFilter(){
@Override
public boolean accept(File dir, String name){
return name.endsWith(".txt");
}
}
);
for(String s : fs){
System.out.println(s);
}
}
}
- 文件夹的复制
public class Test{
public static void main(String[] args){
}
}
字符流
文本流
- 显示文本文件内容
public class Test{
public static void main(String[] args) trows Exception{
FileReader fr = new FileReader("d:/test.txt"); //默认GBK
//按照UTF-8
InputStreamReader isr = new InputStreamReader(
new FileInputStream("d:/test.txt"), "utf-8");
System.out.println("编码:" + fr.getEncoding());
int ch;
while((ch = fr/*isr*/.read()) != -1){
System.out.println((char)ch);
}
isr.close();
fr.close();
}
}
/**
* 输出第一个字符是‘?’
* Windows 记事本的BOM头,有?,需要处理
**/
文本行
- BufferedReader类
- 以文本行为单位读取文件
public class Test{
public static void main(String[] args) throws Exception{
Bufferedreader br = new BufferedReader(new FileReader("d:/test.txt"));
String line = null;
while((line = br.read) != null){
System.out.println(line);
}
br.close();
}
}
- 从键盘读入一系列整数值,以','分割,计算和
public class Test{
public static void main(String[] args) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入一行整数值, 以逗号分隔:");
String line = reader.readLine();
String[] split = line.split(",");
int sum = 0;
for (String s : split) {
if(s.trim().length() > 0) {
//trim() 去掉头尾空格
sum += Integer.parseInt(s.trim());
}
}
System.out.println("和为:" + sum);
}
}
/**
* 输出第一个字符是‘?’
* Windows 记事本的BOM头,有?,需要处理
**/
思路:
- 键盘字节流转换为字符流 InputStreamReader
- 按行读取BufferedReader
- 正则表达式