java基础相关
String类
String 用来表示一个字符串,具有以下特点:
- java.lang.String 使用了final修饰,因此 不能 被继承。
- 字符串底层封装了字符数组以及针对字符数组的操作算法。
- 字符串一旦创建,对象永远无法改变,但字符串引用可以重新复制。
- java字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的定长编码。
字符串常量池
java在堆内存中开辟了一段空间用于缓存所有使用字面量形式创建的字符串对象,并在后期再次使用该字面量创建字符串时重用对象,避免内存中堆积大量内容一样的字符串对象来减小内存开销。
对于重复出现的字符串直接量,JVM会首先在常量池中查找,如果存在即返回该对象地址。
String s1 = "123abc";//字面量
String s2 = "123abc";//与s1字面量相同,重用对象
//地址相同,说明s2重用了s1对象
System.out.println(s1==s2);//true
String s3 = "123abc";
System.out.println(s1==s3);//true
注意:
通常我们判断字符串都是比较内容,因此应当使用字符串的equals方法
/*
这里触发了一个编译器的特性:
编译器在编译期间若遇到几个计算表达式,发现在编译期可以确定结果时就会进行计算
并将结果编译到class文件中,这样以来JVM每次执行字节码文件就无需再计算了。
下面的代码会被编译器改为:
String s5 = "123abc";
也因此s5会重用常量池中的对象,所以地址与s2相同
*/
String s5 = "123" + "abc";
System.out.println("s5:"+s5);
System.out.println(s2==s5); //true
字符串常用方法:
返回长度int length()
返回当前字符串的长度(字符个数)
String str = "我爱java!";
int len = str.length();
System.out.println("len:"+len);
获取元素下标indexOf()
检索给定字符串在当前字符串中的位置,若当前字符串不含有给定内容则返回值为-1
String str = "echo.li.blue";
int index = str.indexOf("l");//5
System.out.println(index);//5
重载方法,可以从指定位数开始检索:
index = str.indexOf("l",6);//3
// 字符 指定位数
System.out.println(index);
检索最后一次出现l的位置lastIndexOf()
index = str.lastIndexOf("l");
System.out.println(index);//9
截取指定字符串substring()
截取当前字符串中指定范围内的字符串。两个参数分别为开始位置的下标和结束位置的下标。注:在JAVA API中通常使用两个数字表示范围时是"含头不含尾"的。
String line = "echo.li.blue";
// 012345678901
String str = line.substring(5,7);
System.out.println(str); //li
重载方法,可以从指定位数一直截取到末尾:
str = line.substring(5);
System.out.println(str);//li.blue
去除空白trim()
去出一个字符串两边的空白字符 //只去两边,不去中间
String line = " he llo ";
System.out.println(line); //he llo
获取下标元素charAt()
获取字符串指定位置下标的元素
String str = "thinking in java";
//获取第10个字符
char c = str.charAt(9); //i
判断开始或结尾startsWith()和endsWith()
判断一个字符串是否是以指定字符开始或结尾
//starts 开始 //ends 末端
String line = "echo.li.blue";
boolean starts = line.startsWith("echo"); //true
boolean ends = line.endsWith("li"); // false
转大小写toLowerCase()和toUpperCase()
String line = "Java";
String lower = line.toLowerCase(); //java
String upper = line.toUpperCase(); //JAVA
valueOf将其他类型转为String
将其他类型转为String。
int a = 123456;
String s1 = String.valueOf(a);
double d = 123.456;
String s2 = String.valueOf(d);
String s3 = a+"";//任何内容和字符串链接结果都是字符串
StringBuider
由于String是不变对象,每次修改内容都要创建新对象,因此String不适合做频繁修改操作.为了解决这个问题,java提供了StringBuilder类.
java.lang.StringBuilder
StringBuilder是专门用来修改String的一个API,内部维护一个可变的char数组,修改都是在这个数组上进行的,内部会自动扩容.修改速度和性能开销优异.并且提供了修改字符串的常见操作对应的方法:增删改插
String str = "java";
//复制给定字符串到StringBuilder内部
// StringBuilder builder = new StringBuilder(str);//不是线程安全的
StringBuffer builder = new StringBuffer(str);//是线程安全的
append:追加内容
builder.append(".lang");
System.out.println(builder);//输出StringBuilder的内容 : java.lang
// 0123456789
replace:替换部分内容
在Java中的下标操作,一般是含头不含尾的
builder.replace(5,8,".lang.Stri");
System.out.println(builder); //java.lang.String
// 01234567890123456
delete:删除部分内容
builder.delete(0,8);
System.out.println(builder); //g.String
insert:插入操作
builder.insert(0,"学习");
System.out.println(builder); //学习g.String
翻转字符串
builder.reverse();
System.out.println(builder); //gnirtS.g习学
StringBuffer 和StringBuilder
- StringBuffer是线程安全的,同步处理的,性能稍慢
- StringBuilder是非线程安全的,并发处理的,性能稍快
正则表达式
正则表达式是用来描述一个字符串的内容格式,使用它通常用来匹配一个字符串的内容是否符合格式要求.
基本语法
[]:表示一个字符,该字符可以是[]中指定的内容
例如:
预定义字符
- . : “.”表示任意一个字符,没有范围限制 //点
- \d: 表示任意一个数字,等同于[0-9]
- \w: 表示任意一个单词字符,等同于a-zA-Z0-9_
- \s: 表示任意一个空白字符.
- \D: 表示不是数字
- \W: 不是单词字符
- \S: 不是空白字符
量词:
- ? : 表示前面的内容出现0-1次
- 例如:
- abc? 可以匹配:a 或 b 或 c 或什么也不写
- + : 表示前面的内容出现1次以上
- abc+ 可以匹配:aaaaaaaaaa…或abcabcbabcbabcbabcbabbabab…
- 但是不能匹配:什么都不写或abcfdfsbbaqbb34bbwer…
- * : 表示前面的内容出现任意次(0-多次)
- 匹配内容与+一致,只是可以一次都不写.
- {n} : 表示前面的内容出现n次
- 例如:
- abc{3} 可以匹配:aaa 或 bbb 或 aab
- 不能匹配:aaaa或aad
- {n,m} : 表示前面的内容出现最少n次最多m次
- abc{3,5} 可以匹配:aaa 或 abcab 或者 abcc
- 不能匹配:aaaaaa 或 aabbd
- {n,} : 表示前面的内容出现n次以上(含n次)
- abc{3,} 可以匹配:aaa 或 aaaaa… 或 abcbabbcbabcbabcba…
- 不能匹配:aa 或 abbdaw…
- () 用于分组,是将括号内的内容看做是一个整体
- 例如:
- (abc){3} 表示abc整体出现3次. 可以匹配abcabcabc.
- 不能匹配aaa 或abcabc
- (abc|def){3} 表示abc或def整体出现3次.
- 可以匹配: abcabcabc 或 defdefdef 或 abcdefabc
String支持正则表达式的相关方法
matches方法
boolean matches(String regex)
使用给定的正则表达式验证当前字符串是否满足格式要求,满足则返回true.否则返回false
/*
邮箱的正则表达式
用户名@域名
echo@qq.cn
[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\.[a-zA-Z]+)+
*/
String mail = "fancq@tedu.cn";
String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";
//两个\因为Java中\有转义的用法,所以需要再转义一次
boolean match = mail.matches(regex);
if(match){
System.out.println("是邮箱");
}else{
System.out.println("不是邮箱");
}
split方法 (拆分)
String[] split(String regex)
将当前字符串按照满足正则表达式的部分进行拆分,将拆分后的每部分以数组形式返回。用来拆分的字符不返回。
String str = "abc123def456ghi";
//按照数字部分拆分,获取其中每部分字母
String[] arr = str.split("[0-9]+");
System.out.println(arr.length); //3
System.out.println(Arrays.toString(arr)); //[abc, def, ghi]
str = "123,456,789,023";
//拆分出所有的数字部分
arr = str.split(",");
System.out.println(Arrays.toString(arr)); //[123, 456, 789, 023]
//如果连续遇到拆分项,则会拆分出一个空字符串.但是在字符串末尾连续遇到则忽略.
str = ",,,123,,,456,789,023,,,,";
//拆分出所有的数字部分
arr = str.split(",");
System.out.println(Arrays.toString(arr)); //[, , , 123, , , 456, 789, 023]
str = "123.456.789.023";
//拆分出所有的数字部分
arr = str.split("\\.");//.在正则表达式中表示任意字符,要注意转意!
System.out.println(Arrays.toString(arr)); //[123, 456, 789, 023]
replaceAll方法
String replaceAll(String regex,String str)
将当前字符串中满足正则表达式的部分替换为给定内容
String str = "abc123def456ghi";
//将当前字符串中的数字部分替换为#NUMBER#
str = str.replaceAll("[0-9]+","#NUMBER#");
System.out.println(str);
Object类
Object是所有类的顶级超类,其中有两个经常被子类重写的方法:
toString()与equals().
对于引用类型而言,变量保存的值是对象的地址.
Point p = new Point(1,2);
Point p2 = new Point(1,2);
System.out.println(p == p2);//false
System.out.println(p.equals(p2));//true
/*
==比较是比较两个变量的值是否相等,因此对于引用类型而言就是比较地址是否相等,
那么意思就是比较是否为同一个对象.
equals是Object定义的另一个方法,意图是比较两个对象的内容是否相同.
但是如果子类不重写这个方法,则没有实际意义,因为Object实现时内部仍然是用==比较的!
*/
包装类
java定义了8个包装类,目的是为了解决基本类型不能直接参与面向对象开发的问题,使得基本类型可以通过包装类的实例以对象的形式存在.
- 其中数字类型的包装类都继承自java.lang.Number,而char和boolean的包装类直接继承自Object
- Number是一个抽象类,定义了一些方法,目的是让包装类可以将其表示的基本类型转换为其他数字类型.