@System类&抽象类与接口的区别&Date类
增强for循环:
String [ ] arr="abcde";
for(String s:arr){
System.out.println(s);
}
增强for循环的好处是不计入循环次数,所以执行速度快效率高,但是也有弊端,增强for循环不可控,从第一个元素遍历到最后一个元素,而且不记入循环次数。
for循环:
- 迭代for循环(普通for循环):可以控制循环次数
- for each(增强for循环):运行速度快,但是循环次数不可控。
if循环和for循环的嵌套最好不要超过三层,因为超过三层以后很容易会有逻辑上的漏洞。
正则表达式:用来校验字符串的规则。
regex表示正则的类。
例题:
判断用户输入的字符串,要求:2位到5位,由数字,字母,下划线组成,不允许有其他字符。
如果不使用正则表达式,那么代码将及其冗长且易出错;
```
1 package com; 2 3 import java.util.Scanner; 4 5 public class Demo { 6 7 public static void main(String[] args) { 8 Scanner sc=new Scanner(System.in); 9 String str=sc.next(); 10 char[] arr=str.toCharArray(); 11 if(str.length()>=2&&str.length()<=5) { 12 boolean flag=false; 13 for(char s:arr) { 14 if(!(s>='a'&&s<='z'||s>='A'&&s<='Z')) { 15 if(!Character.isDigit(s)) { 16 if(!(s=='_')) { 17 flag=true; 18 } 19 } 20 } 21 } 22 if(flag) { 23 System.out.println("不合法"); 24 } 25 else { 26 System.out.println("合法"); 27 } 28 29 } 30 else { 31 System.out.println("不合法"); 32 } 33 } 34 35 }
```
而使用了正则表达式以后,代码会简洁很多
```
1 package com; 2 3 import java.util.Scanner; 4 5 public class Demo { 6 7 public static void main(String[] args) { 8 Scanner sc=new Scanner(System.in); 9 String str=sc.next(); 10 String regex="[0-9a-zA-Z_]{2,5}"; 11 boolean result=str.matches(regex); 12 System.out.println(result); 13 14 15 } 16 }
```
使用了正则表达式的代码,简洁,逻辑清晰,不易出错,这就是正则表达式存在的意义。
正则表达式 [该位置允许出现的字符]{该字符可以出现的次数}
元字符:
.表示任何字符
d表示数字
D表示非数字
s表示空白字符 space
S表示非空白字符
w表示单词字符 (数字 字母) word
W表示非单词字符
*任意多次
+至少一次
?至多一次
matches 匹配 校验方法
使用正则表达式来简单校验手机号 规则: 以1开头,第二位为 3,5,7,8
1[3578]\d{9}另一种非主流写法
1[(3)|(5)|(7)|(8)]\d{9};
使用正则表达式来简单的校验邮箱:
[0-9]\w*@\w+\.com
类只能单继承,也就是说一个类只能继承一个父类,而一个接口,却可以继承多个接口,原因如下:
首先:接口中的方法都是抽象方法,都没有被实现,而抽象类中有的方法不是抽象方法,如果一个类可以继承多个类,恰好这多个类中都有同名的非抽象方法,那么调用时该调用哪一个方法就不知道了,这也是为什么类只能继承一个类的原因,下面将用简单的代码来说明:、
abstract class T{
public viod fun();
}
abstract class T2{
public void fun();
}
如果有一个子类同时集成了T 和T2
class Zi extends T,T2{
那么它在调用fun()方法时系统就无法知道它调用的是哪一个父类的fun()方法。
}
下面用接口来说明一下:
1 interface Y{ 2 abstract void fun(); 3 } 4 interface Y2{ 5 abstract void fun(); 6 } 7 interface Y3 extends Y,Y2{ 8 因为父接口的两个fun()方法都是抽象的,都没有被实现,所以这两个方法是完全相同的两个方法,调用哪一个都是一样的,所以接口可以继承多个接口。 9 }
下面来介绍一次抽象类和接口的区别:
抽象类:为同一事物,有“血缘关系”
接口: 许多事物都具有的共性功能
拿缉毒犬来举一个例子
1 abstract class Dog{ 2 //狗的属性和功能 3 } 4 abstract class Pig{ 5 //猪 的属性和功能 6 } 7 interface JD{ 8 public void jd(); //缉毒方法 9 } 10 interface DM{ 11 public void dm(); //导盲方法 12 } 13 14 class JDDog extends Dog implements JD{ //这是一条缉毒犬 15 public void jd(); 16 } 17 class DMDog extends Dog implements DM{ //这是一条导盲犬 18 public void dm(); 19 } 20 class JDPig extends Pig implements JD{ //这是一只缉毒猪 21 public void jd(); 22 }
缉毒犬有缉毒的功能,但是其他犬没有缉毒的功能,所以将狗的属性,功能写在Dog类中,将缉毒的方法
写在缉毒接口中,不光有缉毒犬,还有缉毒猪,这样缉毒猪也可以实现缉毒接口。还有导盲犬,实现导盲
的接口。各个动物都写在抽象类中,特有的功能写在接口中
假如每个抽象类都是竖着的个体,那么接口就是一个横着贯穿这些抽象类的东西。可以用一幅图来形象的
描述
错误流的输出是随机的,不一定在哪出现
1. day02 课堂笔记
1.1. 正则表达式
1. 用来校验字符串的规则, 实质:字符串
2. 格式:
该位置可以出现的字符 [ 这些字符可以出现的次数 ]
3. 规则 :
该位置可以出现的字符 [ 该字符可以出现的次数 ]
1 》字符:正则表达式 字符 分为 :原义字符 、元字符
*** 元字符 / 预定义字符:
① . 表示任意字符
② d 表示数字 [0-9]
③ D 表示非数字 [^0-9]
④ s 表示空白字符 [
x0Bf
]
⑤ S 表示非空白字符 [^s]
⑥ w 表示单词字符 [a-zA-Z0-9_]
⑦ W 表示非单词字符 [^w]
2 》次数 :
*** 数量词:
① * 任意次数
② + 至少一次
③ ? 至多一次
④ {n} n 次
⑤ {n,} 大于等于 n 次
⑥ {n,m} n 到 m 次
3 》边界匹配器:
① ^ 表示行的开头
② $ 表示行的结尾
③ 表示单词的边界
4. 分组: () 表示
代码演示:
1 public static void main(String[] args) { 2 // 规则: 数字组成 、 5 到 11 位 --> 升级 -- 》第一位必须是数字 1 3 String qq="212345"; 4 // 校验 : 5 String qqReg="1\d{4,10}"; 6 //String str.matches(reg) 校验 当前 str 字符串是否符合 reg 规则 7 System.out.println(qq.matches(qqReg)); 8 } 9 代码演示分组: 10 public static void main(String[] args) { 11 String tel="13451241235"; 12 // 数字组成, 11 位,必须 1 开头,第二位为 3,5,7,8 。 13 // String reg="1[3578]\d{9}"; 14 // 分组的形式 ( 了解内容 ) 15 String reg="1((3)|(5)|(7)|(8))\d{9}"; 16 System.out.println(tel.matches(reg)); 17 }
1.1.1. 正则表达式补充内容 ( 了解 )
正则表达式可以进行其他操作,如提取
代码演示:
1 public static void main(String[] args) { 2 String msg="adfas123 我 sfsdf 我 1235s 我 dfsdf123"; 3 // 把数字提取出来 4 /* compile(reg) 用来预编译正则表达式的规则 5 * Pattern p = Pattern.compile("a*b"); 6 * matcher(str) 用来进行操作的 str ,表示 str 是否能够匹配预编译的规则。 7 Matcher m = p.matcher("aaaaab"); 8 boolean b = m.matches(); 9 */ 10 Pattern co = Pattern.compile(" 我 "); 11 Matcher matcher = co.matcher(msg); 12 /*System.out.println(matcher.find()); 13 System.out.println(matcher.group());*/ 14 // find() 表示搜索字符串中是否有与规则匹配的字符串,有返回 true 15 while(matcher.find()) { 16 System.out.println(matcher.start()); 17 // group() 表示查找字符串中符合规则的字符串,有返回该字符串 18 System.out.println(matcher.group()); 19 } 20 }
1.2. 常用类
1.2.1. Math 类
1. 工具类:
辅助其他类实现某些功能的, Math 、 Arrays
2. 常用的方法与属性:
① PI : 圆周率
② abs(obj) 返回 obj 绝对值
③ cbrt(obj) 返回 obj 的立方根
*** ④ ceil(double a) 返回一个等于某个整数的 double 的值,该值大于等于 a 的整数
*** ⑤ floor(double a) 返回一个等于某个整数的 double 的值,该值小于等于 a 的整数
*** ⑥ round(double a) 四舍五入,返回 long 类型的值。
⑦ pow(double a, double b) 求第一个参数的第二个参数次幂 返回值 double 类型
⑧ random() 随机数 表示从 [0,1.0)
代码演示:
1 public class Math 类 { 2 public static void main(String[] args) { 3 // PI : 圆周率 4 // System.out.println(Math.PI); 5 //abs(obj) 返回 obj 绝对值 6 // System.out.println(Math.abs(-5)); 7 // cbrt(obj) 返回 obj 的立方根 8 // System.out.println(Math.cbrt(27)); 9 System.out.println("====================="); 10 //ceil/floor/round 11 /*System.out.println(Math.ceil(10.7)); 12 System.out.println(Math.floor(10.7)); 13 System.out.println(Math.round(10.7));*/ 14 //pow(double a, double b) 求第一个参数的第二个参数次幂 15 // System.out.println(Math.pow(2, 3)); 16 // random() 随机数 表示从 [0,1.0) nextInt(11) 17 System.out.println(Math.floor(Math.random()*10+1)); 18 } 19 }
System 类
1. 标准输入、输出流、错误流
① 标准输入 System.in
② 标准输出 System.out
③ 标准错误流 System.err
2.arrayCopy(src,srcPos,dest,destPos,length) 快速数组复制
src : 原数组
srcPos: 原数组开始复制的索引值
dest :目标数组
destPost: 目标数组中要放置的位置
length: 表示复制的长度。
3.currentTimeMillis() 返回当前时刻的毫秒值。从 1970 年 1 月 1 日 0 时 0 分 0 秒开始的。
4.exit(0) 表示退出 jvm 。其中 0 表示正常退出。
5.gc(): java 垃圾回收机制:自动的垃圾回收机制。
代码演示:
1 public class System 类 { 2 public static void main(String[] args) { 3 /*System.out.println("===========1"); 4 System.err.println("==========5"); 5 System.out.println("===========2"); 6 System.out.println("===========3"); 7 System.out.println("===========4");*/ 8 // Scanner sc=new Scanner(System.in); 9 // System.out.println(5/0); 10 //arrayCopy(src,srcPos,dest,destPos,length) 11 /*int[] arr= {1,5,2,4}; 12 int[] brr= new int[10]; 13 System.arraycopy(arr, 1, brr, 3 , 2); 14 arr[2]=10; 15 System.out.println(Arrays.toString(arr)); 16 System.out.println(Arrays.toString(brr));*/ 17 //switch 循环 -->break 18 /*System.out.println("======1"); 19 System.exit(0); 20 System.out.println("======2");*/ 21 // 了解 getProperties() 获取系统的属性集 22 Properties prp = System.getProperties(); 23 Set<Entry<Object, Object>> entrySet = prp.entrySet(); 24 Iterator<Entry<Object, Object>> it = entrySet.iterator(); 25 while(it.hasNext()) { 26 Entry<Object, Object> entry = it.next(); 27 System.out.println(entry.getKey()+"======>"+entry.getValue()); 28 } 29 } 30 }
1.2.2. Date 类
1.Date 表示特定的瞬间 表示当前的时刻
2. 构造方法 :
① Date() 表示当前的时间
默认表示的是 cst 的时间:
CST 可视为美国、澳大利亚、古巴或中国的标准时间
② Date(long) 表示从 1970 年 1 月 1 日 0 时 0 分 0 秒开始的毫秒值。
3. 常用方法:
① getTime() 获取从 1970 年 1 月 1 日 0 时 0 分 0 秒开始的毫秒值。
代码演示:
1 public class Date 类 { 2 public static void main(String[] args) { 3 Date d=new Date(); 4 /* System.out.println(d); 5 Date d1=new Date(1000); 6 System.out.println(d1);*/ 7 // System.out.println(d.getDate()); 8 System.out.println(d.toGMTString()); 9 System.out.println(d.toLocaleString()); 10 } 11 }
1.2.3. Calendar 类
1.Calendar 表示日历类,
2. 创建对象的方法:
① getInstance() 获取日历类
3. 常用方法:
① set(int field, int value) /get(field) 设置 / 获取字段的值
代码演示:
1 public class Calendar 类 { 2 public static void main(String[] args) { 3 //getInstance() 获取日历类 4 Calendar in = Calendar.getInstance(); 5 // 月份是从 0 开始,需要加 1 6 // System.out.println(in.get(Calendar.MONTH)); 7 // 年月日 8 /*System.out.println(in.get(Calendar.YEAR)); 9 System.out.println(in.get(Calendar.MONTH)+1); 10 System.out.println(in.get(Calendar.DAY_OF_MONTH)); 11 // 时分秒 12 System.out.println(in.get(Calendar.HOUR_OF_DAY)); 13 System.out.println(in.get(Calendar.MINUTE)); 14 System.out.println(in.get(Calendar.SECOND));*/ 15 // 星期 从周日开始 到周六结束 16 // System.out.println(in.get(Calendar.DAY_OF_WEEK)-1); 17 // 设置当前的日期为 15 18 // in.set(Calendar.DAY_OF_MONTH, 15); 19 //add 添加 20 in.add(Calendar.DAY_OF_MONTH, 31); 21 System.out.println(in.get(Calendar.DAY_OF_MONTH)); 22 } 23 }
1.2.4. SimpleDateFormat 类
模式:
1. 时间 / 日期格式化的类,但是该类是一个抽象类。
2. 使用的子类 SimpleDateFormat 。
3. 概念 :
① 格式化
日期 --> 字符串
② 解析
字符串 --> 日期
4.SimpleDateFormat :
① 构造方法 :
SimpleDateFormat(String pattern)
** 模式 :
y 年
M 月
d 日
H 0-23 小时
m 分钟
s 秒
建议 : 解析或者格式化时,最好使用同一个模式。
**② 常用方法:
1 》 format( 时间 ) 格式化 时间 -- 》字符串
2 》 parse(str) 解析 字符串 -- 》时间
代码演示:
1 public class DateFormat 类 { 2 public static void main(String[] args) throws ParseException { 3 // SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 4 SimpleDateFormat sf=new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒 "); 5 // 将日期格式化为字符串 format(date) 6 // String value = sf.format(new Date()); 7 //2019 年 04 月 02 日 16 时 25 分 48 秒 --> 转成日期格式: 解析 : 字符串 --> 日期格式 parse(str) 将字符串解析为 8 日期格式 9 Date valueP = sf.parse("2019 年 04 月 02 日 16 时 25 分 48 秒 "); 10 System.out.println(valueP); 11 } 12 }
1.2.5. 练习之计算出生日期距今天数
代码演示:
1 package exec; 2 import java.text.ParseException; 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 import java.util.Scanner; 6 7 课程内容 8 1. 输入出生的年月日,算出距离今天你出生了多少天? 9 思路 : 10 ① 字符串 -- 》 转换为时间 -- 》出生的日期 11 ② 出生到现在的毫秒值? 12 ③ 换算该毫秒值为天数。 13 */ 14 public class Topic1 { 15 public static void main(String[] args) throws ParseException { 16 Scanner sc=new Scanner(System.in); 17 System.out.println(" 请输入您的出生日期 格式为 : yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒 "); 18 //2019 年 03 月 29 日 00 时 00 分 00 秒 19 // 获取出生日期的字符串 20 String birth = sc.nextLine(); 21 // 将字符串转换为时间 22 SimpleDateFormat sf=new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒 "); 23 // birth-->date 字符串转时间 解析 24 Date birthTime = sf.parse(birth); 25 // 出生到现在的毫秒值 现在的毫秒值 - 出生的毫秒值 getTime() 获取毫秒值 26 long time=new Date().getTime()-birthTime.getTime(); 27 System.out.println(time/1000/3600/24); 28 } 29 }