Java笔记day20
一、包装类
1、包装类概述
为了对基本数据类型进行更多的操作,更方便的操作,Java就针对每一个基本数据类型
都提供了对应的类类型。我们叫做包装类类型。
2、包装类类型:
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
3、包装类常见的使用场景:
1)、集合中的泛型
2)、用于基本数据类型与字符串之间做转换使用
4、包装类的使用1(进制转换)
需求1:将100这个数据,计算出它的二进制,八进制,十六进制
需求2:如何用代码求出int类型的数据范围
查看代码
public class PackingDemo1 {
public static void main(String[] args) {
//public static String toBinaryString(int i) 求int类型数据的二进制
String s = Integer.toBinaryString(100);
System.out.println("100的二进制为:" + s);
//public static String toOctalString(int i) 求出int类型数据的八进制
String s1 = Integer.toOctalString(100);
System.out.println("100的八进制为:" + s1);
//public static String toHexString(int i) 求出int类型数据的十六进制
String s2 = Integer.toHexString(100);
System.out.println("100的十六进制为:" + s2);
//求出int类型所能表达的最小值
//public static final int MIN_VALUE
System.out.println("int类型数据的最小值为:" + Integer.MIN_VALUE);
//求出int类型所能表达的的最大值
//public static final int MAX_VALUE
System.out.println("int类型数据的最大值为:" + Integer.MAX_VALUE);
}
}
5、包装类的使用2(基本数据类型与字符串之间的转换)
int类型与String类型相互转换
int -- String
public static String valueOf(int i)
String -- Integer -- int
public static int parseInt(String s)
将字符串解析成一个十进制的整数,如果字符串中有不是整数的字符出现,报错转换不了
查看代码
public class PackingDemo2 {
public static void main(String[] args) {
//int -- String
int num = 100;
//方式1:public static String valueOf(int i)
String s = String.valueOf(100); //最常用
System.out.println(s);
System.out.println("**********************************");
//方式2:int - Integer - String
//String s1 = new String(num);
//Integer(int value)
//构造一个新分配的 Integer对象,该对象表示指定的 int值。
Integer integer = new Integer(num);
System.out.println(integer); //Integer重写了toString()方法
//public String toString()返回String表示此对象Integer的价值。
String s2 = integer.toString();
System.out.println(s2);
System.out.println("**********************************");
//方式3:与空字符串拼接
String s3 = "" + num;
System.out.println(s3);
System.out.println("**********************************");
//方式4:public static String toString(int i)
String s4 = Integer.toString(100);
System.out.println(s4);
System.out.println("********** String -- int ****************");
//String -- int
String string = "100";
//方式1:
//String -- Integer -- int
Integer integer1 = new Integer(string);
System.out.println(integer1);
//public int intValue() 将 Integer的值作为 int 。
int i = integer1.intValue(); //此处可以是int i = integer1;自动转换
int i2 = integer1; //包装类中称之为自动拆箱,integer直接转为int
Integer integer2 = 100; //包装类中称之为自动装箱,int直接转为integer
System.out.println(i);
System.out.println("**********************************");
//方式2:
//public static int parseInt(String s)
int i1 = Integer.parseInt("100"); //最常用
System.out.println(i1);
//NumberFormatException,数据类型异常
//int i3 = Integer.parseInt("100abc");
//System.out.println(i3);
}
}
二、正则表达式
1、正则表达式概述
正则表达式的概念
使用单个字符串来描述或者描述/匹配一系列符合某个语法规则的字符串
正则表达式的目的
通过正则表达式处理了字符串复杂的查找/替换/匹配/分割工作、
正则表达式的使用
正则表达式是独立于任何语言的技术(C语言,C++,Python,Scala等都能使用)
正则表达式的使用步骤:
1)、通过大量的字符串你找规律定义规则
2)、使用这种规则去匹配新的字符串
3)、匹配成功做出相应的操作
2、正则表达式的引入
校验QQ号是否合法
1)、必须是5-10位的 10000
2)、0不可以作为QQ号的开头
3)、必须都是数字组成
校验邮箱是否合法
1)、名称是由数字或字母特殊符号组成
2)、长度5-10
3)、含有@符号
4)、...
查看代码
public class RegularDemo1 {
public static void main(String[] args) {
String s = "1165872335";
System.out.println(checkQQ(s));
System.out.println(checkQQ2(s));
}
//不使用正则表达式
public static boolean checkQQ(String qq){
boolean flag = false;
//判断qq号长度是否是5-10位的
if(qq.length()>=5 && qq.length()<=10){
//0不可以作为QQ号的开头
if(!qq.startsWith("0")){
flag = true;
//必须都是数字组成
char[] chars = qq.toCharArray();
for(int i=0;i<chars.length;i++){
//public static boolean isDigit(char ch)确定指定的字符是否是数字。
if(!Character.isDigit(chars[i])){
flag = false;
break;
}
}
}
}
return flag;
}
//使用正则表达式
public static boolean checkQQ2(String qq){
//使用正则表达式可以很容易地完成字符串地查找/匹配替换等工作
String regex = "[1-9][0-9]{4,9}";
return qq.matches(regex);
}
}
3、正则表达式分类介绍
1)、原义字符
字符本身就是一个正则
查看代码
public class RegularDemo2 {
public static void main(String[] args) {
String str = "ab123241dasdasw&;123.";
System.out.println("替换之前:" + str);
//字符串中有一个方法替换所有符合要求的字符串
//String replaceAll(String regex, String replacement)
String regex = "ab";
//如果没有匹配到符合正则表达式规则的式子,返回原来的字符串
System.out.println("替换之后:" + str.replaceAll(regex, "_"));
//替换的是双引号之间的字符串,如果不存在就不改变
//如果是String regex = ".";就全部替换,String regex = "\\.";替换字符串中的点
}
}
2)、元字符
A、字符类
查看代码
public class RegularDemo3 {
public static void main(String[] args) {
//表示格式:[]
//[]表示将字符进行归类,可以匹配出现在中括号中的任意一个字符
//只要被匹配的字符串中存在a,b,2中任何一个,都会被替换
String regex = "[ab2]";
String s = "ab123241dasdasw&;123.";
System.out.println(s.replaceAll(regex, "_"));
//^出现在中括号中,代表的意思式取反,对不是ab2的字符进行匹配
regex = "[^ab2]";
System.out.println(s.replaceAll(regex, "+"));
}
}
****__1_3_41d_sd_sw&;1_3.****
****ab+2+2+++a++a+++++2++****
B、范围类
其实是在字符类的基础之上增加了范围
查看代码
public class RegularDemo4 {
public static void main(String[] args) {
String regex = "[ab]";
String s = "abcdefghijklmnBV1232QWE41dasdasw&;123.";
System.out.println("匹配之前:\n" + s);
System.out.println("======================================");
System.out.println(s.replaceAll(regex, "_"));
//[a-z]表示的是匹配a到z中的任意一个小写字母
regex = "[a-z]";
System.out.println(s.replaceAll(regex, "_"));
//[A-Z]表示的是匹配a到z中的任意一个大写字母
regex = "[A-Z]";
System.out.println(s.replaceAll(regex, "+"));
//既想匹配小写又想匹配大写
regex = "[a-zA-Z]";
System.out.println();
System.out.println(s.replaceAll(regex, "#"));
//想匹配数字咋办
regex = "[0-9]";
System.out.println(s.replaceAll(regex, "_"));
//既想匹配小写又想匹配大写和数字
regex = "[a-zA-Z0-9&;.]";
System.out.println(s.replaceAll(regex, "_"));
}
}
****abcdefghijklmnBV1232QWE41dasdasw&;123.****
****======================================****
****__cdefghijklmnBV1232QWE41d_sd_sw&;123.****
****______________BV1232QWE41_______&;123.****
****abcdefghijklmn++1232+++41dasdasw&;123.****
****################1232###41#######&;123.****
****abcdefghijklmnBV____QWE__dasdasw&;___.****
****______________________________________****
C、预定义类:
我们在上面的范围类的情况下我们在实际开发中可能会遇到一些常见的需求,
比如:判断是否是数字、小写字母、大写字母等这些情况,对应的范围类的正则会比较长,
所以在正则表达式中会给我们预定一些有特殊含义的表达式,正则表达式把我们常见的整理了一下
\d == [0-9] 数字
\D == [^0-9] 非数字
空白字符:[\t\n\x0B\f\r] == \s
[^ \t\n\x0B\f\r] == \S
\w == [a-zA-Z0-9]
\W == [^a-zA-Z0-9]
. 任何字符(与行结束符可能匹配也可能不匹配)
查看代码
public class RegularDemo5 {
public static void main(String[] args) {
String regex = "[0-9]";
String s = "abcdefghijklmnB V1232Q WE 41dasdasw&;123.";
System.out.println("匹配之前:\n" + s);
System.out.println("====================================");
System.out.println(s.replaceAll(regex, "_"));
regex = "\\d"; //[0-9] 匹配所有的数字
System.out.println(s.replaceAll(regex, "_"));
regex = "\\D"; //匹配所有非数字的字符
System.out.println(s.replaceAll(regex, "_"));
regex = "\\s"; //匹配所有空白字符
System.out.println(s.replaceAll(regex, "!"));
regex = "\\S"; //匹配所有非空白字符
System.out.println(s.replaceAll(regex, "_"));
regex = "\\w"; //匹配所有的大小写字母和数字
System.out.println(s.replaceAll(regex, "_"));
regex = "\\W"; //匹配所有的非大小写字母和数字
System.out.println(s.replaceAll(regex, "_"));
regex = "."; //匹配任何字符
System.out.println(s.replaceAll(regex, "_"));
regex = "\\.";//匹配点
System.out.println(s.replaceAll(regex, "_"));
}
}
****匹配之前:****
****abcdefghijklmnB V1232Q WE 41dasdasw&;123.****
****====================================****
****abcdefghijklmnB V____Q WE __dasdasw&;___.****
****abcdefghijklmnB V____Q WE __dasdasw&;___.****
****_________________1232_____41_________123_****
****abcdefghijklmnB!V1232Q!WE!41dasdasw&;123.****
****_______________ ______ __ _______________****
****_______________ ______ __ _________&;___.****
****abcdefghijklmnB_V1232Q_WE_41dasdasw__123_****
****_________________________________________****
****abcdefghijklmnB V1232Q WE 41dasdasw&;123_****
D、边界字符
^:以xxx开头
$:以xxx结尾
\b:单词边界
\B:非单词边界
查看代码
public class RegularDemo6 {
public static void main(String[] args) {
//在没有中括号的时候,^代表的是以什么开头
String regex = "^ac"; //以ac开头,没有就不替换
String s = "abcdefg";
System.out.println("匹配之前:\n" + s);
System.out.println("====================================");
System.out.println(s.replaceAll(regex, "_"));
regex = "fg$";
System.out.println(s.replaceAll(regex, "_"));
regex = "\\b";
s = "Hello World 888 1 2 & ; 0 a b c d";
System.out.println(s.replaceAll(regex, "_"));
regex = "\\B";
System.out.println(s.replaceAll(regex, "_"));
}
}
****匹配之前:****
****abcdefg****
****====================================****
****abcdefg****
****abcde_****
****_Hello_ _World_ _888_ _1_ _2_ & ; _0_ _a_ _b_ _c_ _d_**** //符号不是的单词,所以没有下划线
****H_e_l_l_o W_o_r_l_d 8_8_8 1 2 _&_ _;_ 0 a b c d****
E、量词
?:出现0次或者1次
+:出现1次或者多次
*:出现任意次
{n}:出现正好n次
{n,m}:出现n-m次
{n,}出现至少n次
查看代码
public class RegularDemo7 {
public static void main(String[] args) {
//匹配以a开头的0次或者1次,出现一次就替换,出现0次就添加
//String regex = "^a?";
String regex = "^b?";
String s = "aaaaabcdefaaaaaag";
System.out.println("匹配之前:\n" + s);
System.out.println("====================================");
System.out.println(s.replaceAll(regex, "_"));****_aaaaabcdefaaaaaag****
regex = "^a+";
System.out.println(s.replaceAll(regex, "_"));****_bcdefaaaaaag****
regex = "^b+"; //只有出现一个或者多个才改变,不然不变
System.out.println(s.replaceAll(regex, "_"));****aaaaabcdefaaaaaag****
regex = "^a*";
System.out.println(s.replaceAll(regex, "_"));****_bcdefaaaaaag****
regex = "^b*";
System.out.println(s.replaceAll(regex, "_"));****_aaaaabcdefaaaaaag****
//{n}:出现正好n次
//匹配a连续出现了6次
//aaaaabcdefaaaaaag
regex = "a{6}";
//s = "aaaaabcdefaaaaaag";
System.out.println(s.replaceAll(regex, "_"));
regex = "a{3}";
System.out.println(s.replaceAll(regex, "_"));
//{n,m}:出现n-m次
regex = "^a{3,4}";
System.out.println(s.replaceAll(regex, "_"));
//{n,}出现至少n次
regex = "a{6,}";
System.out.println(s.replaceAll(regex, "_"));
}
}
****匹配之前:****
****aaaaabcdefaaaaaag****
****====================================****
****_aaaaabcdefaaaaaag****
****_bcdefaaaaaag****
****aaaaabcdefaaaaaag****
****_bcdefaaaaaag****
****_aaaaabcdefaaaaaag****
****aaaaabcdef_g****
****_aabcdef__g****
****_abcdefaaaaaag****
****aaaaabcdef_g****
F、分组
分组符号为 "( )"
查看代码
public class RegularDemo8 {
public static void main(String[] args) {
//表示匹配的是ab加上n个c
String regex = "abc{1,2}";
String s = "abccccABC123123baCBAabcccccABCabcabcabc123";
System.out.println("匹配之前:\n" + s);
System.out.println("====================================");
System.out.println(s.replaceAll(regex, "_"));
//表示匹配abc这个整体出现了1次到2次
regex = "(abc){1,2}";
System.out.println(s.replaceAll(regex, "+"));
//表示匹配ABC加上出现了一个或者多个123,abc
regex = "ABC(123|abc){1,}";
System.out.println(s.replaceAll(regex, "+"));
System.out.println(s.matches(regex)); //false
}
}
****匹配之前:****
****abccccABC123123baCBAabcccccABCabcabcabc123****
****====================================****
****_ccABC123123baCBA_cccABC___123****
****+cccABC123123baCBA+ccccABC++123****
****abcccc+baCBAabccccc+****
****false****
G、反向引用
使用$引用对应组号的内容,每一个匹配的内容组号从1开始编号
查看代码
public class RegularDemo9 {
public static void main(String[] args) {
//2018-04-27 ---> 04/27/2018
String regex = "(\\d{4})-(\\d{2})-(\\d{2})"; //\\d表示数字,后面大括号中的数字表示数字的个数
String str = "2018-04-27 2021-12-17";
System.out.println(str.replaceAll(regex, "$2/$3/$1"));
//2018-04-27 ---> 04/27/2018
//分组中如果不想要生成分组编号,可以通过?:来实现
regex = "(\\d{4})-(?:\\d{2})-(\\d{2})";
str = "2018-04-27 2021-12-17";
System.out.println(str.replaceAll(regex, "$2/$1")); //这里不能有3,不然会有索引越界异常
}
}
****04/27/2018 12/17/2021****
****27/2018 17/2021****
4、正则表达式在Java中的应用
1)、字符串的查找操作:Pattern和Matcher
2)、字符串匹配操作:可以用该字符串的matchers方法
3)、字符串的替换操作:字符串的replaceAll()和replaceFirst()方法
4)、字符串的分割:字符串的split()方法,最常用
查看代码
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ReDemo10 {
public static void main(String[] args) {
String regex = "\\w{3,}"; //三个或三个以上英文字母或数字
String str = "abcd123";
System.out.println(str.replaceAll(regex,"_")); //_
System.out.println(str.matches(regex)); //true
regex = "[a-z]{2,}"; //两个或两个以上的英文字母
str = "abc efgsd hello111";
System.out.println(str.replaceAll(regex,"X")); //X X X111
System.out.println(str.replaceFirst(regex,"X")); //XX efgsd hello111
str = "abc,sdf 123ab sa123bds & ";
String[] split = str.split(","); //分割之后长度为2
System.out.println(Arrays.toString(split)); //[abc, sdf 123ab sa123bds & ]
regex = "[as1]";
String[] split2 = str.split(regex); //匹配到就用 隔开,两个字符串之间用逗号隔开
System.out.println(Arrays.toString(split2)); //[, bc,, df , 23,b ,,,23bd, & ]
//Pattern API
regex = "\\w{3,7}";
Pattern compile = Pattern.compile(regex);
Matcher matcher = compile.matcher("abcd123aaaa112321dddd333");
//System.out.println(matcher.matches()); //ture 表示是否匹配,是否符合,比较的是一整个
System.out.println(matcher.find()); //true 表示的是一部分
System.out.println(matcher.end()); //7
System.out.println(matcher.group()); //abcd123
System.out.println(matcher.find()); //true
System.out.println(matcher.end()); //14
System.out.println(matcher.group()); //aaaa112
}
}
5、正则表达式验证的网站:
https://regexper.com/
在开发中若要使用正则表达式可以直接在网上找
6、正则表达式练习
治疗口吃
将字符串“我我我我我我我..........我.......要要要要要..................
要要要要...学习习习习.......习习习习习习习习编程程程程程程.......程程程程程程程程程”
变成“我要学习编程”
分析:先将....去掉:使用"\\.+"模式,再将叠词替换成一个:使用"(.)\\1+"模式。
查看代码
public class Demo01 {
public static void main(String args[])
{
String str="我我我我我我我..........我.......要要要要要..................要要
要要...学习习习习.......习习习习习习习习编程程程程程程.......程程程程程程程程程";
//1.先去掉.
String regex="\\.+";
str=str.replaceAll(regex, "");
//System.out.println(str);
//2.合并叠词。
regex="(.)\\1+";
str=str.replaceAll(regex, "$1");
System.out.println(str);
}
}
三、枚举类型
1、 JDK1.5之前使用自定义枚举
查看代码
public class EnumDemo1 {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring);
}
}
class Season{
//2、创建枚举类的属性(成员遍历),必须是作为私有常量出现
private final String SEASON_NAME;
private final String SEASON_DESC;
//1、必须将构造方法私有化,这是为了保证类的对象是有限个的目的
private Season(String SEASON_NAME,String SEASON_DESC){
this.SEASON_NAME = SEASON_NAME;
this.SEASON_DESC = SEASON_DESC;
}
//3、提供公共的静态的方法给外界获取枚举类中多个对象
public static final Season SPRING = new Season("春天", "春暖花开");
public static final Season SUMMER = new Season("夏天", "夏日炎炎");
public static final Season FALL = new Season("秋天", "秋高气爽");
public static final Season WINTER = new Season("冬天", "白雪皑皑");
//4、提供公共的获取属性的方法
public String getSEASON_NAME() {
return SEASON_NAME;
}
public String getSEASON_DESC() {
return SEASON_DESC;
}
//5、重写toString()方法
@Override
public String toString() {
return "Season{" +
"SEASON_NAME='" + SEASON_NAME + '\'' +
", SEASON_DESC='" + SEASON_DESC + '\'' +
'}';
}
}
2、JDK1.5之前使用自定义枚举改进
查看代码
public class EnumDemo2 {
public static void main(String[] args) {
Season2 spring = Season2.SPRING;
System.out.println(spring);// SPRING
//所有的枚举类都有个父类,叫做Enum
System.out.println(Season2.class.getSuperclass());
System.out.println(spring.getSEASON_NAME()+"---"+spring.getSEASON_DESC());
}
}
enum Season2{
//3、提供公共的静态的方法给外界获取枚举类中多个对象
//将枚举相关的对象放在开头
SPRING("春天", "春暖花开"),
SUMMER("夏天", "夏日炎炎"),
FALL("秋天", "秋高气爽"),
WINTER("冬天", "白雪皑皑");
//2、创建枚举类的属性(成员遍历),必须是作为私有常量出现
private final String SEASON_NAME;
private final String SEASON_DESC;
//1、必须将构造方法私有化,这是为了保证类的对象是有限个的目的
private Season2(String SEASON_NAME,String SEASON_DESC){
this.SEASON_NAME = SEASON_NAME;
this.SEASON_DESC = SEASON_DESC;
}
//4、提供公共的获取属性的方法
public String getSEASON_NAME() {
return SEASON_NAME;
}
public String getSEASON_DESC() {
return SEASON_DESC;
}
//5、重写toString()方法
// @Override
// public String toString() {
// return "Season{" +
// "SEASON_NAME='" + SEASON_NAME + '\'' +
// ", SEASON_DESC='" + SEASON_DESC + '\'' +
// '}';
// }
//这里的枚举已经重写过toString()方法了
}
3、枚举类实现接口
1)、直接在枚举类实现接口中的抽象方法
2)、在每个枚举对象中实现
3)、在枚举中实现方法
查看代码
public class EnumDemo3 {
public static void main(String[] args) {
Season3 spring = Season3.SPRING;
System.out.println(spring);// SPRING
//所有的枚举类都有个父类,叫做Enum
System.out.println(Season3.class.getSuperclass());
System.out.println(spring.getSEASON_NAME()+"---"+spring.getSEASON_DESC());
spring.show();
}
}
interface Person{
void show();
}
enum Season3 implements Person{
//3、提供公共的静态的方法给外界获取枚举类中多个对象
//将枚举相关的对象放在开头
SPRING("春天", "春暖花开"),
SUMMER("夏天", "夏日炎炎"),
FALL("秋天", "秋高气爽"),
WINTER("冬天", "白雪皑皑");
//2、创建枚举类的属性(成员遍历),必须是作为私有常量出现
private final String SEASON_NAME;
private final String SEASON_DESC;
//1、必须将构造方法私有化,这是为了保证类的对象是有限个的目的
private Season3(String SEASON_NAME,String SEASON_DESC){
this.SEASON_NAME = SEASON_NAME;
this.SEASON_DESC = SEASON_DESC;
}
//4、提供公共的获取属性的方法
public String getSEASON_NAME() {
return SEASON_NAME;
}
public String getSEASON_DESC() {
return SEASON_DESC;
}
@Override
public void show() {
System.out.println("好好学习天天向上");
}
}
4)、在枚举对象中实现方法
查看代码
public class EnumDemo4 {
public static void main(String[] args) {
Season4 spring = Season4.SPRING;
System.out.println(spring);// SPRING
//所有的枚举类都有个父类,叫做Enum
System.out.println(Season4.class.getSuperclass());
System.out.println(spring.getSEASON_NAME()+"---"+spring.getSEASON_DESC());
spring.show();
Season4 winter = Season4.WINTER;
winter.show();
}
}
interface Person2{
void show();
}
enum Season4 implements Person2{
//4、提供公共的静态的方法给外界获取枚举类中多个对象
//将枚举相关的对象放在开头
SPRING("春天", "春暖花开"){
@Override
public void show() {
System.out.println("出去春游");
}
},
SUMMER("夏天", "夏日炎炎"){
@Override
public void show() {
System.out.println("夏天吃西瓜");
}
},
FALL("秋天", "秋高气爽"){
@Override
public void show() {
System.out.println("中秋吃月饼");
}
},
WINTER("冬天", "白雪皑皑"){
@Override
public void show() {
System.out.println("冬天打雪仗");
}
};
//2、创建枚举类的属性(成员遍历),必须是作为私有常量出现
private final String SEASON_NAME;
private final String SEASON_DESC;
//1、必须将构造方法私有化,这是为了保证类的对象是有限个的目的
private Season4(String SEASON_NAME,String SEASON_DESC){
this.SEASON_NAME = SEASON_NAME;
this.SEASON_DESC = SEASON_DESC;
}
//4、提供公共的获取属性的方法
public String getSEASON_NAME() {
return SEASON_NAME;
}
public String getSEASON_DESC() {
return SEASON_DESC;
}
}