zoukankan      html  css  js  c++  java
  • Java 笔记

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

    重载,重写,隐藏

    img

    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 第七讲:

    接口:

    1. 类之间只能单一继承(只有一个父类。)
    2. 类没有明确extends,则默认Object类
    3. 接口之间多重继承
    4. 类可以实现多个接口

    抽象类:

    区别:

    • 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。

    • 默认的方法实现

      抽象类可以有默认的方法实现完全是抽象的。接口根本不存在方法的实现。

    • 抽象类可以有构造器,而接口不能有构造器


    内部类:

    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{}
    }
    

    内部类:

    1. 不能使用Outer.this

    2. static类型的内部类直接初始化:Outer.Inner_2 oi = new Outer.Inner_2()

    3. 非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;
    }
    

    ​ 执行过程:

    1. 类代码(.class)从硬盘调到内存中时,执行类的初始化动作。

    2. 类的初始化动作:

      按照定义的先后次序,依次进行初始化。

    ​ 编译器把代码重整:

    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"。" "匹配换行符。序列"\"匹配"","("匹配"("。
    ^ 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与" "或" "之后的位置匹配。
    $ 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与" "或" "之前的位置匹配。
    * 零次或多次匹配前面的字符或子表达式。例如,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} mn 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的头三个 o。'o{0,1}' 等效于 'o?'。注意:您不能将空格插入逗号和数字之间。
    ? 当此字符紧随任何其他限定符(、+、?、{n}、{n,}、{n,m*})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o"。
    . 匹配除" "之外的任何单个字符。若要匹配包括" "在内的任意字符,请使用诸如"[sS]"之类的模式。
    (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 匹配 xy。例如,'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"范围内的任何字符。
     匹配一个字边界,即字与空格间的位置。例如,"er"匹配"never"中的"er",但不匹配"verb"中的"er"。
    B 非字边界匹配。"erB"匹配"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。
    换行符匹配。等效于 x0a 和 cJ。
    匹配一个回车符。等效于 x0d 和 cM。
    s 匹配任何空白字符,包括空格、制表符、换页符等。与 [ f v] 等效。
    S 匹配任何非空白字符。与 [ f v] 等效。
    制表符匹配。与 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,其中 nm 是八进制数字 (0-7)。
    ml n 是八进制数 (0-3),ml 是八进制数 (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 异常

    img

    异常处理

    • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
    • 运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
    • 错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

    img


    语义

    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

    img

    字节流:

    输入流

    image-20200609080923786

    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,表示读到了输入流的末尾。
    */
    

    输出流

    image-20200609084625844

    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

    1. 列出f盘目录下所有内容
    2. 过滤.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);
            }
        }
    }
    
    1. 文件夹的复制
    public class Test{
        public static void main(String[] args){
            
        }
    }
    

    字符流

    文本流

    1. 显示文本文件内容
    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类
    1. 以文本行为单位读取文件
    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();
        }
    }
    
    1. 从键盘读入一系列整数值,以','分割,计算和
    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头,有?,需要处理
     **/
    

    思路:

    1. 键盘字节流转换为字符流 InputStreamReader
    2. 按行读取BufferedReader
    3. 正则表达式
  • 相关阅读:
    STL(五)list
    WinCE进程ID获取窗口句柄
    【转】.obj, .lib, .dll, .exe的关系
    《Windows核心编程》——线程
    【转】windows结束线程方式
    VS2005调试多进程
    【转】VC中常用的宏
    【转】C++标准库简介
    WinCE下用STL的奇怪问题
    STL(三)string
  • 原文地址:https://www.cnblogs.com/fans-fan/p/13202986.html
Copyright © 2011-2022 走看看