@w460461339
2016-11-16T07:02:41.000000Z
字数 7194
阅读 934
Java基础
妈蛋这些视频好长…学吐了= - 还有机器学习的视频要学…God Bless Me。
今天学习的内容有,正则表达式,常用类:Math类,Random类,BigInteger类,BigDecimal类,System类,Date类,DateFormat类,Calender类。
其中,正则表达式主要与字符串的格式判断有关;Math类和Random类主要是一些数学公式以及随机数的获取;BigInteger和BigDecimal分别是为了获得更大范围数值的整数以及高精度的小数;System类主要提供了一些系统内置方法;Date类,DateFormat类以及Calender类都是与日期时间有关的类。
另外,很重要的一点就是,学习的查阅jdk(Java Developer's Kit:Java 的开发者工具包)的API(Application Program Interface 应用程序接口),这样就可以方便的查阅一些内置类以及它们所包含的方法。
先说下应用场景吧。比如我们需要判断一下某个字符串是不是手机号。根据我们了解的手机号特征,我们知道,若这个字符串是手机号,那它必须有11位,并且都是数字;而起开头数字是1……根据这些要求,我们可以写多层if来判断这个字符串是不是满足要求。但这样就显得特别的麻烦。这时可以用正则表达式来解决。
正则表达式可以理解为正确规则的表达式,它本质上是一个字符串,只不过这个字符串定义了正确的规则。我们有两种调用它的方式
Way1:
这个是直接用String类自带的matches方法,来判断该字符串是不是符合要求。
public static void main(String args[]){
String regex="1[0-9]{10}";//表示定义了一个字符串的规则,这个字符串第一位必须是1,后面10位必须是数字。
String phone="18868111057";
boolean flag=phone.matches(regex);//返回boolean值
System.out.println(flag);
}
Way2:
这个方法首先将字符串类型的正则表达式构造成Patter的实例,并利用Matcher类构造了匹配器,以返回匹配结构:
public static void main(String args[]){
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
//或者,只要调用一次时:
boolean b=Patter.matches("a*b","aaaaab");
}
感觉第二种方法烦尿了= - 个人比较喜欢第一种。
这里仅讲几个规范,其他的自己去API的Patter类中查看:
[abc]: a、b 或 c(简单类) (注意这里是方括号)
[^abc]: 任何字符,除了 a、b 或 c(否定)
[a-zA-Z]: a 到 z 或 A 到 Z,两头的字母包括在内(范围)
\d 数字:[0-9]
\w 单词字符:[a-zA-Z_0-9]
\b :单词边界(任意非单词字符)
X?+ X,一次或一次也没有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次 (注意是花括号)
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超过 m 次
需要提醒的是,在这里也存在转义字符,\t\b之类的。所以,比如想要匹配.字符,需要用\ \ .才行(\ \ 相当于输出了一个“\”,然后输出的“\ .”相当于输出的一个“.”,这样就对了;不然“\ .”会报错,“.”是对全字符进行匹配)。
另外一个例子,文件路径“C:\Desktop\Users”这样放在java中会报错,因为会把\D \U认为是转义字符,而实际上又不存在这样的转义字符。因此,需要写成“C:\ \Desktop\ \Users”。在进行匹配的时候,我们需要对两个\ \都要匹配。这里可以发现,匹配时,是对转义前的待匹配字符串进行匹配,而非转义后的字符串。
public static void main(String[] args) throws ParseException {
String phoneNumber="\\";//待匹配字符串
String regex="\\\\";//正则表达式
System.out.println(phoneNumber);//输出转义后字符串,为 \
System.out.println(phoneNumber.matches(regex));//true
}
第一个作用就是用作判断,比如之前的way1,这里就不多说了。还有的作用有分割,替换,先说说分割。
分割功能:
public static void main(String args[]){
String str="hello world! i'm coming!";
String regex="\\s";
String[] word=str.split(regex);//以regex里面的元素为分割标志,将str字符串分割成一个一个子字符串。此处的分割标志是空白字符。
}
替换功能
public static void main(String args[]){
String str="hello world! i'm coming!";
String regex="\\s";
String result=str.repalceAll(regex,"*");//把str中所有与regex相同的字段替换为“*”字符。
}
这两个类真心没什么…需要的时候去API里查一下就好。
由于Math.random()是在[0,1)内取随机数,当需要[a,b)范围内的随机数是,可用:
Math.random()*(b-a)+a
来表示[a,b)内的随机数。至于最后一个值能不能取到,可以自己通过加减的手法类得到。
另外,Math里基本都是静态方法,直接利用Math类名调用即可。
Random必须先创建Random的对象之后,才能够调用里面的方法。具体的方法介绍请查看API。
BigInteger,看名字,就是大整数。是为了解决int Integer不能处理2^31-1以上的运算而构建了。它有许多种构造器,但貌似最后都会调用到他的BigInteger(String number)类构造器,所以一般我们利用它的参数为String类型的构造器来进行构造。另外,不同于与Integer的是,它的加减乘除运算需要通过它内置的方法来进行,而不能用+ — * /运算符。
public static void main(String args[]){
BigInteger num1= new BigInteger("10000000000000");
BigInteger num2= new BigInteger("99999999999999");
BigInteger num3;
num3=num1.add(num2);
num3=num1.subtract(num2);
num3=num1.multiply(num2);
num3=num1.divide(num2);
BigInteger[] num4;
num4=num1.divideAndRemainder(num2);//返回商和余数组成的数组。
}
BigDecimal同理,记得创建对象,其他的这里不多说了,自己查API吧,吃饭了…………
System类可以算是用的最多的类之一了,比如经常用的System.out.println,System.in等等。这里现在主要讲的是利用System对不再有用的对象进行回收。呃,说明一点,由于java有自己的回收机制,会不定时的对垃圾进行回收,所以这里只是为了更好的明白这个回收机制是怎么回事。一般来说,java本身会调用类的finlize()方法来释放内存,该方法存在于Object内。用户可以利用System.gc()来自行调用该对象中的finalize()方法。注意两点,首先若要调用对象中的finalize,必须要明确该对象已经成为垃圾(不在有变量指向它);其次,它是从下向上回收,先回收子类,在回收父类。
class Callback{
private int number=0;
public Callback() {
super();
// TODO Auto-generated constructor stub
}
@Override //覆盖Object内部的finalize类
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
System.out.println("you are out!"+this);
super.finalize();
}
}
public static void main(String args[]){
Callback test= new Callback();//令test指向堆内存中的一个对象
test=null//堆内存的中的对象没有变量指向了,成为了垃圾
System.gc();//调用该类中的finalize方法释放,然后在向上逐个调用。
}
3.2 exit()以及currentRunMillis()
exit()相当于强行中断程序,需要输入一个参数,0表示正常结束,其他则表示非正常结束。
currentRunMillis()返回从1970年1月1日0点至今的毫秒数,返回值是个long类型。不懂就看API。
参数表略多,其实很好理解,就是从src的第srcPos个数据往后数length个,覆盖掉dest中从destPos中往后数length个。
public static void main(String args[]){
int[] array1={1,2,3,4,5};
int[] array2={6,7,8,9,10};
System.arraycopy(array1,2,array2,3,2);//别忘记从0计数
for(int i=0;i<array1.length;i++){//输出为1 2 3 4 5
System.out.println(array1[i]);
}
for(int i=0;i<array1.length;i++){//输出为6 7 8 3 4
System.out.println(array2[i]);
}
}
目前而言,Date类已经过时了,更多的是作为另外几个类的参数或者返回值来使用。我们从Date类入手,来一步步的理解这几个用来处理日期的类。
另外,时间原点是1970年1月1日0点
打开API,查阅Date类就可以看到,满眼的已过时啊……没几个有用的。这里介绍下构造函数以及它的get与set函数就好。
构造函数:
public static void main(String args[]){
//无参构造函数,会将从时间原点到现在的毫秒数输出。
Date date= new Date();
Date date2= new Date(10000);//直接告诉date2, 10000ms。
}
get和set函数:
public static void main(String args[]){
Date date= new Date();
long time1=date.getTime();//返回从时间原点到当前时间的毫秒数。
Date date2= new Date(1000);
//返回从时间原点到设定时间的毫秒数,1000。
long time2=date2.getTime();
date.setTime(1000*60*60);//从时间原点往后加1个小时。
//由于我们是东八区,所以在1小时的基础上再加8小时。
}
由于Date中时间全部用毫秒值来表示,太难看,所以需要将它与格式优雅的String类进行转换的方法。DateFormat类是一个抽象类,它其中提供了将Date类转换成String类的方法。由于它是一个抽象类,需要有子类才能实例化,故存在子类SimpleDateFormat,在该子类中提供将String类型的字符串转为Date的方法。
另外,今后将Date类转换成String类成为格式化;将String类转化为Date类成为解析。
public static void main(String args[]){
Date date= new Date();
//SimlpeDateFormat()无参构造函数,表示用默认格式进行格式化以及解析
SimpleDateFormat sfdate= new SimpleDateFormat();
//将Date类型的对象以默认格式格式化为String类型。
String strdate=sfdate.format(date);//格式化Date类型对象
//将默认格式的String类型时间解析为Date类。
Date date2=sfdate.parse(strdate);//解析String类型对象。
}
上面的代码提到了默认的格式,那么显然,也存在用户自定义的格式,下面给出演示,具体请在API中的SimpelDateFormat类中查看
public static void main(String args[]){
Date date= new Date();
System.out.println(date);//输出年月日小时分钟秒周几等信息
//SimlpeDateFormat()含参构造函数,表示用自定义格式进行格式化以及解析
SimpleDateFormat sfdate= new SimpleDateFormat(“yyyy-MM-dd”);
//将Date类型的对象以自定义格式格式化为String类型。
String strdate=sfdate.format(date);
System.out.println(strdate);//为2015-12-09
//与自定义格式的相同的String类型时间解析为Date类。
Date date2=sfdate.parse(strdate);
System.out.println(date2);//只含有年月日,周几,小时分钟秒全部为0。
//所以未在自定义格式中的某些信息会被丢失。
}
另外,注意一点,由String类型转为Date类型(解析)时,String类型的日期表达要与自定义的格式完全一样,不然会出错。即,需要格式匹配。
日历类,之前很多Date中的方法全部都在Calendar中更新了,所以Date中的许多方法才说过期了= - 但它不是Date的子类,它的直接父类就是Object类。
它是一个抽象类,而调用它需要有它的实例,所以需要用一下方法实例化:
public static void main(String args[]){
//实例化Calendar类(其实是创建了Calendar子类的对象,然后向上造型而已)
Calendar cal= Calerdar.getInstance();
//此时cal已用当前的时间初始化过了
}
想获得当前年份,月份,天,小时等信息,利用get函数以及Calendar提供的静态成员变量即可。下面仅举例而已,另外的通过API,Calendar类查吧
public static void main(String args[]){
Calendar cal= Calendar.getInstance();
int year=cal.get(Calendar.YEAR);
int month=cal.get(Calendar.MONTH);
}
另外,可以通过add方法对年,月, 日,小时等信息做增加或减少操作;以及可以通过set方法重新设定对象所储存时间。
public static void main(String args[]){
Calendar cal= Calendar.getInstance();
cal.add(Calendar.YEAR,+1);//加一年
cal.add(Calendar.MONTH,-3);//减三月
cal.set(Calendar.DAY_OF_MONTH,19);//日期设为月里面19号
}
需要注意的一点是,Calender里面月份从0开始计数,所以:
cal.set(Calendar.MONTH,2);//表示的是3月份。
例子:计算任意年份的2月份天数
public static void main(String args[]){
Scanner in = new Scanner(System.in);
int year=in.nextInt();
Calendar cal= Calendar.getInstance();
cal.set(year,2,1);//将年,月,月中的天数分别重置为:输入的年份,3月(注意!!),1号
cal.add(Calendar.DAY_OF_MONTH,-1);//此时时间为该年2月份最后一天
int day=cal.get(Calendar.DAY_OF_MONTH);//得到该年二月份天数
System.out.println(day);
}