目录
StringBuffer and StringBuilder
String类
java.lang.String
-
String,引用数据类型。字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。
例如:
String str = "abc";
等效于:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
-
在JDK当中双引号括起来的字符串,例如“abc”都是直接存储在方法区的“字符串常量池”当中的。(为什么?因为字符串在实际开发中使用频繁,为了执行效率)
String s1 = “abcdef“”; String s2 = “abcdef” + “xy”; 底层创建了三层个对象。
String s3 = new String("xy");
思考:String s1 = "hello"; String s2 = "hello"; String s3 = new String("hello");
s1 == s2 //true; s1 == s3 //false;
class TEXT{
public int num;
public String str;
public TEXT(int num, String str){
this.num = num;
this.str = str;
}
}
public class Class4 {
//tIn是传对象的地址,修改形参的属性,会影响实参
//intIn是传数据,基本数据类型的形参修改和实参无关
//Integer和String对象不可变
public static void f1(TEXT tIn, int intIn, Integer integerIn, String strIn){
tIn.num =200;
tIn.str = "bcd";//形参和实参指向的是同一个TEXT的对象,修改了属性,就相当于修改实参对象的属性
intIn = 200;//基本数据类型的形参是实参的“副本”,无论怎么修改和实参都没关系
integerIn = 200;//Integer对象和String对象一样都是不可变,一旦修改都是新对象,和实参无关
strIn = "bcd";
}
public static void main(String[] args) {
TEXT tIn = new TEXT(100, "abc");//tIn.num = 100, tIn.str="abc"
int intIn = 100;
Integer integerIn = 100;
String strIn = "abc";
f1(tIn,intIn,integerIn,strIn);
System.out.println(tIn.num + tIn.str + intIn + integerIn + strIn);
//200 + bcd + 100 + 100 + abc
}
}
- 常用方法
构造方法(constructor)
|
|
String类方法(methods)
- 掌握
char | charAt(int index) 返回指定索引处的 char 值。 |
char[] | toCharArray() 将此字符串转换为一个新的字符数组。 |
String |
|
String |
|
String | replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 |
String | replaceFirst(String regex, String replacement) 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 |
boolean | matches(String regex) (整体匹配) 告知此字符串是否匹配给定的正则表达式。 |
String[] | split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串。 |
String | trim() 返回字符串的副本,忽略前导空白和尾部空白。 |
String |
|
int |
|
boolean | contains(CharSequence s) 底层调用indexOf 当且仅当此字符串包含指定的 char 值序列时,返回 true。 |
boolean |
|
boolean | isEmpty() 可用length()方法替代。 当且仅当 length() 为 0 时返回 true。 |
int | length() 注:数组长度是Length属性,字符串长度是Length()方法。返回此字符串的长度。 |
了解↓ | |
static String |
|
int | compareTo(String anotherString) 按字典顺序比较两个字符串。 |
String | concat(String str) 将指定字符串连接到此字符串的结尾。 |
boolean |
|
byte[] | getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
static String | copyValueOf(char[] data) 返回指定数组中表示该字符序列的 String。 |
static String | copyValueOf(char[] data, int offset, int count) 返回指定数组中表示该字符序列的 String。 |
String | intern() 保证字符串常量池一定有该字符串 返回字符串对象的规范化表示形式。 |
byte[] | getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
//字节码转换
String s2 = "abc";
byte[] bytes = s2.getBytes();
String s = new String(bytes,"UTF-8");
System.out.println(s);
String |
|
String c = "http://www.baidu.com/";
System.out.println(c.replace("http","https")); //https://www.baidu.com/
String[] | split(String regex) 根据给定正则表达式的匹配拆分此字符串。 |
String c = "1998-8-24"; //
String[] s = c.split("-");
for (int i = 0; i < s.length; i++) {
System.out.print(s[i]+","); //1998,8,24,
- 练习:
1.截取文件名
public void test02(){
String fileName = "快速学习Java的秘诀.dat";
//截取文件名
System.out.println("文件名:" + fileName.substring(0,fileName.lastIndexOf(".")));
//截取后缀名
System.out.println("后缀名:" + fileName.substring(fileName.lastIndexOf(".")));
}
2、编写程序:替换字符串中的指定字符串
ststic public String replace(String text,String subtext,String replace)
示例:replace(“aabbccbb”, “bb”, “dd”); 结果:aaddccdd
注意:不能使用String及StringBuffer等类的replace等现成的替换API方法。
*/
public static void main(String[] args) {
System.out.println(replace("aabbcbcbb", "bb", "dd"));
}
public static String replace(String text, String target, String replace) {
while (true) {
int index = text.indexOf(target);
if (index != -1) {
//替换
text = text.substring(0, index) + replace + text.substring(index + target.length());
} else {
break;
}
}
return text;
}
正则表达式(matches)
java.util.regex.Matcher
boolean matches(正则表达式):判断当前字符串是否匹配某个正则表达式
字符类
[abc]
:a
、b
或 c
(简单类)
[^abc]
:任何字符,除了 a
、b
或 c
(否定)
[a-zA-Z]
:a
到 z
或 A
到 Z
,两头的字母包括在内(范围)
预定义字符类
.
:任何字符(与行结束符可能匹配也可能不匹配)
\d
:数字:[0-9]
\D
:非数字: [^0-9]
\s
:空白字符:[ \t\n\x0B\f\r]
\S
:非空白字符:[^\s]
\w
:单词字符:[a-zA-Z_0-9]
\W
:非单词字符:[^\w]
POSIX 字符类(仅 US-ASCII)
\p{Lower}
小写字母字符:[a-z]
\p{Upper}
大写字母字符:[A-Z]
\p{ASCII}
所有 ASCII:[\x00-\x7F]
\p{Alpha}
字母字符:[\p{Lower}\p{Upper}]
\p{Digit}
十进制数字:[0-9]
\p{Alnum}
字母数字字符:[\p{Alpha}\p{Digit}]
\p{Punct}
标点符号:!"#$%&'()*+,-./:;<=>?@[]^_`{|}~
\p{Blank}
空格或制表符:[ \t]
边界匹配器
^
:行的开头
$
:行的结尾
Greedy 数量词
X?
:X,一次或一次也没有
X*
:X,零次或多次
X+
:X,一次或多次
X{
n}
:X,恰好 n 次
X{
n,}
:X,至少 n 次
X{
n,
m}
:X,至少 n 次,但是不超过 m 次
Logical 运算符
XY:X 后跟 Y
X|
Y:X 或 Y
(
X)
:X,作为捕获组
特殊构造(非捕获)
(?:X) X,作为非捕获组
(?=X) X,通过零宽度的正 lookahead
(?!X) X,通过零宽度的负 lookahead
(?<=X) X,通过零宽度的正 lookbehind
(?<!X) X,通过零宽度的负 lookbehind
(?>X) X,作为独立的非捕获组
@Test
public void test1(){
//简单判断是否全部是数字,这个数字可以是1~n位
String str = "12a345";
//正则不是Java的语法,它是独立与Java的规则
//在正则中\是表示转义,
//同时在Java中\也是转义
boolean flag = str.matches("\\d+");
System.out.println(flag);
}
@Test
public void test2(){
String str = "123456789";
//判断它是否全部由数字组成,并且第1位不能是0,长度为9位
//第一位不能是0,那么数字[1-9]
//接下来8位的数字,那么[0-9]{8}+
boolean flag = str.matches("[1-9][0-9]{8}+");
System.out.println(flag);
}
@Test
public void test03(){
//密码要求:必须有大写字母,小写字母,数字组成,6位
System.out.println("Cly892".matches("^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[A-Za-z0-9]{6}$"));//true
System.out.println("1A2c45".matches("^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[A-Za-z0-9]{6}$"));//true
System.out.println("Clyyyy".matches("^(?=.*[A-Z])(?=.*[0-9])[A-Za-z0-9]{6}$"));//false
}
1.验证用户名和密码,要求第一个字必须为字母,一共6~16位字母数字下划线组成:(^[a-zA-Z]\w{5,15}$)
2.验证电话号码:xxx/xxxx-xxxxxxx/xxxxxxxx:(^(\d{3,4}-)\d{7,8}$)
3.验证手机号码:( ^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ )
4.验证身份证号: (^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
5.验证Email地址:(^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$)
6.只能输入由数字和26个英文字母组成的字符串:(^[A-Za-z0-9]+$)
7.整数或者小数:(^[0-9]+(.[0-9]+){0,1}$)
8.中文字符的正则表达式:([\u4e00-\u9fa5])
9.金额校验(非零开头的最多带两位小数的数字):(^([1-9][0-9]*)+(.[0-9]{1,2})?$)
10.IPV4地址:(((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5])
String replace(xx,xx):不支持正则
String replaceFirst(正则,value):替换第一个匹配部分
String repalceAll(正则, value):替换所有匹配部分
String[] split(正则):按照某种规则进行拆分
StringBuffer and StringBuilder
java.lang.StringBuilder|Buffer
Java中的字符串是不可变的,每一次拼接都会产生新的字符串。
但这样会占用大量的方法区内存,造成内存空间的浪费,给字符串常量池造成很大压力。
-
在创建StringBuffer时,尽可能给定一个初始化容量(预估),减少底层数组扩容次数。
-
StringBuffer拼接字符串使用append方法。
-
new StringBuffer时默认创建初始化容量为16的byte[] 数组。
-
String 的方法与 StringBuilder 大部分相同。
public static void main(String[] args) {
//创建一个默认初始化容量为16的byte[]数组。(字符串缓冲区对象)
StringBuffer sb = new StringBuffer();
int a = 10;
//拼接字符串,调用append方法
sb.append("a"+12+a);
sb.append(100l);
sb.append(3.14);
sb.append(true);
System.out.println(sb); //a12101003.14true
//如果append方法在进行追加时byte[]数组满了,会自动调用"arraycopy();数组拷贝"进行扩容。
}
StringBuilder 的初始化与方法和 StringBuffer相同。
- StringBuffer 和 StringBuilder的区别。
StringBuffer 中的方法都有 synchronized关键字修饰,表示在多线程环境下运行是安全的。
StringBuilder 没有,在多线程环境下运行是不安全的。
- 常用方法:
StringBuffer | append(char[] str, int offset, int len) 将 |
StringBuffer | append(Object obj) 追加 |
StringBuffer | insert(int offset, Object obj) 将 |
StringBuffer | delete(int start, int end) 删除此序列的子字符串中的字符。 |
StringBuffer | deleteCharAt(int index) 删除 |
char | charAt(int index) 返回 |
StringBuffer | reverse() 导致该字符序列被序列的相反代替。 |
void | setLength(int newLength) 设置字符序列的长度。 |
StringBuffer | replace(int start, int end, String str) 用指定的String中的字符替换此序列的子字符串中的 |
int | indexOf(String str) 返回指定子字符串第一次出现的字符串内的索引。 |
int | indexOf(String str, int fromIndex) 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。 |
int | lastIndexOf(String str) 返回指定子字符串最右边出现的字符串内的索引。 |
int | lastIndexOf(String str, int fromIndex) 返回指定子字符串最后一次出现的字符串中的索引。 |
CharSequence | subSequence(int start, int end) 返回一个新的字符序列,该序列是该序列的子序列。 |
String | substring(int start) 返回一个新的 |
String | substring(int start, int end) 返回一个新的 |
String | toString() 返回表示此顺序中的数据的字符串。 |
void | setCharAt(int index, char ch) 指定索引处的字符设置为 |
包装类(Wrapper Class)
java.lang.Number
-
Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。基本类型的数据不具备"对象"的特性(没有成员变量和成员方法可以调用),因此,java为8种数据类型分别设计了对应的类,即包装类。
-
八种包装类中,6个都是数字对应的包装类,他们的父类都是Number,所对应的拆箱方法也为Number类中的方法。Number 是一个抽象类,无法实例化对象。
基本数据类型 | 对应的包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
floar | Float |
double | Double |
boolean | Boolean |
装箱:将基本数据类型变为包装类对象。 valueOf();
拆箱:将包装类中包装的基本数据类型取出。 byteValue();
包装类 | 装箱 | 拆箱 |
---|---|---|
Byte | valueOf() | byteValue() |
Short | valueOf() | shortValue() |
Integer | valueOf() | intValue() |
Long | valueOf() | longValue() |
Float | valueOf() | floatValue() |
Double | valueOf() | doubleValue() |
Character | valueOf() | charValue() |
Boolean | valueOf() | booleanValue() |
- 三种类型互相转换
- Integer方法
static int |
MIN_VALUE 值为 -231 的常量,它表示 int 类型能够表示的最小值。 |
static int | parseInt(String s) 将字符串参数作为有符号的十进制(int)整数进行解析。 |
static Integer | valueOf(String s) 返回保存指定的 String 的值的 Integer 对象。 |
System.out.println(Byte.MAX_VALUE); //127
System.out.println(Byte.MIN_VALUE); //-128
int a = Integer.parseInt("100");
- 自动装箱、拆箱
JDK1.5之后,支持自动拆箱和自动装箱。
Integer x =100 ; //自动装箱
int y = x ; //自动拆箱
- 包装类缓存分析
Java中为了提高程序执行效率,将[-128到127]之间的包装类提前创建好, 放到了一个方法区的"整数型常量池中",目的是只要使用这个去加你的数据 不需要再new了,直接从整数型常量池中取出来。 池:cache,就是缓存机制
包装类 | 缓存对象 |
---|---|
Byte | -128~127 |
Short | -128~127 |
Integer | -128~127 |
Long | -128~127 |
Float | 没有 |
Double | 没有 |
Character | 0~127 |
Boolean | true和false |
public static Integer valueOf(int i) {
assert IntegerCache.high>= 127;
if (i >= IntegerCache.low&& i <= IntegerCache.high)
return IntegerCache.cache[i+ (-IntegerCache.low)];
return new Integer(i);
}
@Test
public void test1() {
Integer i1 = 10;//取出缓存了10对应的包装类对象
Integer i2 = 10;//取出缓存了10对应的包装类对象
System.out.println(i1 == i2);//? true 说明i1和i2是同一个对象
Integer i3 = new Integer(20);
Integer i4 = new Integer(20);
System.out.println(i3 == i4);//false
Integer i5 = 200;//超过缓存对象的范围,新创建对象
Integer i6 = 200;//超过缓存对象的范围,新创建对象
System.out.println(i5 == i6);//false
}
public static void main(String[] args){
//原理:x变量中保存的对象的内存地址,和y变量中保存的内存地址是一样的。
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true重写了equals方法,比较的内容
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);//false
System.out.println(i3.equals(i4));//true
Integer i5 = 128;
Integer i6 = 128;
System.out.println(i5 == i6);//false
System.out.println(i5.equals(i6));//true
Integer i7 = 127;
Integer i8 = 127;
System.out.println(i7 == i8);//true
System.out.println(i7.equals(i8));//true
}
系统相关类 (System)
java.lang.System
tatic void | arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。 |
static long | currentTimeMillis() 返回以毫秒为单位的当前时间。 |
static void | exit(int status) 终止当前正在运行的 Java 虚拟机。 |
static void | gc() 运行垃圾回收器。 |
static String | getProperty(String key) 获取指定键指示的系统属性。 |
static Properties | getProperties() 确定当前的系统属性。 |
- arraycopy
//mone 移动数组
public static void move(int[] arr) {
int temp = arr[arr.length-1];
System.arraycopy(arr,0,arr,1,arr.length-1);
arr[0] = temp;
}
//[9, 0, 1, 2, 3, 4, 5, 6, 7, 8]
//[8, 9, 0, 1, 2, 3, 4, 5, 6, 7]
//删除数组的的3
int[] arr = {1,2,3,4,5,6,7,8}; //从下标3开始复制,到2位置,
System.arraycopy(arr,3,arr,2,5);
int[] ints = Arrays.copyOf(arr, 7); //返回新数组,元素数为7
for (int i = 0; i < ints.length; i++) {
System.out.print(ints[i]+" "); //1 2 4 5 6 7 8
}
- currentTimeMillis
public static void main(String[] args) {
//获取昨天的此时的时间
Date time2 = new Date(System.currentTimeMillis() - 1000*60*60*24);
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
String strTime2 = sdf.format(time2);
//北京是东8区
System.out.println(strTime2); //2021-12-30 16:50:47 679
}
public static void main(String[] args){
//需求:统计一个方法执行所耗费的时长
//在调用目标方法前记录一个毫秒数
long begin = System.currentTimeMillis();
print();
//在调用目标方法后记录一个毫秒数
long end = System.currentTimeMillis();
System.out.println("耗费时长 = "+(end-begin)); //耗费时长 = 31
}
public static void print(){
for (int i = 0; i < 1000; i++) {
System.out.println("i = "+i); //打印增加了时长
}
}
Runtime类
java.lang.Runtime
每个 Java 应用程序都有一个 Runtime
类实例,使应用程序能够与其运行的环境相连接。可以通过 getRuntime
方法获取当前运行时。 应用程序不能创建自己的 Runtime 类实例。
static Runtime | getRuntime() 返回与当前 Java 应用程序相关的运行时对象。 |
long | totalMemory() 返回 Java 虚拟机中的内存总量。 |
long | freeMemory() 返回 Java 虚拟机中的空闲内存量。 |
long | maxMemory() 返回 Java 虚拟机试图使用的最大内存量。 |
Process | exec(String command) //CMD中的命令 配置环境 在单独的进程中执行指定的字符串命令。 |
void | gc() 运行垃圾回收器。 |
int[] arr = new int[1024 * 1024 * 512];//2G
// public long totalMemory():返回 Java 虚拟机中的内存总量。此方法返回的值可能随时间的推移而变化,这取决于主机环境。
long totalMemory = rt.totalMemory();
System.out.println("totalMemory = " + totalMemory);
//public long freeMemory():回 Java 虚拟机中的空闲内存量。调用 gc 方法可能导致 freeMemory 返回值的增加。
long freeMemory = rt.freeMemory();
System.out.println("freeMemory = " + freeMemory);
//public long maxMemory(): 返回 Java 虚拟机试图使用的最大内存量。
long maxMemory = rt.maxMemory();
System.out.println("maxMemory = " + maxMemory);
}
@Test
public void test3() throws IOException {
Runtime rt = Runtime.getRuntime();
// rt.exec("notepad");
// rt.exec("calc");
// rt.exec("mspaint");
rt.exec("QQ");
}