String类和正则表达式
今天的主要内容
-
Scanner类概述
- Scanner获取数据出现的小问题及解决方案
-
String类概述
String类的构造方法
String面试题之"=="和equals的区别
Sring类的判断功能
String类的获取功能
字符串的遍历
统计不同类型字符个数
String类的转换功能
把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
字符串反转
在大串中查找小串出现的次数思路
正则表达式
一、Scanner的概述和方法介绍(掌握)
A:Scanner的概述
-
B:Scanner的构造方法原理
- Scanner(InputStream source)
- System类下有一个静态的字段:
- public static final InputStream in; 标准的输入流,对应着键盘录入。
-
C:一般方法
- hasNextXxx() 判断是否还有下一个输入项,其中Xxx可以是Int,Double等。如果需要判断是否包含下一个字符串,则可以省略Xxx
- nextXxx() 获取下一个输入项。Xxx的含义和上个方法中的Xxx相同,默认情况下,Scanner使用空格,回车等作为分隔符
二、常见对象(Scanner获取数据出现的小问题及解决方案)(掌握)
-
A:两个常用的方法:
public int nextInt():获取一个int类型的值
public String nextLine():获取一个String类型的值
-
B:案例演示
-
b:再演示先获取int值,然后获取String值出现问题
- 当nextInt()与nextLine()一起使用时,可能会出现问题
nextInt()方法是键盘录入整数的方法,当我们录入10的时,其实是在键盘录入了10和\r\n,nextInt()方法只获取10就结束了
nextLine()是键盘录入字符串的方法,遇到\r\n时证明一行结束
因此此时产生冲突
- 当nextInt()与nextLine()一起使用时,可能会出现问题
-
c:问题解决方案
第一种:先获取一个数值后,在创建一个新的键盘录入对象获取字符串。
第二种:把所有的数据都先按照字符串获取,然后要什么,你就对应的转换为什么。(后面讲)
-
三、常见对象(String类的概述)(掌握)
-
A:String类的概述
通过JDK提供的API,查看String类的说明
-
可以看到这样的两句话。
a:字符串字面值"abc"也可以看成是一个字符串对象。
b:字符串是常量,一旦被赋值,就不能被改变。
四、常见对象(String类的构造方法)(掌握)
-
A:常见构造方法
public String():空构造
public String(byte[] bytes):把字节数组转成字符串
public String(byte[] bytes,int index,int length):把字节数组的一部分转成字符串
public String(char[] value):把字符数组转成字符串
public String(char[] value,int index,int count):把字符数组的一部分转成字符串
public String(String original):把字符串常量值转成字符串
-
B:案例演示
- 演示String类的常见构造方法
五、常见对象(String类的常见面试题)(掌握)
-
==可以比较基本数据类型和引用数据类型
- 当比较基本数据类行时,比较的是值
- 当比较引用时,比较的是地址
- String属于引用类型
String重写了equals方法,因此比较的是值
-
1.判断定义为String类型的s1和s2是否相等*****
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); //true
System.out.println(s1.equals(s2)); //true
-
2.下面这句话在内存中创建了几个对象?*****
String s1 = new String("abc"); //两个对象
创建两个对象,一个在常量池中,一个在堆中
-
3.判断定义为String类型的s1和s2是否相等
String s1 = new String("abc");
String s2 = "abc";
-
System.out.println(s1 == s2); //false
- s1指向的是堆中的字符串
- s2指向的是常量池中的字符串
System.out.println(s1.equals(s2)); //true
-
4.判断定义为String类型的s1和s2是否相等
String s1 = "a" + "b" + "c";
String s2 = "abc";
-
System.out.println(s1 == s2); //true
- 在编译时,java中有常量优化机制
System.out.println(s1.equals(s2)); //true
-
5.判断定义为String类型的s1和s2是否相等
String s1 = "ab";
String s2 = "abc";
String s3 = s1 + "c";
System.out.println(s3 == s2); //false
System.out.println(s3.equals(s2)); //true
六、常见对象(String类的判断功能)(掌握)
-
A:String类的判断功能
boolean equals(Object obj):比较字符串的内容是否相同,区分大小写
boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写
boolean contains(String str):判断大字符串中是否包含小字符串
boolean startsWith(String str):判断字符串是否以某个指定的字符串开头
boolean endsWith(String str):判断字符串是否以某个指定的字符串结尾
boolean isEmpty():判断字符串是否为空。
若字符串常量和字符串变量进行比较,通常都是字符串常量调用方法,防止空指针异常
七、常见对象(String类的获取功能)(掌握)
-
A:String类的获取功能
int length():获取字符串的长度。
char charAt(int index):获取指定索引位置的字符
int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引。
int indexOf(String str):返回指定字符串在此字符串中第一次出现处的索引。
int indexOf(int ch,int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现处的索引。
int indexOf(String str,int fromIndex):返回指定字符串在此字符串中从指定位置后第一次出现处的索引。
lastIndexOf
-
String substring(int start):从指定位置开始截取字符串,默认到末尾。
- subString方法会返回新的字符串,不会改变源字符串,一定要注意
String substring(int start,int end):从指定位置开始到指定位置结束截取字符串。
八、常见对象(字符串的遍历)(掌握)
- A:案例演示
- 需求:遍历字符串
- 分析:
- 循坏获取每一个字符
- 用到charAt(int index)方法
九、常见对象(统计不同类型字符个数)(掌握)
-
A:案例演示
需求:统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数,其他字符出现的次数。
ABCDEabcd123456!@#$%^
-
分析:
-
for循坏遍历字符串中的每一个字符,charAt()方法
-
for循坏中对每一个字符进行判断
大写字母:ch >= 'A' && ch <= 'Z'
小写字母:ch >= 'a' && ch <= 'z'
数字字符:ch >= '0' && ch <= '9'
其他字符
-
其中需要定义常量,统计个数
-
-
程序:
public static void main(String[] args) { //定义常量 int upperCount = 0; int lowerCount = 0; int numCount = 0; int elseCount = 0; //定义字符串 String string = "ABCDEabcd123456!@#$%^"; //1. for循坏遍历字符串中的每一个字符,charAt()方法 for(int i = 0;i < string.length();i++) { char ch = string.charAt(i); //2. for循坏中对每一个字符进行判断 if(ch >= 'A' && ch <= 'Z') upperCount++; else if(ch >= 'a' && ch <= 'z') lowerCount++; else if(ch >= '0' && ch <= '9') numCount++; else elseCount++; } System.out.println("大写字母个数:" + upperCount + "\n小写字母个数:" + lowerCount + "\n数字字符个数:" + numCount + "\n其他字符个数:" + elseCount); }
十、常见对象(String类的转换功能)(掌握)
-
A:String的转换功能:
byte[] getBytes():把字符串转换为字节数组。
char[] toCharArray():把字符串转换为字符数组。
static String valueOf(char[] chs):把字符数组转成字符串。
-
static String valueOf(int i):把int类型的数据转成字符串。
- 注意:String类的valueOf方法可以把任意类型的数据转成字符串
* String toLowerCase():把字符串转成小写。(了解)
* String toUpperCase():把字符串转成大写。
* String concat(String str):把字符串拼接。
十一、常见对象(按要求转换字符)(链式编程掌握)
-
A:案例演示
需求:把一个字符串的首字母转成大写,其余为小写。(只考虑英文大小写字母字符)
-
程序:
public static void main(String[] args) { String string = "hahaWOhaoxiangJIA"; String string2 = string.substring(0,1).toUpperCase().concat(string.substring(1).toLowerCase()); System.out.println(string2); //Hahawohaoxiangjia }
链式编程:每一次调用方法后返回的是一个对象,可以继续调用其他方法
十二、常见对象(把数组转成字符串)
-
A:案例演示
-
需求:把数组中的数据按照指定的格式拼接成一个字符串
-
举例:
- int[] arr = {1,2,3};
-
输出结果:
- "[1, 2, 3]"
分析:其实是字符串的一个拼接工作
-
程序:
public static void main(String[] args) { int[] arr = {1,2,3}; String string = "["; for(int i = 0;i < arr.length;i++) { int ch = arr[i]; if(i == arr.length-1) { string = string.concat(ch + "]"); }else string = string.concat(ch + ", "); } System.out.println(string); }
-
-
十三、常见对象(String类的其他功能)
-
A:String的替换功能及案例演示
String replace(char old,char new)
String replace(String old,String new)
-
B:String的去除字符串两空格及案例演示
- String trim()
-
C:String的按字典顺序比较两个字符串及案例演示
int compareTo(String str)(暂时不用掌握)
int compareToIgnoreCase(String str)(了解)
十四、常见对象(字符串反转)
-
A:案例演示
-
需求:把字符串反转
举例:键盘录入"abc"
输出结果:"cba"
-
分析:
键盘录入字符串
转换为字符数组
-
将数组反转
- 联系快速排序
将数组转为字符串(new String(byte[] b))
-
程序:
public static void main(String[] args) { //1. 键盘录入字符串 Scanner input = new Scanner(System.in); System.out.println("请输入一个字符串:"); String string = input.nextLine(); //2. 转换为字符数组 char[] cArr = string.toCharArray(); //3. 将数组反转 int i; int j; for(i = 0,j = cArr.length - 1;i < j;i++,j--) { //交换cArr[i]和cArr[j] char temp = cArr[i]; cArr[i] = cArr[j]; cArr[j] = temp; } //4. 将数组转为字符串(new String(byte[] b)) System.out.println("反转后字符串为:"); System.out.println(new String(cArr)); }
-
十五、常见对象(在大串中查找小串出现的次数思路图解)
-
A:画图演示
需求:统计大串中小串出现的次数
这里的大串和小串可以自己根据情况给出
-
程序:
//定义大串 String max = "hahahahawoxianghuijiaxixixixiwoxianghuijiawojia"; //定义小串 String min = "woxianghuijia"; //定义计数器变量 int count = 0; //定义索引 int index = 0; //定义循坏 while((index = max.indexOf(min)) != -1){ count++; max = max.subString(index + min.length()); } System.out.println(count);
正则表达式
一、正则表达式概述
-
A:正则表达式
是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。其实就是一种规则。有自己特殊的应用。
作用:比如注册邮箱,邮箱有用户名和密码,一般会对其限制长度,这个限制长度的事情就是正则表达式做的
-
B:案例演示
-
需求:校验qq号码.
- 1:要求必须是5-15位数字
- 2:0不能开头
- 3:必须都是数字
-
a:非正则表达式实现
public static void main(String[] args) { System.out.println(checkQQ("123456")); } public static boolean checkQQ(String qq) { boolean flag = true; //若校验不合格则置为false if(qq.length() >= 5 && qq.length() <= 15) { if(!qq.startsWith("0")) { char[] cArr = qq.toCharArray(); for (int i = 0; i < cArr.length; i++) { char ch = cArr[i]; if(!(ch >= '0' && ch <= '9')) { flag = false; break; } } }else { //以0开头 flag = false; } }else { //不是5-15位数字 flag = false; } return flag; }
-
b:正则表达式实现
String regex = "[1-9]\\d{4,14}"; System.out.println("123256".matches(regex));
-
二、常见对象(字符类演示)
- A:字符类
[ ] 代表单个字符
[abc] a、b 或 c(简单类)
-
[^abc] 任何字符,除了 a、b 或 c(否定)
- ^表否定
[a-zA-Z] a到 z 或 A到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a到d或者m到p
-
[a-z&&[def]] &&交集,因此此时指的是:d或e或f
- 等价于[def]
[a-z&&[^bc]] a到z之间而且不是b和c
[a-z&&[^m-p]] a到z之间而且不是m到p
[0-9] 0到9的字符都包括
三、常见对象(预定义字符类演示)
-
A:预定义字符类
. 任何单个字符。
-
\d 三个数字字符:[0-9]
- \d转义字符
\D [^0-9] 除0-9的单个字符
\w 单词字符:[a-zA-Z_0-9]
\s 空白字符: [ \t\n\x0B\f\r]
\S 非空白字符: [^\s]
\w 一个单词字符: [a-zA-Z_0-9]
\W 非单词字符: [^\w]
四、常见对象(数量词)
-
A:Greedy 数量词
-
X? X,一次或一次也没有
[abc]?
a或者b或者c出现一次或者一次也没有
-
X* X,零次或多次
[abc]*
a或者b或者c出现0次或者多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
-
五、常见对象(正则表达式的分割功能)
-
A:正则表达式的分割功能
String类的功能:public String[] split(String regex)
当以'.'切割时,正则表达为:regex = "\.",需要两个\
-
B:案例演示
- 正则表达式的分割功能
六、常见对象(把给定字符串中的数字排序)
-
A:案例演示
需求:我有如下一个字符串:”91 27 46 38 50”,请写代码实现最终输出结果是:”27 38 46 50 91”
-
分析:
- 按照空格分割
- 调用排序函数
- 遍历数组输出结果
-
程序
public static void main(String[] args) { //1. 按照空格分割 String string = "91 27 46 38 50"; String[] sArr = string.split(" "); //2. 调用排序函数 Arrays.sort(sArr); //3. 遍历数组输出结果 for(String string2 : sArr) { System.out.print(string2 + " "); } }
七、常见对象(正则表达式的替换功能)
-
A:正则表达式的替换功能
- String类的功能:public String replaceAll(String
regex,String replacement)
- String类的功能:public String replaceAll(String
-
B:案例演示
- 正则表达式的替换功能
C:代码实现
public static void main(String[] args) {
String string = "hahaha23hahah19";
String regex = "[0-9]"; //此时使用\\d也可以
System.out.println(string.replaceAll(regex, "")); //输出hahahahahah
}
八、常见对象(正则表达式的分组功能)
-
A:正则表达式的分组功能
- 捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 ((A)(B(C))) 2 (A 3 (B(C)) 4 (C) 组零始终代表整个表达式。
-
B:案例演示
-
a:切割
- 需求:请按照叠词切割: "sdqqfgkkkhjppppkl";
-
b:替换
需求:我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程
将字符串还原成:“我要学编程”。
-
-
C:知识储备
-
判断是否为叠词
String regex = "(.)\\1(.)\\2"; //此时\\1代表第一组出现一次,\\2代表第二组出现一次 System.out.println("开开心心".matches(regex)); //true System.out.println("aabb".matches(regex)); //true System.out.println("abb".matches(regex)); //false
需求:请按照叠词切割: "sdqqfgkkkhjppppkl";
-
程序:
String string = "sdqqfgkkkhjppppkl"; String regex = "(.)\\1+"; //第一组出现一次或多次 String[] sArr = string.split(regex); for(String string2 : sArr) { System.out.print(string2); //输出结果为:sdfghjkl }
需求:我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程,将字符串还原成:“我要学编程”。
-
程序:
String string = "我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程"; //先把'.'去掉 String regex = "\\.+"; String string2 = string.replaceAll(regex,""); //输出:我我我我要要要要学学学学编编编编程程程程 //再把叠词去掉 String regex2 = "(.)\\1+"; System.out.print(string2.replaceAll(regex2,"$1")); //$1获得第一组数据并替换掉regex表达的内容
-
九、常见对象(Pattern和Matcher的概述)
A:Pattern和Matcher的概述
-
B:模式和匹配器的典型调用顺序
通过JDK提供的API,查看Pattern类的说明
-
典型的调用顺序是
-
Pattern p = Pattern.compile("a*b");
- 获取到正则表达式
-
Matcher m = p.matcher("aaaaab");
- 获取匹配器
-
boolean b = m.matches()
- 判断是否可匹配
-
上述等价于
- System.out.println("aaaaab".matches("a*b"));
-
十、常见对象(正则表达式的获取功能)
-
A:正则表达式的获取功能
- Pattern和Matcher的结合使用
-
B:案例演示
- 需求:把一个字符串中的手机号码获取出来
-
C:程序
public class TestRegular_5 { public static void main(String[] args) { String string = "我的手机号是:13345678910,哈哈哈哈,小明的手机号是:18945612300,小花的手机号是15975348621"; String regex = "1[3578]\\d{9}"; //手机号码正则表达式 /*Pattern p = Pattern.compile(regex); Matcher m = p.matcher(string); boolean b = m.matches();*/ Pattern p = Pattern.compile(regex); Matcher m = p.matcher(string); String s1 = null; while(m.find()) { //找到就输出 s1 = m.group(); System.out.println(s1); } } } /* * 在JDK1.8中输出结果为: * ----------------- * 13345678910 18945612300 15975348621 ----------------- * */
十一、常见对象(String类对正则表达式的支持)
public boolean matches(String regex)
public String replaceAll(String regex,String replacement)
public String replaceFirst(String regex,String replacement)
public String[] split(String regex)
public String[] split(String regex,int limit)
* Splits this string around matches of the given regular expression.
十二、常见对象(正则表达式在反射中应用)
-
定义抽象超类Fruit
abstract class Fruit { abstract void desc(); }
-
定义Apple继承Fruit
public class Apple extends Fruit{ @Override void desc() { // TODO Auto-generated method stub System.out.println("苹果过好好吃啊"); } }
-
定义Durian继承Fruit
public class Durian extends Fruit{ @Override void desc() { // TODO Auto-generated method stub System.out.println("榴莲过好好吃啊"); } }
-
定义Orange继承Fruit
public class Orange extends Fruit{ @Override void desc() { // TODO Auto-generated method stub System.out.println("橘子过好好吃啊"); } }
-
定义Factory生产水果
public class Factory { public static Fruit getInstance(String fruitName) { Class c1 = null; try { c1 = Class.forName(fruitName); Fruit fruit = (Fruit)c1.newInstance(); return fruit; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
-
定义测试类
public class TestFactory { public static void main(String[] args) { Fruit fruit = Factory.getInstance("factory.Orange"); fruit.desc(); } }