异常、常用类、GUI、正则


一、异常
1、概述:
异常:就是程序在运行时出现不正常情况。将问题封装成对象就是异常。
异常由来:问题也是现实生活中一个具体事务,也可以通过 java 的类的形式进行描述。并封装成对象。其实就是 java 对不正常情况进行描述后的对象体现。
严重的问题:java 通过Error 类进行描述。一般不编写针对性代码对其进行处理。
非严重问题:java 通过Exception 类进行描述。可以使用针对性的处理方式处理。
    Error 类和 Exception 类都具有一些共性内容,向上抽取部分是父类 Throwable。Exception 类的错误代表那些诸如算术错误、数据格式错误、非法参数、非法存取等与程序有关的错误。Throwable 类是 java 语言中所有错误或异常的超类。 这也就构成了 Java 异常体系:

    Throwable

         |---Error  //通常出现重大问题如:运行的类不存在或者内存溢出等。

         |---Exception //运行时出现的一起情况

              |---RuntimeException    //特殊异常类,抛时不需要声明

    Exception和Error的子类名都是以父类名作为后缀。

异常体系的特点

    1)异常体系中的所有类以及建立的对象都具备可抛性。

    2)也就是说可以被throw和throws关键字所操作。

     3) 只有异常体系具备这个特点。
2、异常分类:

    1)编译时被检测异常:

      该异常在编译时,如果没有处理(没有抛也没有try),编译失败。该异常被标识,代表着可以被处理。

    2)运行时异常(编译时不检测):

      在编译时,不需要处理,编译器不检查。该异常的发生,建议不处理,让程序停止,需要对代码进行修正例如:RuntimeException以及其子类。

3、异常处理:
格式:
    try{
         //需要被监测的代码
     }catch(异常类  常量){  
         //处理异常的代码(处理方式)
     }finally{
         //一定会执行的代码
     }
Note:
    1) catch 小括号中的参数代表要捕获哪种异常,应该写 Exception 或其某个子类的对象。
    2) 若发生异常,则 try 语句块的执行发生在发生问题的位置中断,后面若还有语句将被忽略,执行流程转移到捕获该异常的 catch 语句块中。
    3) 若不发生异常,则 catch 语句块中的代码不会被执行。
    4) 无论是否发生异常 finally 块中的代码一定会被执行。一般用于关闭资源码(比如:关闭数据库), 因为资源必须释放。
    5) try语句块不能单独出现,catch 和 finally 必须至少有一个跟在 try 后面。
    6) catch 语句块可以写多个,每个 catch 捕捉不同的异常,一次跟在 try 语句块的后面,发生异常时,程序将从上向下找到最先匹配的 catch 语句块去执行,因此子类级别的异常要写在前面,父类级别的异常靠后。
    7) finally 只有一种情况不会执行:当执行到System.exit(0);后fianlly 不会再执行。

4、throw和throws

    throw定义在函数内,用于抛出异常对象。

    throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。

    当函数内容有throw抛出异常对象,并未进行try处理。必须要在函数上声明,否则编译失败。
Note:throws 和 throw 的区别:
    throws 使用在函数上(写在小括号和大括号之间)。throw 使用在函数内。
    throws 后面跟的异常类。可以跟多个。用逗号隔开。throw 后跟的是异常对象。

使用格式:
    返回值类型  方法名称  throws  异常类{
    if(发生异常){
       throw  异常类对象;
    }
Note: RuntimeException除外。也就说,函数内如果抛出的RuntimeExcpetion异常,函数上可以不用声明。

常见方法操作:

    String getMessage();//获取异常的信息。返回字符串。

    toString();//获取异常类名和异常信息,返回字符串。

    printStackTrace();    //获取异常类名和异常信息,以及异常出现在程序中的位置.返回值void.

                          //其实JVM默认的异常处理机制,就是在调用printStackTrace方法,打印异常的堆栈的跟踪信息。

    printStackTrace(PrintStream s)// 通常用该方法将异常内容保存在日志文件中,以便查阅。

5、自定义异常类
    因为项目中会出现特有的问题,而这些问题并未被 java 所描述并封装对象。所以对于这些特有的问题可以按照 java 的对问题封装的思想。将特有的问题,进行自定义的异常封装。
    1)自定义异常必须是自定义类继承 Exception。
    原因:异常体系有一个特点,因为异常类和异常对象都被抛出,他们都具备可抛性。这个可抛性是 Throwable 这个体系中独有特点,只有 Throwable 体系中的类和对象才可以被 throws 和 throw 操作。
    2)自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException。

    3) 当自定义了异常类继承Exception后,如果未在类中定义异常信息,那么通过toString方法打印出来的结果就只有自定义的异常类名,不会显示异常信息。
    4) 要定义自定义异常的信息时,可以使用父类已经定义好的功能。异常信息传递给父类的构造函数。因为父类中已经把异常信息的操作都完成了。所以子类只要在构造时,将异常信息传递给父类通过super语句。那么就可以直接通过getMessage方法获取自定义的异常信息。

示例如下:
class MyException extends Exception {
	private String msg;

	MyException(String msg) {
		super(msg);// 返回自定义的输入信息
	}
}
6、异常的好处:
    1)将问题进行封装。
    2)将正常流程代码和问题处理代码相分离,方便于阅读。
7、异常的处理原则:
    1)处理方式有两种:try  或者  throws。
    2)调用到抛出异常的功能时,抛出几个,就处理几个。一个 try 对应多个 catch。多个 catch,父类的 catch 放到最下面。
    3)catch 内,需要定义针对性的处理方式。不要简单的定义 printStackTrace,输出语句。也不要不写。
    4)当捕获到的异常,本功能处理不了时,可以继续在 catch 中抛出。
