String 的两种实例化方式
String内容一旦声明赋值后是不可被改变的,改变的是它的引用,但是可以使用+=进行拼接字符串。
public class Demo {
public static void main(String[] args) {
String s = "hello";
s += "world";
System.out.println(s);//helloworld
}
}
如果字符串频率改变高的时候我们不使用String类来创建,而是使用"StringBuffer",“StringBuild” 来创建字符串。
StringBuffer线程安全 可以触发JVM里的gc垃圾回收
StringBuild线程非安全 不触发gc垃圾回收
隐式实例化:直接赋值
public class Demo {
public static void main(String[] args) {
String s = "hello";
String s2 = "hello";
System.out.println(s == s2);//true
}
}
内存图:
String 一般使用直接赋值的方式创建字符串。此时字符串是一个匿名对象,存放于位于堆的字符串常量池(String Table)中。匿名对象也是对象,就如同对象创建后,对象本身不可以改变,字符串也有不可变的特性,每次都将创建新的字符串。因为不可变,所以字符串可以称为字符串常量。
JVM 中设计字符串常量池是为了减少实例化重复的字符串,以节约新建时间和内存空间。
public class Demo {
public static void main(String[] args) {
String s = "hello";
System.out.println(s);//hello
String s = "world";
System.out.println(s2);//world
}
}
内存图:
显式实例化:使用构造函数
public class Demo {
public static void main(String[] args) {
String s = "hello";
String s2 = new String("hello");
String s3 = new String("hello");
System.out.println(s==s2);//false
System.out.println(s==s3);//false
System.out.println(s2==s3);//false
}
}
String 是一个类,可以使用构造函数创建字符串。
intern() 方法
public class Demo {
public static void main(String[] args) {
String s = "hello";
String s2 = new String("hello");
String s3 = new String("hello");
System.out.println(s2 == s2.intern());//false
System.out.println(s == s3.intern());//true
System.out.println(s2.intern() == s3.intern());//true
}
}
intern() 方法,复制字符串对象到字符串常量池,返回字符串(引用)。native() 方法
具体来说:JVM 会在字符串常量池中去比较是否有「等于(equals)」 此 String 对象的字符串,如果有,返回字符串引用,没有则将此 String 对象包含的字符串放入字符串常量池中,再返回引用
String 被 final 修饰。
- final 修饰类,类不能被继承
- 修饰方法,方法不能被重写
- 修饰字段,字段不能指向其他对象
- 字符串常量池和运行时常量池的关系
- 没有关系,运行时常量池存放运行 Class 文件的常量池表。
String 常用方法
String的构造方法功能
- String(String original):把字符串数据封装成字符串对象
- String(char[] value):把字符数组的数据封装成字符串对象
- String(char[] value, int index, int count):把字符数组中的一部分数据封装成字符串对象
String获取功能
1.length():获取字符串的长度,其实也就是字符个数
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.length());//18
2.charAt(int index):获取指定索引处的字符
String str = "adsfaxsdfas沙发上案发地方";
char[] c = {'a','d','s','f','a'};
System.out.println(str.charAt(12));//发
3.indexOf(String str):获取str在字符串对象中第一次出现的索引
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.indexOf('a',5));//9
4.substring(int start):从start开始截取字符串
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.substring(1));//dsfaxsdfas沙发上发地方
5.String substring(int start,int end):从start开始,到end结束截取字符串。包括start,不包括end
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.substring(1, 12));//dsfaxsdfas沙
String判断功能
6.equals(Object obj):比较字符串的内容是否相同
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.equals("adsfaxsdfas沙发上发地方"));//true
System.out.println(str.equals("adsfaxsdfas"));//false
7.equalsIgnoreCase(String anotherString):比较字符串的内容是否相同,忽略大小写
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.equalsIgnoreCase("ADsfaxsdfAs沙发上发地方"));//true
8.startsWith(String prefix):判断字符串对象是否以指定的字符开头(区分大小写)
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.startsWith("a"));//true
System.out.println(str.startsWith("A"));//false
9.startsWith(String prefix,int toffset):判断字符串对象是否以指定的字符开头,参数toffset为指定从哪个下标开始
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.startsWith("f", 3));//true
System.out.println(str.startsWith("f", 4));//false
10.endsWith(String str):判断字符串对象是否以指定的字符结尾
String str = "adsfaxsdfas沙发上案发地方";
System.out.println(str.endsWith("x"));//false
System.out.println(str.endsWith("方"));//true
11.isEmpty():判断指定字符串是否为空
String的转换方法
12.toCharArray():把字符串转换为字符数组
public static void main(String[] args) {
String str = "adsfaxsdfas沙发上发地方";
char arr[] = str.toCharArray();
printArray(arr);
}
public static void printArray(char a[]) {
for(int i=0;i<a.length;i++) {
System.out.print(a[i]+"--");
//a–d--s–f--a–x--s–d--f–a--s–沙--发–上--发–地--方–
}
}
13.toLowerCase():把字符串转换为小写字符串
String str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
System.out.println(str1.toLowerCase());//abcdefghijklmnopqrstuvwxyz
14.toUpperCase():把字符串转换为大写字符串
String str1 = "abcdefghijklmnopqrstuvwxyz";
System.out.println(str2.toUpperCase());//ABCDEFGHIJKLMNOPQRSTUVWXYZ
String其他常用方法
15.trim():去除字符串两端空格
String str3 = " a c e x u a n x u a n ";
System.out.println(str3.trim());
System.out.println(str3);
//a c e x u a n x u a n
16.split():去除字符串中指定的的字符,然后返回一个新的字符串
public static void main(String[] args) {
String str = "adsfaxsdfas沙发上发地方";
String array[] = str.split("a");
printString(array);
}
public static void printString(String a[]) {
for(int i=0;i<a.length;i++) {
System.out.print(a[i]);//dsfxsdfs沙发上发地方
}
}
17.subSequence(int beginIndex,int endIndex ):截取字符串中指定位置的字符组成一个新的字符串
String str = "adsfaxsdfas沙发上发地方";
System.out.println(str.subSequence(1, 10));//dsfaxsdfa
18.replace(char oldChar, char newChar):将指定字符替换成另一个指定的字符
String str = "adsfaxsdfas沙发上发地方";
System.out.println(str.replace('a', 's'));//sdsfsxsdfss沙发上发地方
19.replaceAll(String regex,String replasement):用新的内容替换全部旧内容
String str4 = "Hello,world!";
System.out.println(str4.replaceAll("l", "&"));//He&&o,wor&d!
20.replaceFirst(String regex,String replacement):替换首个满足条件的内容
String str = "adsfaxsdfas沙发上发地方";
System.out.println(str.replaceFirst("沙", "璇"));//adsfaxsdfas璇发上发地方
21.lastIndexOf(String str):返回指定字符出现的最后一次的下标
String str4 = "Hello,world!";
System.out.println(str4.lastIndexOf("l"));//9
22.contains(CharSequence s):查看字符串中是都含有指定字符
String str4 = "Hello,world!";
System.out.println(str4.contains("l"));//true
23.concat(String str):在原有的字符串的基础上加上指定字符串
String str5 = "dr";
System.out.println(str5.concat("eam"));//dream
24.开发过程中经常用到的方法
/**
* 截取字符串str中指定字符 strStart、strEnd之间的字符串
*
* @param str 待截取的字符串
* @param strStart 起始字符或字符串
* @param strEnd 截止字符或字符串
* @return
*/
public String subString(String str, String strStart, String strEnd) {
// 找出指定的2个字符在该字符串里面的位置
int strStartIndex = str.indexOf(strStart);
int strEndIndex = str.indexOf(strEnd);
// index为负数,即表示该字符串中没有该字符
if (strStartIndex < 0) {
return "字符串 :---->" + str + "<---- 中不存在 " + strStart + ", 无法截取目标字符串";
}
if (strEndIndex < 0) {
return "字符串 :---->" + str + "<---- 中不存在 " + strEnd + ", 无法截取目标字符串";
}
// 开始截取
return str.substring(strStartIndex, strEndIndex).substring(strStart.length());
}
小扩展
正则表达式
开发心得:看着正确数据,从左到右书写正则表达式
正则表达式的概念及演示
- 在Java中,我们经常需要验证一些字符串,例如:年龄必须是2位的数字、用户名必须是8位长度而且只能包含大小写字母、数字等。正则表达式就是用来验证各种字符串的规则。它内部描述了一些规则,我们可以验证用户输入的字符串是否匹配这个规则。
- 先看一个不使用正则表达式验证的例子:下面的程序让用户输入一个QQ号码,我们要验证:
- QQ号码必须是6–20位长度
- 而且必须全部是数字
- 而且首位不能为0
public class Test1 {
public static void main(String[] args) {
// 假如现在要求校验一个qq号码是否正确,6位及20位之内,0不能在开头,必须全部是数字 。
System.out.println(checkQQ("23658977452"));
System.out.println(checkQQ("236589775223589775223589775223589775223658977452"));
}
public static boolean checkQQ(String qq){
//1.校验长度
if(qq.length() < 6 || qq.length() > 20){
return false;
}
//2.校验开头
char c = qq.charAt(0);
if(c == '0'){
return false;
}
//3.校验内容
for (int i = 0; i < qq.length(); i++) {
//i索引 charAt(i)字符
char at = qq.charAt(i);
if(at < '0' || at > '9'){
return false;
}
}
//4.当循环结束之后,还没有发现不是数字的
return true;
}
}
- 使用正则表达式验证:
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的QQ号码:");
String qq = sc.next();
System.out.println(checkQQ2(qq));
}
//使用正则表达式验证
private static boolean checkQQ2(String qq){
String regex = "[1-9]\\d{5,19}";//正则表达式
return qq.matches(regex);
}
}
上面程序checkQQ2()方法中String类型的变量regex就存储了一个"正则表达式 ",而这个正则表达式就描述了我们需要的三个规则。matches()方法是String类的一个方法,用于接收一个正则表达式,并将"本对象"与参数"正则表达式"进行匹配,如果本对象符合正则表达式的规则,则返回true,否则返回false。
我们接下来就重点学习怎样写正则表达式
正则表达式-字符类
- 语法示例:
- [abc]:代表a或者b,或者c字符中的一个。
- [^abc]:代表除a,b,c以外的任何字符。
- [a-z]:代表a-z的所有小写字符中的一个。
- [A-Z]:代表A-Z的所有大写字符中的一个。
- [0-9]:代表0-9之间的某一个数字字符。
- [a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。
- [a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符。
- 代码示例:
public class Demo {
public static void main(String[] args) {
String str = "ead";
//1.验证str是否以h开头,以d结尾,中间是a,e,i,o,u中某个字符
String regex = "h[aeiou]d";
System.out.println("1." + str.matches(regex));
//2.验证str是否以h开头,以d结尾,中间不是a,e,i,o,u中的某个字符
regex = "h[^aeiou]d";
System.out.println("2." + str.matches(regex));
//3.验证str是否a-z的任何一个小写字符开头,后跟ad
regex = "[a-z]ad";
System.out.println("3." + str.matches(regex));
//4.验证str是否以a-d或者m-p之间某个字符开头,后跟ad
regex = "[[a-d][m-p]]ad";
System.out.println("4." + str.matches(regex));
}
}
正则表达式-逻辑运算符
- 语法示例:
- &&:并且
- | :或者
- 代码示例:
public class Demo {
public static void main(String[] args) {
String str = "had";
//1.要求字符串是小写辅音字符开头,后跟ad
String regex = "[a-z&&[^aeiou]]ad";
System.out.println("1." + str.matches(regex));
//2.要求字符串是aeiou中的某个字符开头,后跟ad
regex = "[a|e|i|o|u]ad";//这种写法相当于:regex = "[aeiou]ad";
System.out.println("2." + str.matches(regex));
}
}
正则表达式-预定义字符
- 语法示例:
- “.” : 匹配任何字符。
- “\d”:任何数字[0-9]的简写;
- “\D”:任何非数字[^0-9]的简写;
- “\s”: 空白字符:[ \t\n\x0B\f\r] 的简写
- “\S”: 非空白字符:[^\s] 的简写
- “\w”:单词字符:[a-zA-Z_0-9]的简写
- “\W”:非单词字符:[^\w]
- 代码示例:
public class Demo {
public static void main(String[] args) {
String str = "258";
//1.验证str是否3位数字
String regex = "\\d\\d\\d";
System.out.println("1." + str.matches(regex));
//2.验证手机号:1开头,第二位:3/5/8,剩下9位都是0-9的数字
str = "13513153355";//要验证的字符串
regex = "1[358]\\d\\d\\d\\d\\d\\d\\d\\d\\d";//正则表达式
System.out.println("2." + str.matches(regex));
//3.验证字符串是否以h开头,以d结尾,中间是任何字符
str = "had";//要验证的字符串
regex = "h.d";//正则表达式
System.out.println("3." + str.matches(regex));
//4.验证str是否是:had.
str = "had.";//要验证的字符串
regex = "had\\.";//\\.代表'.'符号,因为.在正则中被预定义为"任意字符",不能直接使用
System.out.println("4." + str.matches(regex));
}
}
正则表达式-数量词
- 语法示例:
- X? : 0次或1次
- X* : 0次到多次
- X+ : 1次或多次
- X{n} : 恰好n次
- X{n,} : 至少n次
- X{n,m}: n到m次(n和m都是包含的)
- 代码示例:
public class Demo {
public static void main(String[] args) {
String str = "";
//1.验证str是否是三位数字
str = "012";
String regex = "\\d{3}";
System.out.println("1." + str.matches(regex));
//2.验证str是否是多位数字
str = "88932054782342";
regex = "\\d+";
System.out.println("2." + str.matches(regex));
//3.验证str是否是手机号:
str = "13813183388";
regex = "1[358]\\d{9}";
System.out.println("3." + str.matches(regex));
//4.验证小数:必须出现小数点,但是只能出现1次
String s2 = "3.1";
regex = "\\d*\\.{1}\\d+";
System.out.println("4." + s2.matches(regex));
//5.验证小数:小数点可以不出现,也可以出现1次
regex = "\\d+\\.?\\d+";
System.out.println("5." + s2.matches(regex));
//6.验证小数:要求匹配:3、3.、3.14、+3.14、-3.
s2 = "-3.";
regex = "[+-]\\d+\\.?\\d*";
System.out.println("6." + s2.matches(regex));
//7.验证qq号码:1).5--15位;2).全部是数字;3).第一位不是0
s2 = "1695827736";
regex = "[1-9]\\d{4,14}";
System.out.println("7." + s2.matches(regex));
}
}
String的split方法中使用正则表达式
-
String类的split()方法原型:
public String[] split(String regex)//参数regex就是一个正则表达式。可以将当前字符串中匹配regex正则表达式的符号作为"分隔符"来切割字符串。
-
代码示例:
String names = "小路dqwefqwfqwfwq12312蓉儿dqwefqwfqwfwq12312小何";
//要求1:把字符串中的三个姓名切割出来
String[] arr = names.split("\\w+");
//String[] arr = names.split("\\.");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
String类的replaceAll方法中使用正则表达式
- String类的replaceAll()方法原型:
public String replaceAll(String regex,String newStr)
//参数regex就是一个正则表达式。可以将当前字符串中匹配regex正则表达式的字符串替换为newStr。
- 代码示例:
//要求2:把字符串中三个姓名之间的字母替换为vs
String names = "小路dqwefqwfqwfwq12312蓉儿dqwefqwfqwfwq12312小何";
//切记:字符串本身是不可变的,不管是截取,还是替换还是其他操作,不能改变字符串本身
//只有返回值才是操作之后的结果
String result = names.replaceAll("\\w+", "vs");
System.out.println(result);
练习1-匹配手机号码(掌握)
代码示例:
//验证手机号码 13112345678 13712345667 13945679027
String regex1 = "[1-9][3-9]\\d{9}";
System.out.println("13112345678".matches(regex1));
System.out.println("13712345667".matches(regex1));
System.out.println("13945679027".matches(regex1));
System.out.println("139456790271".matches(regex1));
6.9练习2-匹配座机号码(掌握)
代码示例:
//验证座机电话号码 020-2324242 02122442 027-42424 0712-3242434
String regex2 = "0\\d{2,3}-?[1-9]\\d{4,9}";
System.out.println("020-2324242".matches(regex2));
System.out.println("02122442".matches(regex2));
System.out.println("027-42424".matches(regex2));
System.out.println("0712-3242434".matches(regex2));
6.10练习3-匹配邮箱(了解)
代码示例:
//验证邮箱3232323@qq.com zhangsan@itcast.cnn dlei0009@163.com dlei0009@pci.com.cn
//把邮箱分为三段来写:
//第一段:@的左半部分,任意的字母数字下划线,至少出现一次 \\w+
//第二段:@只能出现一次 @
//第三段:比较难,我们可以把第三段继续分为三段
//3-1:点的左半部分:字母和数字可以出现2~8次。 [\w^_]{2,8}
//3-2:点 \\.
//3-3:点的右半部分:大写字母和小写字母只能出现2~3次。 [a-zA-Z]{2,3}
//又因为,有的邮箱,还有可能会有点,所以把3-2和3-3看成一个整体,这个整体可以出现1~2次。
String regex3 = "\\w+@[\\w^_]{2,8}(\\.[a-zA-Z]{2,3}){1,2}";
System.out.println("39232323@qq.com".matches(regex3));
System.out.println("zhangsan@itcast.cnn".matches(regex3));
System.out.println("dlei0009@163.com".matches(regex3));
System.out.println("dlei0009@pci.com.cn".matches(regex3));
爬取数据的小扩展(了解)
代码示例:
String rs = "来学习Java,电话020-43422924,或者联系邮箱" +
"电话18762832633,0203992323" +
"邮箱400-100-3233 ,4001003232";
//四段当中,只要满足其中一段就可以
String regex =
//匹配邮箱
"(\\w{1,}@\\w{2,10}(\\.\\w{2,10}){1,2})|" +
//匹配手机号码
"(1[3-9]\\d{9})|" +
//匹配座机号码
"(0\\d{2,5}-?\\d{5,15})|" +
//匹配热线电话
"400-?\\d{3,8}-?\\d{3,8}";
//获取一个正则表达式的对象
Pattern pattern = Pattern.compile(regex);
//获取匹配器对象
Matcher matcher = pattern.matcher(rs);
while(matcher.find()){
String group = matcher.group();
System.out.println(group);
}
第七章 Arrays类
7.1常见方法
方法名 | 说明 |
---|---|
public static String toString(类型[] a) | 把数组变成字符串返回 |
public static void sort(类型[] a) | 对数组进行默认升序排序 |
public static int binarySearch(int[] a, int key) | 二分搜索数组中的数据,存在返回索引,不存在返回负插入点-1 |
代码示例:
public class Demo1 {
public static void main(String[] args) {
//1.定义数组
//int[] arr = {4,1,3,2,5};
//对数组中的数据进行排序
//Arrays.sort(arr);
//把数组里面所有的数据,拼接在一起,变成一个字符串给你返回
//String result = Arrays.toString(arr);
//System.out.println(result);
//System.out.println(Arrays.toString(arr));
//binarySearch作用:查找某一个数据在数组中出现的索引
//前提:数组必须是从小到大,有序的
//如果要查询的数据不存在,那么返回负数
//了解:-插入点-1
int[] arr = {1,2,3,4,5,7,9,10,20,30};
int index = Arrays.binarySearch(arr, 0);
System.out.println(index);
}
}