异常:就是程序在运行时出现不正常情况。将问题封装成对象就是异常。
异常由来:问题也是现实生活中一个具体事务,也可以通过 java 的类的形式进行描述。并封装成对象。其实就是 java 对不正常情况进行描述后的对象体现。
Throwable
|---Error //通常出现重大问题如:运行的类不存在或者内存溢出等。
|---Exception //运行时出现的一起情况
|---RuntimeException //特殊异常类,抛时不需要声明
Exception和Error的子类名都是以父类名作为后缀。
异常体系的特点:
1)异常体系中的所有类以及建立的对象都具备可抛性。
2)也就是说可以被throw和throws关键字所操作。
1)编译时被检测异常:
该异常在编译时,如果没有处理(没有抛也没有try),编译失败。该异常被标识,代表着可以被处理。
2)运行时异常(编译时不检测):
在编译时,不需要处理,编译器不检查。该异常的发生,建议不处理,让程序停止,需要对代码进行修正例如:RuntimeException以及其子类。
4、throw和throws
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
当函数内容有throw抛出异常对象,并未进行try处理。必须要在函数上声明,否则编译失败。
Note:throws 和 throw 的区别:
throws 使用在函数上(写在小括号和大括号之间)。throw 使用在函数内。
throws 后面跟的异常类。可以跟多个。用逗号隔开。throw 后跟的是异常对象。
常见方法操作:
String getMessage();//获取异常的信息。返回字符串。
toString();//获取异常类名和异常信息,返回字符串。
printStackTrace(); //获取异常类名和异常信息,以及异常出现在程序中的位置.返回值void.
//其实JVM默认的异常处理机制,就是在调用printStackTrace方法,打印异常的堆栈的跟踪信息。
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("换老师或者放假");
}
}
}
二、常用类
概述:存在于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 修饰的类,所以不可能有子类。字符串一旦初始化就不可以被改变(此处指的是内存中的地址值不可改变)。
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 相同。
常见操作:
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。
概述: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); //在单独的进程中执行指定的字符串命令。
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(); //创建时间对象
第二种:
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(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)让正则对象和药操作的字符串相关联
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"));
}
}
}
结果如图所示:以上所述仅代表个人观点,如有出入请谅解。