8、异常的注意事项:
    1)问题能在内部解决就解决,坚决不再往外抛出。
    2)catch是用于处理异常的,如果没有catch就代表异常没有被处理,如果该一场是编译时异常那必须要进行声明。
    3)在子父类覆盖时:子类抛出的异常必须是父类的异常的子类或者子集。如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能再抛。
小练习示例:
/*
老师使用电脑讲课。

描述电脑:
	1、电脑运行
	2、电脑重启
描述电脑问题:
	1、电脑蓝屏了
	2、电脑起火了

描述老师:
	1、老师使用电脑
	2、老师讲课。
描述老师可能出现的问题:
	1、老师不能继续讲课了,他让同学们自己做练习。

*/

//电脑蓝屏了
class BlueScreenException extends Exception
{
	BlueScreenException(String message)
	{
		super(message);
	}
}
//电脑起火了
class FireBreakingException extends Exception
{	
	FireBreakingException(String message)
	{
		super(message);
	}
}

//老师无法继续上课
class StopTeachException extends Exception
{	
	StopTeachException(String message)
	{
		super(message);
	}
}
class Computer
{
	int start=1;
	//电脑启动
	void run()throws BlueScreenException,FireBreakingException
	{
		if(start==2)
			throw new BlueScreenException("Computer_BlueScreen");
		else if(start==3)
			throw new FireBreakingException("Computer_FireBreaking");
		System.out.println("Computer_run");
	}
	//电脑重启
	void reset()
	{	
		start=1;
		System.out.println("Computer_reset");
	}
}

class Teacher
{
	private String name;
	private Computer cpt;

	//对老师进行初始化
	Teacher(String name)
	{
		this.name=name;
		cpt=new Computer();
	}

	//老师开始讲课
	public void teach()throws StopTeachException
	{
		try
		{
			cpt.run();
			
		}
		catch (BlueScreenException e)
		{
			//System.out.println(e.getMessage());
			cpt.reset();
		}
		catch (FireBreakingException e)
		{
			test();
			//System.out.println(e.getMessage());
			throw new StopTeachException("Teather_StopTeach:"+e.getMessage());
		}

		System.out.println(name+"Teacher_teaching");
	}
	void test()
	{
		System.out.println("学生做练习");
	}

}
class ExceptionTest
{
	public static void main(String[] args) 
	{
		Teacher t=new Teacher("毕老师");
		try
		{
			t.teach();
		}
		catch (StopTeachException e)
		{
			System.out.println(e.toString());
			System.out.println("换老师或者放假");
		}
	}
}
二、常用类
1、Object类
概述:存在于java.lang包中,是所有类的根类、超类。Java 中的每一个类都直接或间接地使用Object作为父类,所有对象都实现这个类的方法。所有类对 Object类的继承都是java默认的,无需使用 extends 明确表示。Object 类中提供了 11 个成员方法,也就是说所有其他类都具备这 11 个方法。其中最常用的方法:
    public boolean equals(Object obj); //比较两个对象是否相等
    public String toString(); //返回该对象的字符串表示
    void  finalize();  //  当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
    Class getClass();  //获取对象的字节码文件的描述类,后面再讲反射的时候还会在说这个类。String name = s.getClass().getName();
    int hashCode();    //  获取对象的哈希值。其实就是对象的内存地址值十进制表示若自定义类中有与 Object 类中相同的方法功能,没有必要重新定义。
                       //只要沿袭父类中的功能,建立自己特有的内容即可,也就是覆盖。
equals():我们获取对象后,比较它的地址值意义不大。所以也会对这个方法进行重写。重写要完成什么功能,是根据需求定的。
"==" 和 equals 的用法:
"==":
    1) 可以用于比较基本数据类型,比较的就是基本数据类型的值是否相等。
    2) 可以用于比较引用数据类型,比较的是对象的地址值是否相等。
equals:
    1) equals 只能用于比较引用数据类型的。
    2) Object 提供的 equals 是用于比较对象地址值是否相同。
    3) 自定义类中,如果重写了 equals 方法,那么就是按照你自己的需求来比较的。
toString():
    表示格式:getClass().getName()+"@"+Integer.toHexString(hashCode());一般我们输出对象名的时候,其实底层调用的就是该对象的 toString()方法。这种返回没有意义,所以,我们会重写这个方法,显示类的成员变量信息。
2、String类:
概述:
多个字符组成的一个序列,叫字符串。生活中很多数据的描述都采用的是字符串的,而且我们还会对其进行操作。字符串是一个特殊的对象,是一个被 final 修饰的类,所以不可能有子类。字符串一旦初始化就不可以被改变(此处指的是内存中的地址值不可改变)。
构造方法:
    1)String():无参构造
     eg: String s = new String();
          s = "hello";
    2)String(byte[] bys):  传一个字节数组作为参数 
     eg: byte[] bys = {97,98,99,100,101};
          String s = new String(bys);
    3)String(byte[] bys,int index,int length): 把字节数组的一部分转换成一个字符串 
     eg:byte[] bys = {97,98,99,100,101};
         String s = new String(bys,1,2); 
    4)String(char[] chs):  传一个字符数组作为参数 
     eg:char[] chs = {'a','b','c','d','e'};
         String s = new String(chs);
    5)String(char[] chs,int index,int length): 把字符数组的一部分转换成一个字符串
     eg:char[] chs = {'a','b','c','d','e'};
         String s = new String(chs,1,3);
    6)String(String str): 把一个字符串传递过来作为参数
     eg:String ss = new String(s);
    7)直接把字符串常量赋值给字符串引用对象(最常用)
     eg:String s = "hello";
常见方法:

