1.Pattern类和 Matcher类
1.Pattern范例
1.1简介:
因为正则表达式只能做一些简朴的校验工作,像要做进一步复杂的工作,须要使用Pattern类和 Matcher类。
字符串在真正的校验过程中,实际上底层维护了一个pattern对象,使用对象的干系方法进行校验;
pattern类的构造器私有化了,因此我们不能通过构造器创建对象,但是可以利用工厂方法来创建对象: static compile(String regex):
通过一个案例来明白创建pattern对象校验字符串的过程:
- public static void main(String[] args) {
- String regex = "[a-zA-Z][_$a-zA-Z0-9]{7,9}";
- //获取一个Pattern对象
- Pattern p1 = Pattern.compile(regex);
- //和普通字符串进行校验,会得到一个Mathcer对象,该对象封装的时匹配的结果,并提供各种操作
- Matcher matcher = p1.matcher("micheal12_");
- //想要得到是否匹配成功,需要调用Matcher里的matches(). 该方法的作用是从头到尾严格匹配
- //匹配成功返回true,匹配失败返回false
- boolean match = matcher.matches();
- System.out.println("是否匹配成功"+match);
- }
复制代码 我们起首界说了一个正则表达式,要求第一位是字母,第二位是字母数字或下划线$,剩余的长度应该是7-9位。之后调用工厂方法把正则表达式传入,创建对象p1,然后创建一个matcher对象使用p1去匹配想要比力的字符串。效果封装在matcher对象中,想要获取效果,须要调用matcher对象的matches()方法,并打印出效果。
2.pattern对象的其他方法
String pattern();
作用: 返回pattern的正则表达式,即特殊的字符串
- public static void main(String[] args) {
- String regex = "\\d+";
- String str = "aaa111bbb222ccc";
- //获取一个Pattern对象
- Pattern p1 = Pattern.compile(regex);
- /**
- * String pattern():
- * 作用:返回Pattern的正则表达式,即特殊的字符串
- */
- String str2 = p1.pattern();
- System.out.println(str2);
复制代码 我们先界说了一个正则表达式,要求至少传入一位的数字或字母或下划线,然后创建p1对象,之后新界说了一个字符串并通过p1调用pattern()方法,来获取传入的那个正则表达式;
String[ ] split(String str)
作用:对字符串进行切分,符合正则表达式的字符串会被切除并作为隔板,来分割字符串,返回一个数组
- String[] split = p1.split(str);
- System.out.println(Arrays.toString(split));
复制代码
2.Matcher范例
该类的构造器也私有化了,不能直接通过构造器来创建对象,须要通过pattern对象的matcher()方法来创建对象,该方法的形参是须要比力的字符串,创建出的对象储存的是匹配的效果。该类提供了多种方法,并且可以对效果进行多种操作。
matches() lookingAt() find() start() end() group() groupCount() reset() 等
matchers()方法:
该方法在上述的代码中已经演示一遍了,在使用的时候须要使用matcher对象来调用,返回值是布尔范例,返回的效果就是匹配的效果,匹配成功返回true,匹配失败返回false
lookingAt() 方法:
该方法用于匹配一个平常的字符串前面是否符合正则表达式规定的形式,须要注意:内部有一个类似指针的操作,匹配成功后指针会指向子串,在匹配前指针位于字符串的前面;
- String regex = "\\d+";
- // String info = "1234abcd";
- String info ="abc123";
- Pattern pattern = Pattern.compile(regex);//获取模式对象
- Matcher matcher = pattern.matcher(info);//获取匹配结果对象
- boolean result = matcher.lookingAt();
- System.out.println(result);
复制代码 创建matcher对象的过程就不过多赘述了,该方法的返回值是一个bollean范例,须要使用matcher对象来调用,匹配成功就返回true,匹配失败就返回false
传入的字符串开头不是以数字开头的,以是会返回false;
find( )方法:
该方法用于匹配字符串中是否有符合正则表达式的子串,匹配操作会一直执行到字符串的末了一个位置,假如有,返回true,该方法的返回值也是boolean范例,须要注意的是:该方法中也有一个指针操作;假如匹配到子串,指针就会向后移动,寻找下一个子串,在匹配操作开始前,指针也位于字符串的前面
- regex = "\\d+";
- info ="abc123eee444ff555ggg";
- pattern = Pattern.compile(regex);
- matcher = pattern.matcher(info);
- //循环的次数表示了find()找到的符合正则表达式要求的子串的个数
- while(matcher.find()){
- System.out.println("--匹配成功--");
- }
复制代码 该方法寻找的子串须要满足是至少一位数字,会找到133,444,555三组,以是用while循环,会返回三次匹配成功fin
group() groupCount() reset() start() end() 这几个方法必须要基于匹配操作成功之后的操作
group()方法:
该方法的返回值范例是String范例,用于返回指针指向的符合正则表达式的那部门子串
- Pattern pattern = Pattern.compile("\\d+");
- Matcher matcher = pattern.matcher("abc123def456xxx");
- while(matcher.find()){
- System.out.println(matcher.group());
- }
复制代码 在上述代码中,我们使用while循环寻找符合正则表达式的子串,并在找到之后直接调用group方法打印出来,会找到123,456
须要注意的是,在寻找子串的操作结束后,指针会处于找到的末了一个子串的尾部,此时我们假如想再次寻找符合条件的子串,指针会继承向后移动,导致查找失败,以是我们须要重置指针,再重新查找
- matcher.reset();
- while(matcher.find()){
- System.out.println(matcher.group());
- }
复制代码
start() end() 方法
这两个方法的返回值是int范例;start用于返回符合正则表达式子串的开始索引,end用于返回符合正则表达式子串的结束索引+1(索引的初始位置是0)
- public static void main(String[] args) {
- Pattern pattern = Pattern.compile("\\d+");
- Matcher matcher = pattern.matcher("abc123def456xxx");
- int count = 1;
- while (matcher.find()) {
- int start = matcher.start();
- int end = matcher.end();
- System.out.println("第" +count +"部分的开始和结束位置 "+start+"," + end);
- count++;
- }
- }
复制代码 我们在这个演示中界说了一个count用于记录检索出符合正则表达式子串的次数,该方法也是使用对象来调用;
lookingAt() 和 find() 在一起使用时,大概会影响指针的操作
- public static void main(String[] args) { Pattern pattern = Pattern.compile("\\d+"); Matcher matcher = pattern.matcher("123aaa444bbb555"); System.out.println("字符串是否以数字开头"+matcher.lookingAt()); /** * 因为在使用lookingAt时指针向后移动了一次 * 以是在使用find()方法时,指针就不是从字符串前就开始移动的,而是紧随着lookingAt()方法的位置移动 * 注意指针重置的问题 */// matcher.reset();
- while(matcher.find()){
- System.out.println(matcher.group());
- } }
复制代码 在上述代码中,我们先使用lookingAt方法判定字符串是否以数字开头,在判定的过程中,指针已经移动到第一个以数字开头的子串后,以是这时候我们调用find()方法去检索每一个符合正则表达式的子串时,会导致找不到第一个子串,返回的效果只有第二个和第三个子串,
为相识决这个问题,我们必须让指针复位,使用reset方法
groupCount()方法
该方法的返回值是int范例,用于返回正则表达式中小括号的个数
- public static void main(String[] args) {
- Pattern pattern = Pattern.compile("(ca)(t)");
- Matcher matcher = pattern.matcher("one cat, two cats in a yard");
- /**
- * int groupCount()
- * 作用:用于获取正则表达式中小括号的个数。()用于分组
- */
- System.out.println(matcher.groupCount());
- while(matcher.find()){
- //打印符合正则表达式的子串,因此循环次数是两次
- System.out.println(matcher.group());
- }
- System.out.println("=======================");
- matcher.reset();
- matcher.find();
- //使用小括号的个数来循环,可以使用group()重载方法,String group(int group)
- //注意,想要使用小括号的个数进行遍历,需要将指针移动到字符串之前,然后还需要find()方法,使指针归位
- //group(0): 表示的是对组进行拆分括号整体的样子
- //group(1):表示第一个括号
- //group(2):表示第二个括号
- for (int i = 0; i <= matcher.groupCount(); i++) {
- System.out.println(matcher.group(i));
- }
- }
复制代码 在上述代码中,我们传入的正则表达式是(ca)(t),在我们直接使用find方法通过循环可以得到两个cat,我们也可以通过小括号的个数来进行循环,须要注意,我们须要把指针复位,我们可以分别通过遍历分别得到满足两个括号的子串,满足第一个括号的子串,满足第二个括号的子串
以是满足两个括号的子串样式就是cat,满足第一个括号的样式就是ca,满足第二个括号的样式是t打印效果如下:
2.包装类
1.包装类的学习
因为Java是面向对象编程的语言,而基本数据范例没有面向对象的特征,以是Java专门为这些基本数据范例筹划了具有面向对象特征的类,实际上就是对这些数据范例做了类的封装,即里面有一个基本数据范例的成员变量和成员方法,常量等
除了int 和 char以外的其余六个基本数据范例的包装类名都是基本数据范例的首字母大写的形式
int---Integer char---Character
装箱和拆箱操作:
装箱:调用包装类的valueOf方法获取一个包装类对象的过程称之为装箱
拆箱:调用包装类里的XXXValue方法,返回一个基本数据范例的过程称之为拆箱
我们通过一个案例来更好的明白装箱和拆箱:
- public static void main(String[] args) {
- //装箱操作,对1进行封装,获取一个包装类对象,思考:num存储的是什么?
- //存储的是对象的地址 int a = 1; a存储的是值
- Integer num = new Integer(1);
- //num和num2是不是同一个对象? 两个对象
- Integer num2 = Integer.valueOf(1);//利用valueOf()的方式进行装箱,类名调用
- System.out.println(num==num2); //是两个不同的对象,只不过对象的成员变量的值一样
- System.out.println(num.equals(num2)); //true,值是相等的
- //拆箱 包装类对象调用方法xxxValue();
- int i = num.intValue();//调用对象的intValue()方法来进行拆箱操作
- //形参是包装类,因此可以赋值为null,编译器不会报错
- // Integer result = calculate(null,num2);
- Integer result = calculate(num,num2);
- System.out.println(result);
- //
- }
- //定义一个方法,形参是包装类型
- public static Integer calculate(Integer num, Integer num2) {
- return num+num2;
- }
复制代码 起首我们调用构造器创建了一个Integer范例的对象num,然后使用Integer.valueOf的方式来创建一个Integer对象num2;并判定它们两个是不是一个对象,由于都是相当于new出来的,以是说肯定返回false,之后判定他们的值是否相同,值都是1,返回true。当使用拆箱时,须要使用包装类对象来调用intValue()方法,我们在后面界说了一个返回值范例是Integer方法calculate,返回值是两个形参的和,在main方法中直接调用该方法,传入两个参数num,num2并设置返回值,打印效果,可以得到两个包装类对象的和,说明包装类也可以作为返回值范例。
2.包装类的自动拆箱和装箱
从jdk1.5开始,引入了包装类的自动拆箱和装箱;
自动装箱:将基本数据范例的字面量(直接表达式的数)或变量直接赋值给包装类的变量;本质上编译器在编译期间自动调用了valueOf方法;进行包装
自动拆箱:将包装类的变量的地址直接赋值给基本数据范例的变量,本质上编译器在编译期间调用了XXXValue方法,进行拆箱
- public static void main(String[] args) {
- Integer num = 1; //发生了自动装箱的操作,底层调用了Integer.valueOf()进行包装
- int a = 10;
- Integer num2 = a;//也是自动装箱
- //自动拆箱
- int x = num; //底层隐含了num.intValue();
- int y = new Integer(100);
- }
复制代码 我们直接声明一个包装类的对象并初始化为int范例的1,编译器自动调用了valueOf方法装箱;也可以直接声明一个int范例的变量a,将其直接赋值给包装类的对象
对于自动拆箱操作,我们直接声明一个变量 x,并将包装类对象num的地址赋值给该变量,实现了自动拆箱,还可以直接调用包装类的构造器并传入参数100来赋值
3.包装类的常量池
自动装箱大概手动装箱的对象都会有常量池;Byte,Short,Integer,Long四种范例的常量池的范围[-128,127] ; Character的常量池范围是[0,127] ; Boolean的常量池就只有两个值 true和false ; 浮点数范例没有常量池
- public static void main(String[] args) {
- //检验常量池
- Integer n1 = 10;
- Integer n2 = 10;
- int a = 10;
- System.out.println(n1 == n2);//true
- Integer n3 = Integer.valueOf(a);
- System.out.println(n3 == n2);//true
- Integer n4 = new Integer(10);
- System.out.println(n4 == n2);//false,new出来的对象都是在堆里的
- //范围
- Integer n5 = 128;
- Integer n6 = 128;
- System.out.println(n5 == n6);//false 128超过范围了,应该是在堆中创建的
- Boolean b1 = true;
- Boolean b2 = true;
- //调用常量也是常量池
- // Boolean b2 = Boolean.TRUE;
- System.out.println(b1 == b2);//true 在常量池中,不创建新的对象
- Character c1 = 'a';
- Character c2 = 'a';
- System.out.println(c1 == c2);//true
- }
复制代码 在上述的代码中,我们查验了包装类的常量池;起首界说了n1和n2,并都赋值为10;在包装类常量池中查验他们是不是一个对象;之后又通过装箱的操作界说了n3,查验他们是不是同样的对象,查验效果是true,然后我们通过new关键字创建了一个和n2值一样的对象n4,经过查验发现他们不是同一个对象;
然后查验常量池的范围,Integer的范围是[-128,127],我们界说的值是128,超出了字符串常量池,对象就变为在堆中创建;之后我们测验了Boolean范例的对象,假如值相同则也是一个对象;
对于Character范例也是一样的,只要不超过范围,就不会产生新的对象,这样有利于掩护内存,节约空间;
4.包装类的其他方法大概常量
- System.out.println(Short.MAX_VALUE);//32767
- System.out.println(Short.MIN_VALUE);//-32728
- //找出两个数中的较大值
- System.out.println(Integer.max(10,20));//20
- System.out.println(Integer.min(10,20));//10
复制代码 我们可以通过类名调用他们内部的常量,好比最大值最小值;也可以通过类名调用内部已经界说好的成员方法,好比找出最大值,最小值;
static int parseInt( String str )
该方法是一个静态方法,将字符串范例的值转为int范例的值,须要使用Integer类名来调用,方法声明了一个运行时非常;数字格式非常,当传入的数字字符串中含有不属于数字的形式,就会报非常
- String str = "10";
- // String str = "10a"; 这样使用就会出现运行时异常NumberFormatException
- int n1= Integer.parseInt(str);
- System.out.println(n1);//10
复制代码
- int n2 = 10;
- System.out.println(Integer.toHexString(n2));//16进制
- System.out.println(Integer.toBinaryString(n2));//2进制
- System.out.println(Integer.toOctalString(n2));//8进制
复制代码 还可以通过包装类名调用一些方法,使int范例的数据转换为16进制,2进制,8进制等;
3. BigDecimal范例
当我们在进行盘算时,尤其是要准确到浮点数15,16位的时候,建议使用BigDecimal范例;
常用的构造器:
new BigDecimal(int i);
new BigDecimal(double i); //不建议使用,因为double范例在传入的时候就大概已经发生精度缺失
new BigDecimal(long i);
new BigDecimal(String i); //假如想使用浮点数,建议使用String范例
加减乘除运算:须要注意:在除法的过程中,除不尽会报非常的,除数不能为0,对象也不能为null
-add -substract -multiply -divide
我们通过一个案例来演示;
- BigDecimal bd1 = new BigDecimal("3");
- BigDecimal bd2 = new BigDecimal("1.5");
- BigDecimal r1 = bd1.add(bd2);
- BigDecimal r2 = bd1.subtract(bd2);
- BigDecimal r3 = bd1.multiply(bd2);
- BigDecimal r4 = bd1.divide(bd2);
- System.out.println("r1 = " + r1+"r2 = " + r2+"r3 = " + r3+"r4 = "+r4 );
复制代码
在做除法运算时,除不尽就会发生非常,以是一般使用try-catch 来处理,以免影响其他程序的运行
- public static void main(String[] args) {
- BigDecimal bg1 = new BigDecimal("3");
- BigDecimal bg2 = new BigDecimal("2.9");
- //减法
- System.out.println(bg1.subtract(bg2));
- //除法
- try{
- System.out.println(bg1.divide(bg2));
- }catch (ArithmeticException e){
- e.printStackTrace();
- }
- System.out.println(bg1.subtract(bg2));
- }
复制代码 我们在使用减法是可以正常运行的,在做除法时,使用try-catch,以免影响打印下一次减法的效果
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |