异常、常用类、GUI、正则

前端之家收集整理的这篇文章主要介绍了异常、常用类、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(PrintStreams)// 通常用该方法将异常内容保存在日志文件中,以便查阅。
5、自定义异常类
因为项目中会出现特有的问题,而这些问题并未被 java 所描述并封装对象。所以对于这些特有的问题可以按照 java 的对问题封装的思想。将特有的问题,进行自定义的异常封装。
1)自定义异常必须是自定义类继承 Exception。
原因:异常体系有一个特点,因为异常类和异常对象都被抛出,他们都具备可抛性。这个可抛性是 Throwable 这个体系中独有特点,只有 Throwable 体系中的类和对象才可以被 throws 和 throw 操作。
2)自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException。
@H_408_301@ 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,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 length):把字符数组的一部分转换成一个字符串
eg:char[] chs = {'a','e'};
String s = new String(chs,3);
6)String(String str):把一个字符串传递过来作为参数
eg:String ss = new String(s);
7)直接把字符串常量赋值给字符串引用对象(最常用)
eg:String s = "hello";
常见方法 @H_408_301@ 1)获取

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

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

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

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

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

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

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

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

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

@H_408_301@ int lastIndexOf()://反向索引

@H_408_301@ 2)判断

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

@H_408_301@ boolean contains(str);

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

@H_408_301@ 2.2字符串中是否有内容

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

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

@H_408_301@ boolean startsWith(str);

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

@H_408_301@ boolean endsWith(str);

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

@H_408_301@ boolean equals(str);

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

@H_408_301@ boolean equalsIgnoreCase();

@H_408_301@ 3)转换

@H_408_301@ 3.1将字符数组转成字符串

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

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

@H_408_301@ 静态方法

@H_408_301@ static String copyValueOf(char[]);

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

@H_408_301@ static String valueOf(char[]);

@H_408_301@ 3.2将字符串转成字符数组

@H_408_301@ char[] tocharArray();

@H_408_301@ 3.3将字节数组转成字符串

@H_408_301@ String(byte[]);

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

@H_408_301@ 3.4将字符串转成字节数组

@H_408_301@ byte[] getBytes();

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

@H_408_301@ String valueOf(int);

@H_408_301@ String valueOf(double);

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

@H_408_301@ 4)替换

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

@H_408_301@ 5)切割

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

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

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

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

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

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

@H_408_301@ String toUpperCase();

@H_408_301@ String toLowerCase();

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

@H_408_301@ String trim();

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

@H_408_301@ 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 方法变成字符串。
@H_408_301@ 常见操作:

@H_408_301@ 1)存储

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

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

@H_408_301@ 2)删除

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

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

@H_408_301@ 3)获取

@H_408_301@ char charAt(int index);

@H_408_301@ int indexOf(String str);

@H_408_301@ int lastIndexOf(String str);

@H_408_301@ int length();

@H_408_301@ String substring(int start,int end);

@H_408_301@ 4)修改

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

@H_408_301@ void setCharAt(int index,char ch);

@H_408_301@ 5)反转

@H_408_301@ StringBuffer reverse();

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

@H_408_301@ 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,intlength);从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
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,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"));
		}
	}
}
结果如图所示:

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

猜你在找的正则表达式相关文章