1)获取

    1.1字符串中包含的字符数,也就是字符串的长度

        int   length()://获取长度。

    1.2根据位置获取位置上的某个字符

        char  charAt(int  index)://当访问到字符串中不存在的角标时,会发生字符串角标越界的错误。

    1.3根据字符获取该字符存在字符串的位置

        int  indexOf(int ch)://返回的是ch在字符串中第一次出现的位置。//传入的是字符对应的ASCII码。//如果没有找到,返回-1。

        int  indexOf(int ch,int fromIndex)://从fromIndex指定位置开始,获取ch在字符串中出现的位置。

        int  indexOf(String str)://返回的是str在字符串中第一次出现的位置。

        int  indexOf(String str,int fromIndex)://从fromIndex指定位置开始,获取str在字符串中出现的位置。

        int  lastIndexOf()://反向索引 

2)判断

    2.1字符串中是否包含某一个子串

        boolean contains(str);

Note:indexOf(str)可以索引str第一次出现的位置,如果返回-1表示该str不在字符串中存在。所以,也可以用于对指定判断是否包。 如:if(str.indexOf(“aa”)!=-1)而且该方法既可以判断,又可以获取出现的位置。如果只为判断,用contains。

    2.2字符串中是否有内容

        boolean isEmpty();//原理就是判断长度是否为0。

    2.3字符串是否是以指定内容开头

        boolean startsWith(str);

    2.4字符串是否是以指定内容结尾

        boolean endsWith(str);

    2.5判断字符串内容是否相同,复写了Object类中的equals方法

        boolean equals(str);

    2.6判断内容是否相同,并忽略大小写。

        boolean equalsIgnoreCase();

3)转换

    3.1将字符数组转成字符串

        构造方法:String(char[]);

                  String(char[],offset,count);//将字符数组中的一部分转成字符串。

        静态方法:

        static String copyValueOf(char[]);

        static String copyValueOf(char[] data,int offset ,int count );

        static String valueOf(char[]);

    3.2将字符串转成字符数组

        char[] toCharArray();

    3.3将字节数组转成字符串

        String(byte[]);

        String(byte[],offset,count);//将字节数组中的一部分转成字符串。count表示个数。

    3.4将字符串转成字节数组

        byte[] getBytes();

    3.5将基本数据类型转成字符串

        String valueOf(int);

        String valueOf(double);

Note:字符串和字节数组在转换过程中,是可以指定编码表的。

4)替换

    String replace(oldchar,newchar);//返回的是一个新字符串。如果要替换的字符不存在,返回的还是原字符串。

5)切割

    String[] split(regex);//涉及到正则表达式的点,不能作为切割字符串的regex。

6)子串,获取字符串中的一部分

    String substring(begin);//从指定位置开始到结尾。如果角标不存在,会出现字符串角标越界异常。

    String substring(begin,end);//包含头,不包含尾。

7)转换,去除空格,比较

    7.1将字符串转成大写或小写

        String toUpperCase();

        String toLowerCase();

    7.2将字符串两端的多个空格去除

        String trim();        

    7.3对两个字符串进行自然顺序的比较

        int compareTo(String);

基于上述知识点,几个小练习演示如下所示:
/*
 * 练习:1、字符串反转
 *       2、获取一个字符串在另一个字符串中出现的次数
 *       3、有两个字符串,找出两个字符串中最大相同那个字符串
 */

public class StringTest {

	// 1、字符串反转
	public static String reverseString(String str) {
		char[] ar = str.toCharArray();// 将字符串转成字符数组
		reverse(ar);// 将字符数组进行反转
		return new String(ar);// 返回反转后的字符串
	}

	// 逐个调换字符数组中的对应位置的字符
	public static void reverse(char[] ar) {
		for (int i = 0, j = ar.length - 1; i < j; i++, j--) {
			swap(ar, i, j);
		}
	}

	// 自定义反转数组中的两个元素
	private static void swap(char[] ar, int i, int j) {
		char temp = ar[i];
		ar[i] = ar[j];
		ar[j] = temp;
	}

	// 2、获取一个字符串在另一个字符串中出现的次数
	public static int getNumOfString(String str, String key) {
		int num = 0;// 定义计数器
		int index = 0;// 定义脚标,用于记录查询位置
		while ((index = str.indexOf(key, index)) != -1) {
			// indexOf(key) 或者indexOf(key,beginIndex)都可以
			// str = str.substring(index + key.length());
			index = index + key.length();// 下一次的查询其实位置是前一次查询返回值加上字符串长度,以此保证每次都是往后偏移查询
			num++;// 查到一次,计数器自增1
		}
		return num;
	}

	// 3、有两个字符串,找出两个字符串中最大相同那个字符串
	public static String getMaxSubString(String str1, String str2) {
		// 不论传进来的两个字符串谁更长,自定义maxString、minString来指向长字符串和短字符串
		String maxString = str1.length() > str2.length() ? str1 : str2;
		String minString = maxString == str1 ? str2 : str1;

		String maxSubString = null;
		for (int i = 0; i < minString.length(); i++) {// 控制在最短字串长度内
			// 依次递减短字符串子串
			for (int j = 0, k = minString.length() - i; k <= minString.length(); j++, k++) {
				maxSubString = minString.substring(j, k);// 获取短字符串的子串
				if (maxString.indexOf(maxSubString) != -1) {// 如果包含在长字符串中则表明找到了
					return maxSubString;
				}
			}
		}
		return "-1";
	}

	public static void main(String[] args) {
		String str = "abc cde";
		String s1 = "ascasfhelloasfasf v";
		String s2 = "ashellolkkd";
		System.out.println(reverseString(str));
		System.out.println(getNumOfString(str, "c"));
		System.out.println(getMaxSubString(s2, s1));
	}
}
结果如下所示:

