JavaSE01_Day02(上中)-StringBuilder修改字符串的API使用、正则表达式、String支持正则表达式的相关API、Object类、包装类
package cn.tedu.sb;
/**
* StringBuilder修改字符串API使用案例
* @author cjn
* StringBuilder builder = new StringBuilder();
* 默认无参构造器,内部表示一个空字符串
* StringBuilder builder = new StringBuilder(line);
* 有参构造,内部为将line字符串中的内容复制到builder对象中
*/
public class StringBuilderAPI {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("好好学习Java");
//append(String str):字符串拼接,追加在末尾
sb.append(",就能找到女朋友");
System.out.println(sb);
//好 好 学 习 J a v a , 就 能 找 到 女 朋 友
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
* 修改替换replace(int start,int end,String str):含头不含尾
* 注:在JAVA API中通常使用两个数字表示范围时是"含头不含尾"的。
* 第一个参数:起始索引位置
* 第二个参数:结束索引位置
* 第三个参数:需要进行替换的字符串内容
*/
sb.replace(9, 16, "挣到高薪");//含头不含尾
System.out.println(sb);//好好学习Java,挣到高薪
/*
* 删除delete(int start,int end):含头不含尾
* 删除“好好学习Java,”
*/
sb.delete(0, 9);//含头不含尾
System.out.println(sb);//挣到高薪
/*
* 指定位置插入字符串内容insert(int offset,String str)
* 第一个参数:将指定下标的字符进行向后移动
* 第二个参数:需要进行插入的字符串内容
*/
sb.insert(0, "懒惰是不可能");//插入位置下标原始的内容向右移
System.out.println(sb);
/*
* 字符串反转:reverse()
*/
sb.reverse();//倒序输出
System.out.println(sb);
}
}
测试结果:
好好学习Java,就能找到女朋友
好好学习Java,挣到高薪
挣到高薪
懒惰是不可能挣到高薪
薪高到挣能可不是惰懒
二、正则表达式
2.1 定义:
正则表达式是一串特定的字符,由这些字符共同组成了一个"特殊的字符串",这个"特殊的字符串"是对于文本规则描述的工具,使用正则表达式可以对于文本格式进行严格的约束。
正则表达式是用来描述一个字符串的内容格式,使用它通常用来匹配一个字符串的内容是否符合格式要求。
2.2 正则表达式使用的意义:
在工作过程中经常会需要对字符串进行一些复杂的匹配、查找、替换等相关操作都需要使用正则表达式进行完成。
可以用于关于用户电话、邮箱等相关验证工作。
2.3正则表达式语法(背下来)
[]:表示一个字符,该字符可以是[]中指定的内容
例如:
分组():将括号内的内容看做是一个整体
在描述电话号码时,前面需要有区号,区号的形式可以是0086或者+86,那么此时如果在对一个有区号的电话号进行匹配时,正则表达式的书写需要用到分组(),()这是一个整体,在()中可以使用"|"表示或的关系。
eg: (0086|+86)即可表示的是+86或者是0086
(abc){3} 表示abc整体出现3次. 可以匹配abcabcabc,不能匹配aaa 或abcabc。
(abc|def){3}表示abc或def整体出现3次,可以匹配: abcabcabc 或 defdefdef 或 abcdefabc。
"^"和"$"
在正则表达式的开始可以添加"^",以及在末尾添加"$"表达一个整体,如果不使用,那么正则表达式只匹配某个字符串的部分内容是否符合标准,但是一旦使用了它们,就是要求字符串必须从头到尾都需要满足该匹配规则。
eg:^\w{8,10}$,表示整个字符串只能出现单词字符8~10个
三、String支持正则表达式相关API
1.boolean matches(String regex)
案例:编写验证手机号的正则表达式
package cn.tedu.regex;
/**
* 正则表达式匹配手机号格式案例
* @author cjn
*
*/
public class RegexPhoneDemo {
public static void main(String[] args) {
/*
* 匹配手机号是否满足规范要求
* eg:17090323286
* 要求:手机号是11位,手机号第一位一定是1,第二位不能是012
*/
String strPhone = "17090323286";
/*
* 正则表达式书写:
* 1[3456789][0-9]{9}
* 1[3456789]\d{9}
* 1[3-9]\d{9} 不建议这种可能存在漏洞
* 1[0-9&&[^012]]\d{9}
* 1[\d&&[^012]]\d{9}
*/
String regex = "1[0-9&&[^012]]\\d{9}";//regex就表示正则表达式
boolean b = strPhone.matches(regex);
System.out.println(b);
}
}
案例:编写验证邮箱的正则表达式
package cn.tedu.regex;
/**
* 正则表达式匹配邮箱格式案例
* @author cjn
*
*/
public class RegEmailDemo {
public static void main(String[] args) {
/*
* 邮箱规则:
* eg:2851318853@qq.com 或者2851318853@163.com 或者 baojiaqi0807@gmail.com
* guyoupeng@cn.gree.com
* @符号是必须存在的
* @符号前面至少有1位,前面的字符可以是字母数字和下划线
* @符号后面.前面可以是字母数字
* .后面是字母
*/
String strEmail = "guyoupeng@cn.gree.com";
/*
* 正则表达式:“\.”表示只匹配.
* [a-zA-Z0-9_]{1,}@[a-zA-z0-9]{1,}(\.[a-zA-Z]{1,}){1,}
* \w{1,}@[a-zA-z0-9]{1,}(\.[a-zA-Z]{1,}){1,}
* \w{1,}@[a-zA-z0-9]{1,}(\.[a-zA-Z]+)+
* \w+@[a-zA-z0-9]+(\.[a-zA-Z]+)+
*/
//注意此处需要转义,复制后若没有\,需要手动加一个
String regex = "\\w+@[a-zA-z0-9]+(\\.[a-zA-Z]+)+"
boolean b = strEmail.matches(regex);
if (b) {
System.out.println("是邮箱");
} else {
System.out.println("不是邮箱");
}
}
}
扩展:
假设工作中需要书写一个复杂的正则表达式需要进行匹配验证相关信息内容,往往并不是自己去从头到尾写一个正则表达式,而是通过网上的相关资源查找一个符合当前业务需求的正则表达式进行使用,如果网上没有完全符合业务的正则表达式,可以找一个业务类似的,然后自己稍作修改进行使用。
常用正则表达式查询网址:开源中国 https://tool.oschina.net/regex/#
2.String[] split(String regex)
该方法需要传递一个正则表达式,然后使用该正则表达式所描述的字符串规则进行匹配对应的字符串内容,如果匹配到符合要求的字符串就将字符串进行拆分。返回的是一个字符串数组对象,数组中的元素就是剩下没有被匹配到的部分。
package cn.tedu.regex;
import java.util.Arrays;
/**
* String字符串类提供的支持正则的拆分方法案例演示
* split(String regex)方法
* @author cjn
*
*/
public class SplitDemo {
public static void main(String[] args) {
String str = "qwer1234asdf567xyz9";
/*
* 准备正则表达式,需求是希望按照数字进行拆分,
* 拆分以后就会只保留字母部分,将拆分的元素保存到字符串数组中
* [0-9]{1,}
* [0-9]+
* \d{1,}
* \d+
*/
String regex = "\\d+";
String[] strArray = str.split(regex);
System.out.println(Arrays.toString(strArray));
System.out.println("拆分出"+strArray.length+"项");
//如果字符串最开始就是拆分项,则会先拆分出一个空字符串
str = "123qwer1234asdf567xyz9";
strArray = str.split(regex);
System.out.println(Arrays.toString(strArray));
System.out.println("拆分出"+strArray.length+"项");
//如果字符串最开始就是拆分项,则会先拆分出一个空字符串
str = ".abc.def.ghi.jkl";
strArray = str.split("\\.");
System.out.println(Arrays.toString(strArray));
//当连续遇到两个拆分项时,中间会拆分出一个空字符串
str = "abc..def.ghi.jkl";
strArray = str.split("\\.");
System.out.println(Arrays.toString(strArray));
//如果是在字符串末尾连续出现拆分项,则所有拆分的空字符串都舍弃
str = "abc.def.ghi.jkl............................";
strArray = str.split("\\.");
System.out.println(Arrays.toString(strArray));
}
}
测试结果:
[qwer, asdf, xyz]
拆分出3项
[, qwer, asdf, xyz]
拆分出4项
[, abc, def, ghi, jkl]
[abc, , def, ghi, jkl]
[abc, def, ghi, jkl]
3.String replaceAll(String regex,String replacement)
package cn.tedu.regex;
/**
* replaceAll(String regex,String replacement)
* 将当前字符串中满足正则表达式的部分内容替换为指定的字符串内容
* @author cjn
*
*/
public class ReplaceAllDemo {
public static void main(String[] args) {
String str = " Hel lo Wo r ld ";
//str = str.replaceAll(" ", "");
str = str.replaceAll("\\s", "");
System.out.println("|"+str+"|");
String str1 = "Java教研部的123是苍老师";
//将字符串中的数字部分替换成"老大",注意替换汉字时要查找对应的Unicode编码才可以,一般都是替换数字或字母
str1 = str1.replaceAll("[0-9]+", "老大");
System.out.println(str1);
System.out.println("-----------匹配指定的骂人信息,替换成***------------");
//上面的----或****有时候两侧或者前后的展现形式不一样,这是工具的问题,但这不影响程序的编写和运行
String str2 = "nmb是,qnmd。";
String regex = "(nmb|qnmd)";//()表示组合,|表示或者
str2 = str2.replaceAll(regex, "***");
System.out.println(str2);
}
}
测试结果:
|HelloWorld|
Java教研部的老大是苍老师
-----------匹配指定的骂人信息,替换成***------------
***是,***。
四、Object类
4.1 定义:
Object类是Java所有类的顶级父类,如果是自定义的一个类,在定义的时候并没有显式的使用extends Object,那么会默认自动继承Object类(隐式使用)。
4.2 存在的意义:
因为所有的Java类都会有共有的属性及其方法,那么通过”泛化“抽取设计超类,所以在Object类中提供了一些基本的结构内容。
4.3 自定义类需要重写的常用方法:
-
toString()方法
-
euqals()方法
4.4 toString()方法
由于Object类是所有类的顶级父类,那么在Object类中定义的方法是所有类中都具备的,那么toString方法就是其中之一。之前在学习String字符串类时是可以调用toString()方法,但是调用的toString()方法并不是Object中的toString()方法,而是String类重写的toString()方法。重写的原因是希望在打印字符串对象信息的时候,是一个字符串内容,如果不重写的情况下,会调用Object类中提供的toString()方法,顶级超类中的toString()方法打印的信息格式为:类的全限定名@hashCode。
如果以后在自定义类的情况下,建议都去重写toString(),哪怕以后不用打印对象信息,但是测试时的查看信息还是可以用到的。
4.5 equals()方法
根据Object中的源码查看,可以看到equals()方法的内容如下:
public boolean equals(Object obj) {
return (this == obj);
}
该方法返回的是一个boolean值,表示判断比较两个对象的内容地址空间是否是相同的,也就是在比较两个对象的首地址值是否相等。由此可以联想到这个equals()方法和“==”的作用是一致的,那当需要去比较两个对象的内容是否一致的情况下,就需要进行重写equals()方法。
4.6 常见面试题equals和==的区别
“==”主要用于比较两个引用所指向的内存对象是否是同一个对象,也就意味着是在比较两个引用变量的首地址的值是否一致,如果一致则表示两个引用变量指向的是同一个对象,反之则是不同的对象。
equals()主要用于比较两个对象中的内容是否一致,也就意味着如果两个引用变量如果指向内容中对象里面的属性值相等时就返回true结果,反之则返回false。由于在Object底层源码中可以得知,仍然是按照地址的方式进行对比,所以无法满足当前要求,那么就需要去重写Object类中的equals()方法。
eg:两个双胞胎,这两个双胞胎都是独立的个体,是两个对象。如果使用进行比较,比较的结果为false。但是他们“长得一样”,使用equals比较的时候,比较结果为true。所以可以进行总结得出,如果使用“==”就是判断是否为同一个,使用equals是判断像不像。
public class Demo {
public static void main(String[] args) {
Point p = new Point(1,2);
/*
Object定义的方法:
String toString()
用于将当前对象转换为一个字符串。很少会主动调用这个方法,多用于
输出对象内容使用。子类不重写时,默认返回的字符串内容是当前对象
的地址信息,实际开发中作用不大。
*/
String str = p.toString();//几乎不会主动调用这个方法
System.out.println(str);
//以下情况对象的toString会被调用:
//1:输出一个对象到控制台时
System.out.println(p);//方法内部会调用p.toString将返回的字符串输出到控制台
/*
2:任何对象和字符串链接结果都是字符串(过程中会将其他对象调
用toString转换为String后链接)
*/
String line = "hello!!!" + p;
System.out.println(line);
/*
Object定义的方法:
boolean equals(Object o)
比较当前对象和参数对象o内容是否相同,相同则返回true否则为false
Object中该方法的实现内部用"=="比较,因此子类不重写该方法则没有
实际意义。
*/
Point p2 = new Point(1,2);
System.out.println("p2:"+p2);
System.out.println(p==p2);//false
System.out.println(p.equals(p2));//true(重写后的equals方法)
}
}
Person类
package cn.tedu.object;
public class Person {
private String name;//姓名
private int age;//年龄
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}