目录
什么是JDK API?
文档注释规范:
文档注释:
字符串基本操作: String及其常用API ,StringBuilder,正则表达式
String是不可变对象
String常量池:
编译器特性:
常用方法:
StringBuilder:
String,StringBuilder,StringBuffer 三者区别
正则表达式:
String 正则API:
JDK中包含大量的API类库,所谓API ( ApplicationProgramming Interface,应用程序编程接口)就是些已写好、可供直接调用的功能(在Java语言中这些功能以类的形式封装)。
JDK API包含的类库功能强大,经常使用的有:字符串操作、集合操作、文件操作、输入输出操作、网络操作、多线程等等。
jdk/bin/javadoc.exe
以/**开始,以*/结束加在类和方法的开头,用于说明作者,时间,版本,要实现功能的详细描述等信息;通过jdk/bin/javadoc.exe工具,可以轻松的将此注释转换为HTML文档说明;学习者和程序员主要通过文档了解API的功能;文档注释不同于普通的注释( //..或/*...*/ ) ,普通注释
写在程序之中,用于程序员进行代码维护和交流,无法通过工具生成文档;而文档注释( /**..*/ )写在类和方法的开头,专门用于生成供API使用者进行参考的文档资料。
/**
* 文档注释是功能级注释,只在三个地方使用:类上,方法上,常量上
* 文档注释在类还是那个使用时,是说明当前类的功能.
* doc-文档
* @author 作者
*
*@version 版本号 1.0 (1 大版本号-增加功能 ,,0小版本号-修复Bug)
*@see 参考 java.lang.String
*@since 始于版本 JDK 1.5
*
*/
java.lang.String;
1)使用final修饰,不能被继承,修改,重写
2)字符串底层封装了字符数组(char[])及对其的操作算法
3)字符串一旦创建,对象永远无法改变,但字符串引用可以重新赋值
4)Java字符串字符对应 16位(2字节)UniCode编码
JDK1.7 放在堆中 大小灵活配置 堆中有GC
Java为了提高性能静态字符串(字面量/常量/常量连接的结果)在常量池中创建,并尽量使用同一个对象,重用静态字符串;
对于重复出现的字符串直接量, JVM会首先在常量池中查找,如果存在即返回该对象。这样可以减少内存开销
String s1 = "123abc";
String s2 = "123abc";//s2重用了s1创建的对象
//是s1和s2都是引用类型变量,保存的是对象的地址,如果相同说明指向同一个对象
System.out.println("s1==s2:"+(s1==s2));
String s3 = "123abc";
System.out.println("s2==s3:"+(s2==s3));//true
System.out.println("s1==s3:"+(s1==s3));//true
//new 关键字创建时一定产生新对象.java不推荐这种形式的创建字符串
String s4 = new String("123abc");
System.out.println("s4:"+s4);
//new出来的字符串不会重用对象
System.out.println("s1==s4:"+(s1==s4));//false
/*
* String是不变对象,即:
* String 对象创建后内容不可改变,若改变内容一定要创建新对象
*/
System.out.println("s1:"+s1);
s1=s1+"!";//修改内容就会重新创建对象
System.out.println("s1:"+s1);
System.out.println("s2:"+s2);
//s1与s2,s3已经不在指向同一个对象了
System.out.println("s1==s2:"+(s1==s2));//false
编译器在编译期间,如果发现一个计算表达式可以在编译期间确定结果时,就会进行计算,并将结果编译到class文件中,下面代码改为: String s5 = "123abc";
String s5 = "123" +"abc";
System.out.println("s5="+s5);
System.out.println("s2==s5:"+(s2==s5));
String s="123";
String s6= s+"abc";//修改内容会创建新对象
System.out.println("s6="+s6);
System.out.println("s2==s6"+(s2==s6));//false
length()方法
该方法可以返回当前字符串的长度(字符的个数),内存编码及长度String在内存中采用Unicode编码,每个字符16位占用两个字节;任何一个字符( 无论中文还是英文)都算1个char字符长度,占用两个字节。
public class LengthDmeo {
public static void main(String[] args) {
String str = "我爱java!";
int length = str.length();
System.out.println("len:"+length);//7
}
}
indexOf(String str) 方法:
检索给定字符串在当前字符串中的位置,如果当前字符串不包含给定内容时,返回值为-1.
String提供几个重载的indexOf方法
int indexOf (String str) | 在字符串中检索str ,返回其第一次出现的位置,如果找不到则返回-1 |
int indexOf (String str, int Index) | 从字符串的Index位置开始检索 |
String还定义有lastIndexOf ()方法:
int lastIndexOf( String str ) | str在字符串中多次出现时,将返回最后一个出现的位置 |
public class IndexOfDemo {
public static void main(String[] args) {
// 0123456789012345
String str = "thinking in java";//java编程思想
int index = str.indexOf("in");
System.out.println(index);//2
index = str.indexOf("IN");
System.out.println(index);//-1
/*
* 重载方法,允许从指定位置开始检索
*/
index = str.indexOf("in",3);
System.out.println(index);//5
/*
* lastIndexOf方法可以检索最后一次出现给定内容的位置
*/
index = str.lastIndexOf("in");
System.out.println(index);//9
}
}
substring((int start,int end):截取当前字符串中指定范围内的字符
start 是开始位置下标 end是结束位置下标(截取时不包含该位置的字符 )
注:通常在API中 ,用两个数字表示范围时,通常含头不含尾
String substring (int beginIndex ,int endIndex ) | 返回字符串中从下标beginIndex (包括)开始到endIndex (不包括)结束的子字符串 |
String substring (int beginIndex ) | 返回字符串中从下标beginIndex (包括)开始到字符串结尾的子字符串 |
public class SubstringDemo {
public static void main(String[] args) {
// 01234567890
String str = "www.tedu.cn";
//截取域名
String sub = str.substring(4, 8);
System.out.println(sub);
/*
* 重载的substring方法是从指定位置开始截取到字符串末尾。
*/
sub = str.substring(4);
System.out.println(sub);
}
}
char charAt( ) 方法:
char charAt(int index) | 获取当前字符串中指定位置的字符 |
public class CharAtDemo {
public static void main(String[] args) {
// 0123456789012345
String str = "thinking in java";
//获取当前字符串第10个字符?
char c = str.charAt(9);
System.out.println(c);
for(int i=0;i
trim( ) 方法:
String trim( ) | 去除字符串两边的空白字符,注意中间的空格不能去除 |
public class TrimDemo {
public static void main(String[] args) {
//左侧为三个空格,右侧为三个缩进符tab
String str = " hello ";
System.out.println(str);
String trim = str.trim();//将去除后的字符串返回
System.out.println(trim);
System.out.println(str);//原字符串不受影响
}
}
startsWith( ) 和 endsWith( )
boolean startsWith(String str) | 判断字符串是否以给定字符串开始 |
boolean endsWith(String str) | 判断字符串是否以给定字符串结尾 |
public class StartsWithDemo {
public static void main(String[] args) {
String str = "thinking in java";
boolean starts = str.startsWith("thi");
System.out.println("start="+starts);
boolean ends = str.endsWith("ava");
System.out.println("ends="+ends);
}
}
toUpperCase( )和 toLowerCase( )
String toUpperCase( ) | 将当前字符串中的英文部分转换为全大写 |
String toLowerCase( ) | 将当前字符串中的英文部分转换为全小写 |
public class ToUpperCaseDemo {
public static void main(String[] args) {
String str = "我爱Java";
String upper = str.toUpperCase();//全大写
System.out.println(upper);
String lower = str.toLowerCase();//全小写
System.out.println(lower);
}
}
valueOf( )
static String valueOf(XXX xxx) | String提供了一组静态的valueOf方法,可以将给定其他类型转换为字符串(String 类型),比较常用的是将基本类型转换为字符串 |
public class ValueOfDmeo {
public static void main(String[] args) {
int a = 123;
String s = String.valueOf(a);//"123"
System.out.println(s);
double d = 12.221;
String s1 = String.valueOf(d);
System.out.println(s1);
//连接空字符串也可以做到转换为String的效果 (性能差)
String s2 = a + "";//任何内容和字符串连接结果都是字符串
System.out.println(s2);
}
}
java.lang.StringBuilder;
由于字符串的特性决定着它不适合做修改操作.为了解决这个问题:java提供了便于修改字符串的API: StringBuilder;
StringBuilder 提供了修改字符串的一系列操作,增删改插等,StringBuilder内部维护着一个可变的char数组,修改速度好,且内存开销小
常用方法:
StringBuilder类的常用方法 | 功能描述 |
StringBuilder append(String str) | 追加字符串,将给定的内容追加到当前字符串末尾 |
StringBuilder delete(int start , int end) | 删除字符串,删除当前字符串中指定范围内的内容 |
StringBuilder replace(int start , int end,String str) | 替换字符串,替换当前字符串中指定范围内的字符串为给定字符(含头不含尾) |
StringBuilder insert (int index,String str) | 插入字符串,将给定字符串插入到指定位置 |
StringBuilder reverse() | 字符串反转 |
String toString( )该方法获取StringBuilder内部表示的修改后的字符串 |
public class A_StringBuilderNote {
public static void main(String[] args) {
String str = "好好学习java";
StringBuilder builder = new StringBuilder(str);
builder.append(",为了找个好工作");
str = builder.toString();
System.out.println(str);
builder.replace(9, 16, "就是为了改变世界");
str = builder.toString();
System.out.println(str);
builder.delete(0, 8);
str = builder.toString();
System.out.println(str);
builder.insert(0, "活着");
str = builder.toString();
System.out.println(str);
}
}
长度 | 线程 | 速度 | 总结 | |
String | final修饰,长度不可变,不可修改 | 如果要操作少量的数据用 | ||
StringBuilder | 字符串变量,是可改变的对象 | 线程非安全的 | 并发处理,性能稍快 | 单线程操作字符串缓冲区 下操作大量数据 |
StringBuffer | 字符串变量,是可改变的对象 | 线程安全的 | 同步处理 性能稍慢 | 多线程操作字符串缓冲区 下操作大量数据 |
正则表达式的作用是验证某个字符串的内容是否符合格式要求的。
字符集合:
正则表达式 | 说明 |
[abc] | 除了a、b、c的任意字符 |
[^abc] | 除了a、b、c的任意字符 |
[a-z] | a、b、c、.....z中的任意一个字符 |
[a-zA-Z0-9] | a~Z、A~Z、 0~9中任意一个字符 |
[a-z&&[^ bc]] | a ~ z中除了b和c以外的任意一个字符,其中&&表示“与”的关系 |
预定义字符集:
正则表达式 | 说明 |
. | 任意一个字符 |
\d | 任意一个字符,相当于[0-9] |
\w | 单词字符,相当于[ a-zA-Z0-9_ ] |
\s | 空白字符,相当于[ \t\n\xOB\f\r ] |
\D | 非数字字符 |
\W | 非单词字符 |
\S | 非空白字符 |
量词:
非空白字符 | 说明 |
X? | 表示0个或1个X |
X* | 表示0个或任意多个X |
X+ | 表示1个到任意多个X (大于等于1个X ) |
X{n} | 表示n个X |
X{n, } | 表示n个到任意多个X (大于等于n个X ) |
X{n, m } | 表示n个到m个X |
分组:
( ) | 将"()"当中的内容看做一个整体 |
" ^ " " $ "
边界匹配: ^代表字符串开始
$代表字符串结束
boolean matches(String regex) | 使用给定的正则表达式验证字符串的内容是否符合使用给定的正则表达式验证字符串的内容是否符合 |
String[] split(String regex) | 将当前字符串按照满足正则表达式的部分进行拆分,将拆分后的字符串以数组形式返回 |
String replaceAll(String regex,String str) | 将当前字符串中满足正则表达式的部分替换为给定的字符串 |
练习用正则表达式检验邮箱地址:
public class MatchesDemo {
public static void main(String[] args) {
/*
* email的正则表达式:
*
* [email protected]
*
* [a-zA-Z0-9_]+@[a-zA-Z0-9]+(\.[a-zA-Z]+)+
* \w+@[a-zA-Z0-9]+(\.[a-zA-Z]+)+
*/
String email = "[email protected]";
/*
* boolean matches(String regex)
* 用给定的正则表达式验证当前字符串是否符合格式要求,匹配通过则返回true
*
* 注:
* 正则表达式中经常会使用"\"转义字符,如果出现时,那么在java字符串中
* 表示该正则表达式时,所有"\"都要写成"\\"
*/
String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";
boolean match = email.matches(regex);
if(match) {
System.out.println("是邮箱地址");
}else {
System.out.println("不是邮箱地址");
}
}
}
replaceAll( );
public class ReplaceAllDemo {
public static void main(String[] args) {
String str = "abc123def456ghi";
/*
* 将当前字符串中的数字部分换乘"#NUMBER#"
* abc#NUMBER#def#NUMBER#ghi
*/
str = str.replaceAll("[0-9]+", "#NUMBER#");
System.out.println(str);
/*
* 和谐用语
*/
String regex = "(wqnmlgb|dsb|cnm|mdzz|nmsl|nc|djb)";
String message = "wqnmlgb!你个dsb,你怎么这么nc,你就是一个djb!";
message = message.replaceAll(regex, "***");
System.out.println(message);
}
}
split(String regex) :
public class SplitDemo {
public static void main(String[] args) {
String str = "abc123def456ghi";
//将当前字符串按照数字部分拆分
String[] arr = str.split("[0-9]+");
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
str = "abc,def,ghi,lmn";
arr = str.split(",");
System.out.println(arr.length);//4
System.out.println(Arrays.toString(arr));
//按照"."拆分
str = "aaa.bbb.ccc.ddd";
arr = str.split("\\.");//"."在这则表达式中表示任意字符,因此要转义
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
/*
* 如果字符串一开始就匹配到了拆分项时,左侧会拆分出一个空字符串。
* 如果连续匹配上两次拆分项时,中间会拆分出一个空字符串
*/
str = ",aaa,,,bbb,ccc";
arr = str.split(",");
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
/*
* 如果是在字符串末尾连续匹配拆分项,那么所有拆分出来的空字符串都忽略
*/
str = ",aaa,,,bbb,ccc,,,,,,,,,,,,,,,,";
arr = str.split("[,]+");
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
}
}
练习巩固:
截取域名:
public class Test01 {
public static void main(String[] args) {
String name1 = getHostName("http://www.baidu.com");
System.out.println("name1:"+name1);//baidu
String name2 = getHostName("www.tedu.cn");
System.out.println("name2:"+name2);//tedu
String name3 = getHostName("doc.canglaoshi.com.cn");
System.out.println("name3:"+name3);//canglaoshi
}
/**
* 根据给定的网址,返回其中的域名
* @param location 例如:http://www.tedu.cn
* @return 返回的就是location中的域名"tedu"
*/
public static String getHostName(String location) {
//找到开始截取的位置(第一个"."之后第一个字符的位置)
int start = location.indexOf(".")+1;
//找到截取末尾的位置(第二个"."的位置)
int end = location.indexOf(".",start);
return location.substring(start, end);
}
}
检测回文:
public class Test2 {
public static void main(String[] args) {
/*
* 检测一个字符串是否为回文?
* 回文:正着念反着念是一句话
*/
String str = "上海自来水来自海上";
for(int i=0;i
解析参数:
public class Test3 {
public static void main(String[] args) {
String line = "username=张三&age=16&id=&gender=男&salary=5000";
/*
* 控制台:
* 参数名:username
* 参数值:张三
* 参数名:age
* 参数值:16
* ...
*
* 注:某个参数没有值的时候,参数值输出null即可。
*/
//先按照&拆分出每一个参数
String[] arr = line.split("&");
for(int i = 0;i1) {//数组长度>1说明拆分出了两项
System.out.println("参数值:"+data[1]);
}else {//不大于则说明没有参数值
System.out.println("参数值:null");
}
}
}
}
随机生成验证码:
import java.util.Random;
/**
* 生成一个4位验证码
* 验证码可以出现的符为英文字符和数字,英文大小写包括。
*
* 例如,执行程序后输出:
* A3bd
*
*/
public class Test4 {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
for(int i=0;i<26;i++) {
builder.append((char)('a'+i));
builder.append((char)('A'+i));
if(i<10) {
builder.append(i);
}
}
String line = builder.toString();
StringBuilder b = new StringBuilder();
Random random = new Random();
for(int i=0;i<4;i++) {
b.append(line.charAt(random.nextInt(line.length())));
}
System.out.println(b);
}
}
扩展提升所有中国字:
public class Test5 {
public static void main(String[] args) {
//中文在unicode中的范围16进制对应:4e00-9fa5
for(char i='\u4e00',d=1;i<='\u9fa5';i++,d++) {
System.out.print(i);
if(d%20==0) {
System.out.println();
}
}
}
}