3、StringBuffer类
概述:
字符缓冲区类,是一个容器,一个线程安全的可变字符序列。
StringBuffer 可以对字符串内容进行增删改查等操作,很多方法和 String 相同。
特点:长度是可变化的。可以直接操作多个数据类型。最终会通过 toString 方法变成字符串。

常见操作:

1)存储

    StringBuffer append():将指定数据作为参数添加到已有数据的结尾处。

    StringBuffer insert(intoffset ,数据):可以将数据插入到指定offset位置。

2)删除

    StringBufferedelete(start,end):删除缓冲区中的数据,包含start,不包含end。

    StringBuffer deleteCharAt(index):删除指定位置的字符。//清空缓冲区:对象.delete(0,对象.length());

3)获取

    char charAt(int index);

    int indexOf(String str);

    int lastIndexOf(String str);

    int length();

    String substring(int start,int end);

4)修改

    StringBuffer replace(int start,int end,String str);

    void setCharAt(int index,char ch);

5)反转

    StringBuffer reverse();

6)将缓冲区中指定数据存储到指定字符数组中

    voidgetChars(int srcBegin, int srcEnd,char[] dst,int dstBegin)
4、StringBuilder类
概述:
StringBuilder在JDK1.5 版本之后出现的,一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换, 用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,简易优先采用 StringBuilder 类,因为此类比 StringBuffer 效率高。 
StringBuilder 和 StringBuffer 的功能是一样的,但是有区别:
    StringBuffer(JDK1.0)是线程安全的。一般用于多线程。
    StringBuilder(JDK1.5)不保证线程安全。一般用于单线程。
Note:一般来说,我们写的程序都是单线程的,所以,用 StringBuilde,效率高,以后开发建议使用 StringBuilder。

5、System类
概述:
System 类包含一些有用的类字段和方法。它不能被实例化。在 System 类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。其中的属性和方法全是静态。
字段摘要:
    err    “标准”错误输出流
    in     “标准”输入流;默认是键盘
    out    “标准”输出流;默认是控制台
方法:
    static void setIn(InputStream in)    重新分配“标准”输入流
    static void setOut(PrintStream out)    重新分配“标准”输出流
    static void arraycopy(Object  src,int  srcPos,Object  dest,int  destPos,int length);从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
    static  long currentTimeMillis();  返回以毫秒为单位的当前时间。
    exit(int status);    退出当前虚拟机。0 之外的表示非正常退出。
    static void gc();    运行垃圾回收器
    getProperty();       获取指定键提示的系统属性
    static Properties getProperties();   获取系统属性信息,确定当前的系统属性。
    //因为 Properties 是 Hashtable 的子类,也就是 Map 集合的一个子类对象。 那么可以通过map 的方法取出该集合中的元素。该集合中存储都是字符串。没有泛型定义。
6、Runtime类
概述:
每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime()方法获取当前运行时,应用程序不能创建自己的Runtime 类实例。
理解:此类没有提供构造函数。因不能直接 new 创建自己的类对象,会联想到类中所有方法都是静态的。但是该类中还有非静态方法。说明该类肯定会提供了方法获取本类对象。而且该方法是静态的,并返回值类型是本类类型。由这个特点可以看出该类使用了单例设计模式完成。该方式为:static Runtime getRuntime(); //返回与当前 Java 应用程序相关的运行时对象。
其他方法:
    Process exec(String conmand); //在单独的进程中执行指定的字符串命令。
Note:在使用时容易发生异常,需要在方法上抛出异常。 其中的参数大多数为 String 类型,可以是一个应用程序或者其地址,作用是执行打开一个应用程序。Process 是一个抽象类,不需要自己去实现它,因为计算机底层自动实现了该类。其中的方法有:Abstract void destroy()用以杀掉子进程。
7、Date类
概述:表示特定的瞬间,精确到毫秒。在 JDK1.1 开始,使用 Calendar 类实现日期和时间字段之间转换。使用 DateFormat 类来格式化和解析日期字符串。Date 中的相应大部分方法已废弃。UTC 为世界标准时间。GMT 为民间标准(格林威治标准时)
构造方法:
    public Date(); //分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)。
    public Date(long Date); //分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00GMT)以来的指定毫秒数。 
方法摘要:
    int compareTo(Date anotherDate)   // 比较两个日期的顺序。 
    boolean equals(Object obj)   //比较两个日期的相等性。
    public void getTime(); //返回当前时间的毫秒值
    public void setTime(); //设置当前毫秒值
    boolean after(Date when);  //测试此日期是否在指定日期之后。
    boolean before(Date when);//  测试此日期是否在指定日期之前。
long 与 Date 类型转换:
    System.currentTimeMillions();//获取系统当前时间,返回值 long 类型
    Date.getTime();(注:需先创建 Date 对象)
Date 与 String 类型转换:
    public final String format(Date date);
获取系统时间的两种方法的区别:
第一种
    Date time=new Date(); //创建时间对象
    System.out.println(time); //输出系统时间
第二种:
    long l=System.currentTimeMillis();//获取系统当前时间
    Date d=new Date(l);
    System.out.println(d);
分析:两种方法的 Date 时间运行的结果相同,它们都创建时间对象 Date,区别在于第二种方法时间对象引用了系统的 long 型时间。 而 System.currentTimeMillis()方法返回值为 long 型,还可以利用此方法计算应用程序的运行时间。
8、DateFormat与SimpleDateFormat类
DateFormat:使用与语言无关的方式格式化和并解析日期和时间。是一个日期格式化子类的抽象类。该类可以进行格式化也可以解析字符串。
方法:
    String format(Date date);//将 Date 日期格式化为日期时间字符串。
SimpleDateFormat:是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。 
方法:
    SimpleDateFormat();  // 用默认的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
    SimpleDateFormat(String pattern);  //参数 Date,创建格式对象。用给定的模式和默认语言环境的日期格式符号构造
格式化日期时间步骤: 
    1)在创建对象时指定一个格式:YYYY 年 MM 月 dd 日 HH:mm:ss (如果调用格式化器无参构造,此步骤省略)
    2)创建一个格式器 SimpleDateFormat
    3)创建一个日期对象 Date d
    4)使用格式化器的 formate 方法格式化 d,得到想要的格式字符串。
Note:hh 表示 12 小时制(1—12),HH 表示 24 小时制(0—23),更多日期和时间模式请参考SimpleDateFormat类的API说明
示例如下:

import java.text.SimpleDateFormat;
import java.util.Date;

/*
 * Date类:
 * 1、获取系统当前时间
 * 2、利用SimpleDateFormat类格式化指定时间
 */
public class DateDemo {
	public static void main(String[] args) {

		// 第一种获取方式
		Date date1 = new Date();

		// 第二种获取方式
		long time = System.currentTimeMillis();
		Date date2 = new Date(time);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
		String needDate = sdf.format(date2);
		System.out.println("系统时间戳:" + date2);
		System.out.println("格式化时间:" + needDate);
		System.out.println("格式化模板:" + sdf.toPattern());
	}
}
结果如下:

9、Calendar类
概述:Calendar 是一个抽象类。时间点(某一时刻)
方法:
      getInstance();   //获取日历(使用默认时区和语言环境获取一个日历),不是通过子类创建,而是通过 父类方法 getInstance()返回一个 Calendar对象。
     int get(int field);//参数是日历字段值 ,月份的统计是从 0 到 11 的
     void set();    //设置日历字段。
     abstract void add(int field,int amount);   //根据日历规则,为给定的日历字段添加或者减去指定的时间量。
以下返回值类型为 int:
     年:  calendar.get(Calendar.YEAR);
     月:   calendar.get(Calendar.MONTH);
     日:   calendar.get(Calendar.DAY_OF_MONTH);
     星期: calendar.get(Calendar.DAY_OF_WEEK);
     时:  calendar.get(Calendar.HOUR_OF_DAY);
     分:  calendar.get(Calendar.MINUTE);
     秒:  calendar.get(Calendar.SECOND);
示例如下:

import java.util.Calendar;

/*
 * Calendar类:
 * 	set() 给指定日历设置给定值
 * 	get() 获取指定字段
 * 
 * 	add() 在指定时间上加上一个指定的值再显示
 */
public class CalendarDemo {

	public static void main(String[] args) {

		// 获取某年2月的天数,例如2012年的2月有几天
		Calendar c = Calendar.getInstance();
		// 3月1日减一天就是2月的最后一天,Calendar月份范围0-11
		c.set(2012, 2, 1);
		c.add(Calendar.DAY_OF_MONTH, -1);
		System.out.println(c.get(Calendar.YEAR) + "年"
				+ (c.get(Calendar.MONTH) + 1) + "月共有"
				+ c.get(Calendar.DAY_OF_MONTH));
		// 日历设置到2个月后
		c.add(Calendar.MONTH, 2);
		System.out.println("日历设置到2个月后是" + c.get(Calendar.YEAR) + "年"
				+ (c.get(Calendar.MONTH) + 1) + "月"
				+ c.get(Calendar.DAY_OF_MONTH) + "日");
	}

}
结果如下:

10、Math类(静态工具类)
Math:包含用于数学基本运算的方法。
字段摘要:
     E:  自然对数的底数。 (double)
     PI: π,即圆周与直径之比。 (double)
方法:
     abs();    //绝对值
     cbrt();    //立方根
     ceil();    //返回大于等于参数的最小整数(double)特别注意负数的值
     floor();    //返回小于等于参数的最小整数(double)
     round();    //四舍五入(int 或 long)  原理:原数加 0.5 判断
     random();   //伪随机数 (0——1 之间的数,不包含 1)
     max();    //返回两个数中最大值
     min();    //返回两个数中最小值
Note: 此处的 random 类与 Math 类中的 random()方法作用类似。Random 类可以生成对象,用其下的 next()方法或者 nextInt()方法生成伪随机数。 其中有方法:
     int next(int bits); 
//生成下一个伪随机数
     int nextInt(int n);  //返回下一个伪随机数,在 0 与指定值(不包括指定值)之间均匀分布的 int 值。
三、GUI
1、概述:
GUI:Graphical User Interface(图形用户接口)。用图形的方式,来显示计算机的操作图形界面。方便、直观。
CLI:Command line User Interface(命令行用户接口)。就是 DOS 命令行操作。不直观。
Java 为 GUI 提供的对象,都存在 java.Awt 和 javax.Swing 两个包中。Java中对于图形化编程有个完整的继承体系:
如图所示:

Awt 与 Swing:
java.Awt:
(Abstract Window Toolkit,抽象窗口工具集),需要调用本地系统方法实现功能。属重量级控件。跨平台性较弱。
javax.Swing: 在 AWT 基础上,建立一套图形界面系统,其中提供了更多组件,而且完全由 Java 实现。增强了可移植性,属轻量级控件。
Note:开发时,制作图形化界面时,一般需要导入两个包,import java.awt.*;  和 import java.awt.event.*;。
2、布局管理器
布局:容器中组件的排放方式。
常见的布局管理器:
    FlowLayout(流式布局管理器):从左到右的顺序排列。Panel 默认的布局管理器。
    BorderLayout(边界布局管理器):东南西北中。Frame 默认的布局管理器。
    GridLayout(网络布局管理器):规则的矩阵。
    GardLayout(卡片布局管理器):选项卡。
    GridBagLayout(网格包布局管理器):非规矩的矩阵。
3、Component

Component 是一个具有图形表示能力的对象,可在屏幕上显示,并可与用户进行交互。常用子类:Window、Panel(面板,不能单独存在)。Window 常用子类:Frame、DialogFrame 类:是带有标题和边框的顶层窗口。若显示窗体,必须设置 setVisible 显示。设置 Frame 时,有一个默认的管理器是边界式布局(BorderLayout) 。
主要方法:
    add()    //添加组件(含参数)
    setVisible(Boolean b)    //根据参数的值来显示或隐藏组件
    setSize()    //设置窗体大小,参数为窗口的横坐标和纵坐标
    setLocation()  //设置窗体在本地位置,参数为横、纵坐标
    setLayout()  //设置布局管理器(参数可以是相应布局管理器的对象)
    setBounds()  //移动组件并调整其大小,参数是 4 个坐标(左边距、右边距、宽、高)
    addMouseListener()  //添加指定的鼠标监听器
    addKeyListener()    //添加键盘监听事件
创建图形化界面的步骤:
    1)创建 frame 窗体。
    2)对窗体进行基本设置。比如大小,位置,布局。
    3)定义组件。
    4)将组件通过窗体的 add 方法添加到窗体中。
    5)让窗体显示,通过 setVisible(true)
4、事件监听机制
组成:
事件源、事件(Event)、监听器(Listener)、事件处理(引发事件后处理方式) 
事件源:就是 awt 包或者 swing 包中的那些图形界面组件。
事件:每一个事件源都有自己特有对应事件和共性事件。
监听器:将可以触发某一个事件的所有动作都封装到监听器中。
事件处理:对时间元传来的信息进行处理并反馈出去。

Note:在 java 中事件源、事件(Event)、监听器(Listener)都已定义好,直接获取其对象使用。只需要做事件处理(对产生的动作进行处理)。
5、Window(窗体事件)
Window :
    addWindowListener( )  //添加窗口事件监听器
windowListener 接口:复写方法,实例化对象,才能使用。但它有一个已复写全部方法的子类WindowAdapter。
WindowAdapter:接收窗口事件的抽象适配器类。此类中的方法为空。它是一个没有抽象方法的抽象类,目的是不能创建对象。此类存在的意义是方便创建监听器对象。使用: 因为 WindowListener 的子类 WindowAdapter 已经实现了 WindowListener 接口。并覆盖了其中的所有方法。那么我只要继承自 Windowadapter 覆盖我需要的方法即可。具体方法如下:
    windowClosing( )    //关闭窗口
    windowIconified( )   //窗口最小化状态
    windowOpened()    //打开窗口
    windowActivated()   //前置窗口
    windowClosed()      //关闭窗口
    wind owDeactivated()    //后置窗口
6、Button(含 Action 事件)
方法:
    addActionListener()    //添加指定的动作监听器
ActionListener 接口:用于接收操作事件的监听器接口。 是少数没有适配器接口的其中一个。其中只有一个方法 actionPerformed(),作用:发生操作时调用。
7、鼠标事件和键盘事件
MouseListener:  用于接收组件上“感兴趣的”鼠标事件(eg:按下、释放、单击、进入或离开)的监听器接口。有适配器。
方法:
    mouseClicked(MouseEvent e)    //鼠标单击(按下并释放)
    mouseEntered(MouseEvent e)    //鼠标进入组件
    mouseExited(MouseEvent e)     //鼠标离开组件
    mousePressed(MouseEvent e)    //鼠标按下时
    mouseReleased(MouseEvent e)   //鼠标释放时
Note:鼠标按下与 Action 事件同时存在操作时,鼠标按下先发生。
MouseEvent: (适配器)
成员变量:static int mouse_clicked
方法:
    int getClickCount()    //返回鼠标单击次数
keyListener:  有适配器。
    static int VK_ENTER
    keyPressed(keyEvent e)  //按下某个键时调用此方法
    keyReleased(keyEvent e)  //释放某个键时调用此方法
    keyTyped(keyEvent e)    //键入某个键时调用此方法
keyEvent: (适配器)
    char getkeyChar()    //返回与此事件中的键相关联的字符
    int getkeyCode()    //获取键盘对应的码
    static String getKeyText(int keyCode)    //通过码获取对应的键盘字符
Note:InputEvent 类中 isControlDown() 判断 ctrl 键是否被按下;InputEvent 类中 consume() 以非默认方式处理事件,屏蔽键 
8、TextField 和 TextArea
TextField:  文本框类;TextArea:  文本区域
构造方法: TextField()  //创建文本框。带参数可以设置文本框大小,只能指定列(宽)。
           TextArea()   //创建文本区域,既能指定行数又能指定列数,还可以指定文本区域内含有的默认文字
方法:
    append(String str)    //追加文本。将给定文本追加到文本区的当前文本在他们的父类 TextComponent 中,
    String getText()      //获取文本的方法
    setText()      //设置填充文本内容,参数为内容
9、Dialog 和 Label
Dialog:  是一个带标题和边界的顶层窗口。对话框,默认边界布局管理器,一般对话框不能单独存在,必须依赖于窗体。
FileDialog:  是 Dialog 的子类。显示一个对话框窗口,用户可以从中选择文件。构造参数可以有模式:FileDialog.LOAD(打开,加载文件)和 FileDialog.SAVE(保存)默认打开。
方法:
    String  getFile()      //获取选定文件
    String  getDirectory()    //获取文件对话框目录
Label:  标签,最常用的控件之一,setText()来设置指定文本
10、MenuBar、MenuItem、Menu
MenuBar:  封装绑定到框架的菜单栏的平台概念。为了将该菜单栏与Frame对象关联,可以调用该框架的setMenuBar方法,add()用来添加菜单栏。
MenuItem:菜单项
Menu:菜单条,其中add()用来将指定菜单项或者标签添加到菜单栏。
Note:MenuBar 包括 Menu,Menu 包括 MenuItem、Menu(带箭头)。MenuBar 为菜单栏,一般一个窗口中只有一个;Menu 菜单项,可以设置多个,若并排显示,都添加进 MenuBar;若显示在菜单项中(带二级箭头菜单条) ,则 Menu 嵌套 (添加)Menu 即可。MenuItem 子菜单,是最终子菜单。可以设置多个,添加进 Menu。
GUI示例如下:
/*
 GUI:文本框和文本区域功能等(对话框)
 */

import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class MyWindowDemo {
	private Frame f;
	private TextField tf;
	private Button but;
	private TextArea ta;

	private Dialog d;
	private Label lab;
	private Button okBut;

	MyWindowDemo() {
		init();
	}

	public void init() {
		f = new Frame("my window");
		f.setBounds(300, 100, 600, 500);
		f.setLayout(new FlowLayout());

		tf = new TextField(60);

		but = new Button("转到");

		ta = new TextArea(25, 70);

		// 此处不应该直接初始化对话框等组件,一般处理用户出错问题再创建使用对话框
		// 这里只为演示看效果。
		d = new Dialog(f, "提示信息-self", true);
		d.setBounds(400, 200, 240, 150);
		d.setLayout(new FlowLayout());
		lab = new Label();
		okBut = new Button("确定");

		d.add(lab);
		d.add(okBut);
		// 注意:不要将对话框添加到frame中,只有出现问题才会调用出现对话框

		f.add(tf);
		f.add(but);
		f.add(ta);

		myEvent();
		f.setVisible(true);
	}

	private void myEvent() {

		okBut.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				d.setVisible(false);
			}
		});
		d.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				d.setVisible(false);
			}
		});

		tf.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER)
					showDir();
			}
		});

		but.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				showDir();

			}
		});

		f.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
	}

	private void showDir() {
		String dirPath = tf.getText();

		File dir = new File(dirPath);

		if (dir.exists() && dir.isDirectory()) {
			ta.setText("");// 清空文本
			String[] names = dir.list();
			for (String name : names) {
				ta.append(name + "\r\n");// 追加文本
			}
		} else {
			String info = "您输入的信息:" + dirPath + "是错误的。请重输";
			lab.setText(info);
			d.setVisible(true);
		}
	}

	public static void main(String[] args) {
		new MyWindowDemo();
	}
}
结果如下:

四、正则表达式
1、概述:符合一定规则的表达式。一些特殊符号的使用。
   作用:用于操作字符串
   特点:用于一些特定的字符串来表达一些代码操作---到达简化效果
   好处:可以简化对字符串的校验操作
   弊端:符号定义越多,正则越长,阅读性极差
2、正则表达式构造摘要(非捕获组)主要:
----字符类:只能规则一个字符
    [abc]        判断字符串当中某一个字符位上出现的字符。字符是 a、b 或 c。 
    [^abc]       任何字符,只要不是 a、b、c 即可。
    [a-zA-Z]     a  到  z  或  A  到  Z,两头的字母包括在内(范围)
    [a-d[m-p]]     a  到  d  或  m  到  p:[a-dm-p](并集)
    [a-z&&[def]]   d、e  或  f(交集)
----预定义字符类:这里的\不是转义字符。使用时,记得用\\
    .         任何字符(与行结束符可能匹配也可能不匹配)
    \d        数字:[0-9]
    \D        非数字:  [^0-9]
    \s        空白字符:[ \t\n\x0B\f \r]
    \S        非空白字符:[^\s]
    \w        单词字符:[a-zA-Z_0-9]
    \W        非单词字符:[^\w]
----Greedy 数量词:x 代表规则,当字符不确定或者很多的时候
    X?          X,一次或一次也没有
    X*        X,零次或多次
    X+        X,一次或多次
    X{n}      X,恰好  n  次
    X{n,}       X,至少  n  次
    X{n,m}    X,至少  n  次,但是不超过  m  次
----边界匹配器:
    ^         行的开头
    $         行的结尾
    \b        单词边界
    \B        非单词边界
    \A        输入的开头
    \G        上一个匹配的结尾
    \Z        输入的结尾,仅用于最后的结束符(若有)
    \z        输入的结尾

3、具体操作功能:
    1)匹配:String matches(regex)
    2)切割:String[] split(String regex) 
    3)替换:String replaceAll(String regex, String replacement)String 类中方法:
    4)获取:将字符串中符合规则的子串取出,具体操作步骤如下:
        a)将正则表达式封装成对象
        b)让正则对象和药操作的字符串相关联
        c)获取正则匹配引擎
        d)通过引擎对符合规则的子串进行取出

4、功能选择:
1)只想知道是否正确————>匹配
2)想要将已有的字符串便称另一个字符串————>替换
3)想要按照自己的规则将字符串变成多个子串————>切割
4)想要拿到符合需求的字符串子串————>获取

示例1:
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
 * 正则表达式:
 * 	作用:用于操作字符串
 * 	特点:用于一些特定的字符串来表达一些代码操作---到达简化效果
 * 	好处:可以简化对字符串的校验操作
 * 	弊端:符号定义越多,正则越长,阅读性极差
 * 
 * 具体操作功能:
 * 	1、匹配:String matches(regex)
 * 	2、切割:String[] split(String regex) 
 * 	3、替换:String replaceAll(String regex, String replacement)
 * 	4、获取:将字符串中符合规则的子串取出
 * 	操作步骤:
 * 		1)将正则表达式封装成对象
 * 		2)让正则对象和药操作的字符串相关联
 * 		3)获取正则匹配引擎
 * 		4)通过引擎对符合规则的子串进行取出
 * 
 * 
 */
public class RegexDemo {

	public static void main(String[] args) {
		System.out.println("---------checkQQ-----------");
		checkQQ();
		System.out.println("---------regexDemo1-----------");
		regexDemo1();
		System.out.println("---------checkPhonenum-----------");
		checkPhonenum();
		System.out.println("---------splitDemo-----------");
		splitDemo();
		System.out.println("---------replaceAllDemo-----------");
		replaceAllDemo();
		System.out.println("---------getDemo-----------");
		getDemo();
	}

	// 获取
	public static void getDemo() {
		String str = "zhong guan cong hei ma di shi er qi jiu yao kai ban le.";
		System.out.println("字符串:" + str);
		String regex = "\\b[a-z]{4}\\b";
		// 将规则封装成对象
		Pattern p = Pattern.compile(regex);
		// 让正则对象和要作用的字符串相关联,获取匹配器对象
		Matcher m = p.matcher(str);
		// String类中的matches()用的就是Pattern和Matcher对象来完成的,仅仅为了使用简单而封装的,功能单一

		// 将规则作用到字符串上,并进行符合规则的子串查找
		// boolean flag = m.find();
		// System.out.println(flag);
		// System.out.println(m.group());// 用于获取匹配后的结果
		System.out.println("获取结果为:");
		while (m.find()) {
			System.out.println(m.group());
			System.out.println(m.start() + "..." + m.end());
		}

	}

	// 替换
	public static void replaceAllDemo() {
		String str = "wwwwwwwitheimaaaaacom";
		// 用“#”替换数字
		// String repstr = str.replaceAll("\\d{5,}", "#");

		// 将叠词替换&
		// String repstr = str.replaceAll("(.)\\1+", "&");

		// 将重叠的字母替换成单个字母,用$n(n为前面的组标识)获取前面的组
		String repstr = str.replaceAll("(.)\\1+", "$1");
		System.out.println("字符串:" + str + "替换后结果为:" + repstr);
	}

	// 切割
	public static void splitDemo() {
		String str = "wwwkkitheimaqqcom";
		// str = "d:\\abc\\a.txt";
		// .代表任何字符(与行结束符可能匹配也可能不匹配)要使用必须转义 \\.
		// String regex = "\\.";

		// 路径分隔符\\对应的regex为\\\\
		// String regex = "\\\\";

		// 按照叠词切割.
		// 为了让规则的结果被重用,可以讲规则封装成一个组,用()完成。
		// 组的出现都有编号,从1开始,要想使用就可以通过\n(n为租的编号)表示
		String regex = "(.)\\1+";
		String[] arr = str.split(regex);
		System.out.println("切割结果如下:");
		for (String ar : arr) {
			System.out.println(ar);
		}
	}

	// 匹配测试1
	public static void regexDemo1() {
		String str = "a111111";
		String regex = "[a-z]\\d{3,5}";
		System.out.println("匹配测试1" + str.matches(regex));
	}

	// 匹配手机号:手机号段 13xxx 15xxx 18xxx
	public static void checkPhonenum() {
		String phone = "18767330882";
		String regex = "1[358]\\d{9}";
		boolean flag = phone.matches(regex);
		if (flag) {
			System.out.println("验证手机号" + phone + "---is ok");
		} else {
			System.out.println("验证手机号" + phone + "---is wrrong");
		}
	}

	// 验证QQ号,不能0开头,5-15位,不能有字符
	public static void checkQQ() {
		String qq = "1512465";
		String regex = "[1-9]\\d{4,14}";

		boolean flag = qq.matches(regex);
		if (flag) {
			System.out.println("验证QQ号" + qq + "---is ok");
		} else {
			System.out.println("验证QQ号" + qq + "---is wrrong");
		}
	}
}
结果如图所示:

示例2:

import java.util.Collections;
import java.util.TreeSet;

/*
 * 功能选择:
 * 1、只想知道是否正确————>匹配
 * 2、想要将已有的字符串便称另一个字符串————>替换
 * 3、想要按照自己的规则将字符串变成多个子串————>切割
 * 4、想要拿到符合需求的字符串子串————>获取
 */
public class RegexTest {

	public static void main(String[] args) {
		System.out.println("----------regexTest1----------");
		regexTest1();
		System.out.println("----------ipSort----------");
		ipSort();
		System.out.println("----------checkMail----------");
		checkMail();
	}

	// 对邮件地址进行验证。
	public static void checkMail() {
		String mail = "cavenzzep@163.com.cn";
		String regex = "\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
		System.out.println(mail.matches(regex));
	}

	// * 练习需求: 将下面的字符串转换成(我要进黑马)
	public static void regexTest1() {
		String str = "我我...我我...我要...要要要...要去...去去去...去北京...京京京";
		// 将已有的字符串变成另一个字符串————>替换
		// 1、先将.去掉
		// 2、将重复的内容变成单个子符内容
		str = str.replaceAll("\\.+", "");
		System.out.println(str);
		str = str.replaceAll("(.)\\1+", "$1");
		System.out.println(str);
	}

	// 将ip地址进行地址段顺序排序
	public static void ipSort() {
		String ip = "192.168.0.1 2.2.2.1 168.192.10.10 10.10.10.10 254.254.254.1 255.255.255.1";
		ip = ip.replaceAll("(\\d+)", "00$1");
		System.out.println(ip);
		ip = ip.replaceAll("0*(\\d{3})", "$1");
		System.out.println(ip);

		String[] ips = ip.split(" ");
		TreeSet<String> tree = new TreeSet<String>(Collections.reverseOrder());
		for (String newIp : ips) {
			// System.out.println(newIp);
			tree.add(newIp);
		}
		for (String s : tree) {
			System.out.println(s.replaceAll("0*(\\d+)", "$1"));
		}
	}
}
结果如图所示:

    以上所述仅代表个人观点,如有出入请谅解。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值