Java常用类

🍓String

  • 注意String 已被声明为final

  • String类:代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。

  • 字符串是常量,用双引号引起来表示。它们的值在创建之后不能更改。

  • String对象的字符内容是存储在一个字符数组value[]中的。

⭐String类和常量池

  • String对象的两种创建方式:

    1
    2
    3
    String str1 = "abcd";
    String str2 = new String("abcd");
    System.out.println(str1==str2);//false

👻这两种不同的创建方法是有差别的,第一种方式是在常量池拿对象,第二种方式是直接在内存空间创建一个新的对象

  • 🍅记住:只要使用new方法,便需要创建新的对象。

image-20220724180029199

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); //true
s1 = "hello";
//创建了一个新的值为"hello"的字符串 赋值给s1;
System.out.println(s1 == s2); //false
String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";//常量池中的对象
String str4 = str1 + str2; //在堆上创建的新的对象
String str5 = "string";//常量池中的对象
String str6 = str1+"ing";//在堆上创建的新的对象
System.out.println(str3 == str4);//false
System.out.println(str3 == str5);//true
System.out.println(str4 == str5);//false
System.out.println(str5 == str6);//false
// 只要有变量名参与,就会在堆区new 对象


String str8= str6.intern();
//str6.intern() 返回的是常量池中已经存在的 "string"
System.out.println(str3 == str8); //true

💦结论:

  • 常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
  • 只要其中有一个是变量,结果就在堆中
  • 如果拼接的结果调用intern()方法,返回值就在常量池中

💖String类型的常量池比较特殊。它的主要使用方法有两种:

  • 直接使用双引号声明出来的String对象会直接存储在常量池中。
  • String如果被final修饰, 那么 就是常量
  • 如果不是用双引号声明的String对象,可以使用String提供的intern方String.intern() 是一个Native方法,它的作用是:如果运行时常量池中已经包含一个等于此String对象内容的字符串,则返回常量池中该字符串的引用;如果没有,则在常量池中创建与此 String 内容相同的字符串,并返回常量池中创建的字符串的引用。
1
2
3
4
5
String s1 = new String("s1");
String s2 = new String("s1");
//二者都定义在堆中
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2));//true

image-20220724180035264

❤️注意: String只要是常量形式,都是保存在常量池中。

  • Q: String s= new String (“123”); 方式创建对象,在内存中创建了几个对象?

    A: 2个 ,堆区s + 常量池 “123”; (如果常量池中已经声明过“123” ,则是1个)

🌟String 类型作为参数传递给函数

  • 首先,必须明白java函数的参数传递方式只有值传递
  • 理解String的不可变性。
  • temp_str赋值后,不在指向str指向的那一块内存

image-20220724180043478

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class StringTest2 {
String str = new String("good");
char[] ch = {'t', 'e', 's', 't'};

public void change(String temp_str, char ch[]) {
System.out.println(temp_str == str); //true
temp_str = "testok";
System.out.println(temp_str == str); //false
ch[0] = 'b';
}

public static void main(String[] args) {
StringTest2 ex = new StringTest2();
ex.change(ex.str, ex.ch);
System.out.println(ex.str);
System.out.println(ex.ch);
//good
//best
}
}

🌟String的常用方法

  • int length()返回字符串的长度: return value.length
  • char charAt(int index):返回某索引处的字符return value[index]
  • boolean isEmpty():**判断是否是空字符串:return value.length == 0 **
  • **String toLowerCase():**使用默认语言环境,将 String 中的所有字符转换为小写
  • String toUpperCase()使用默认语言环境,将 String 中的所有字符转换为大写
  • **String trim():**返回字符串的副本,忽略前导空白和尾部空白
  • **boolean equals(Object obj)****:比较字符串的内容是否相同
  • **boolean equalsIgnoreCase(String anotherString):**与equals方法类似,忽略大小写
  • String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
  • **int compareTo(String anotherString):比较两个字符串的大小
  • **String substring(int beginIndex):**返回一个新的字符串,它是此字符串的从beginIndex开始截取到最后的一个子字符串。
  • String substring(int beginIndex, int endIndex) **:**返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。
  • boolean endsWith(String suffix)测试此字符串是否以指定的后缀结束
  • **boolean startsWith(String prefix):**测试此字符串是否以指定的前缀开始
  • **boolean startsWith(String prefix, int toffset)****:测试此字符串从指定索引开始的子字符串是否以指定前缀开始
  • **boolean contains(CharSequence s):**当且仅当此字符串包含指定的 char 值序列时,返回 true
  • int indexOf(String str)返回指定子字符串在此字符串中第一次出现处的索引
  • **int indexOf(String str, int fromIndex):**返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始
  • int lastIndexOf(String str)返回指定子字符串在此字符串中最右边出现处的索引
  • int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
  • 注:indexOf和lastIndexOf方法如果未找到都是返回-1
  • String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
  • String replace(CharSequence target, CharSequence replacement):**使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。 **

🌟涉及正则表达式的String Method

  • String replaceAll(String regex, String replacement) 使 用 给 定 的replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
  • String replaceFirst(String regex, String replacement) 使 用 给 定 的replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
  • boolean matches(String regex):**告知此字符串是否匹配给定的正则表达式。 **
  • String[] split(String regex):**根据给定正则表达式的匹配拆分此字符串。 **
  • String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package pers.dhx_.java0603;

import java.util.Locale;

/**
* @author Dhx_
* @className StringMethodTest1
* @description TODO
* @date 2022/6/4 17:02
*  int length():返回字符串的长度: return value.length
*  char charAt(int index): 返回某索引处的字符return value[index]  boolean isEmpty():判断是否是空字符串:return value.length == 0  String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
*  String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
*  String trim():返回字符串的副本,忽略前导空白和尾部空白
*  boolean equals(Object obj):比较字符串的内容是否相同
*  boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
*  String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
*  int compareTo(String anotherString):比较两个字符串的大小
*  String substring(int beginIndex):返回一个新的字符串,它是此字符串的从
* beginIndex开始截取到最后的一个子字符串。  String substring(int beginIndex, int endIndex) :
* 返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。 左开右闭
*/
public class StringMethodTest1 {
public static void main(String[] args) {
System.out.println("--------------------------------------");
String s1 = " HelloWorld ";

System.out.println(s1.length());
System.out.println(s1.charAt(6));
System.out.println(s1.toUpperCase(Locale.ROOT)); //s1 是不可变的,仍然为原来的字符串
System.out.println(s1);
System.out.println(s1.isEmpty());
System.out.println(s1.toLowerCase(Locale.ROOT));
System.out.println(s1);
System.out.println(s1.trim()); //返回字符串的副本,忽略前导空白和尾部空白
String s2 = s1.concat("s1.concat()");
System.out.println(s1);
System.out.println(s2);
System.out.println(s1.equals("helloworld"));
String temp = " helloWorld ";
System.out.println(s1.equals(temp)); //false
System.out.println(s1.equalsIgnoreCase(temp)); //true

String str1 = "abc";
String str2 = "bbc";
System.out.println(str1.compareTo(str2)); //-1 小于
str1 = "cbc";
String test = new String("董浩昕牛逼");
System.out.println(test.substring(3));
System.out.println(str1.compareTo(str2)); // 1 大于

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package pers.dhx_.java0603;

/**
* @author Dhx_
* @className StringMethodTest
* @description TODO
* @date 2022/6/5 11:14
*/
public class StringMethodTest {
public static void main(String[] args) {
String str1 = "helloworld";
System.out.println(str1.endsWith("rld"));
System.out.println(str1.startsWith("he"));
System.out.println(str1.startsWith("He")); //区分大小写
System.out.println(str1.indexOf("ll"));
str1 = "ldldld";
str1 = str1.replace("ld", "lldll"); //全部替换
System.out.println(str1);
System.out.println(str1.lastIndexOf("ll"));
System.out.println(str1.lastIndexOf("llda")); //找不到返回-1
String str = "12345";
//判断str字符串中是否全部有数字组成,即有1-n个数字组成
boolean matches = str.matches("\\d+");
System.out.println(matches);
String tel = "0571-4534289";
//判断这是否是一个杭州的固定电话
boolean result = tel.matches("0571-\\d{7,8}"); //七位或八位数字
System.out.println(result);
}
}

🎧String与基本数据类型转换

字符串 —>基本数据类型、包装类

  • Integer.parselent(String s);
  • 类似地,使用java.lang包中的Byte、Short、Long、Float、Double类调相应的类方法可以将由“数字”字符组成的字符串,转化为相应的基本数据类型

基本数据类型、包装类 —>字符串

  • 调用String类的public String **valueOf(int n)**可将int型转换为字符串相应的valueOf(byte b)、valueOf(long l)、valueOf(float f)、valueOf(double d)、valueOf(boolean b)可由参数的相应类型到字符串的转换

String与字符数组转换

  • 字符数组 -->字符串

    1. String 类的构造器:String(char[]) String(char[],int offset,int length)分别用字符数组中的全部字符和部分字符创建字符串对象。
  • 字符串 -->字符数组

    1. public char[] toCharArray()将字符串中的全部字符存放在一个字符数组中的方法。
    2. public void getChars(int srcBegin, int srcEnd, char[] dst,int dstBegin):提供了将指定索引范围内的字符串存放到数组中的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package pers.dhx_.java0603;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
* @author Dhx_
* @className StringChangeTest
* @description TODO
* 编码:字符串----> 字节 (看得懂 --->看不懂)
* 解码编码的逆过程 字节----->字符串等 (看不懂---->看得懂)
* charsetname : 字符集名称
* @date 2022/6/5 13:31
*/
public class StringChangeTest {
public static void main(String[] args) {
String s1 = "我是123";
byte[] test = s1.getBytes();// 使用默认的字符集
byte[] gbks = null;
try {
gbks = s1.getBytes("gbk"); //使用gbk 字符集编码
System.out.println(Arrays.toString(gbks));//gbk 中 一个中文字符占两个字节

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

System.out.println(Arrays.toString(test));
byte[] b = new byte[]{-26, -120, -111, -67, 56, 61, 65, -76, 53, 88};
byte[] a = new byte[]{-26, -120, -111, -26, -104, -81, 49, 50, 51};


String bytE = new String(b); //默认还是utf-8
System.out.println(bytE);
System.out.println(new String(a));
try {
System.out.println(new String(gbks, "gbk"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

//[-26, -120, -111, -26, -104, -81, 49, 50, 51]
//utf-8中 一个中文字符占三个字节
}
}


🐭StringBuffer 、StringBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  package pers.dhx_.java0603;

/**
* @author Dhx_
* @className StringBufferBuilderTest
* @description TODO String StringBuffet StringBUilder 区别
* @date 2022/6/5 14:01
* STirng : 不可变的字符序列
* StringBuffer: 线程安全,可变的字符序列,
* StringBuilder: JDK5.0新增因为StringBuffer效率低 ,线程不安全,效率较高, 可变的字符序列
*/
public class StringBufferBuilderTest {
public static void main(String[] args) {
StringBuffer sb1 = new StringBuffer("abcfgeshwgsabcfgeshwgsrehrthhtrrehrthhtr");
System.out.println(sb1.length());
System.out.println(new StringBuffer().length()); //0 不是value.length()
//底层:new char[]=new char["abc".length+16];
//每次new完都会空出来额外的16个字符位置
//扩容的问题 ;如果添加的数据 底层装不下了,需要扩容底层的数组
//默认情况下,扩容为 size*2+2 ,同时将原先的内容复制到新的数组中
//指导意义,开发中尽可能减少 复制 ,可以使用 StringBuffer(int capacity), 先设定好容量
sb1.setCharAt(0, '6');
//void 不像String ,会返回被改变后的 ,StringBuffer是直接改变本身
}
}

🐘StringBuffer常用方法

很类似于C++的string类,注意start,end 区间都是左闭右开怕[ begin,end),

StringBuilder的方法与其相同。

  • StringBuffer append(String str):提供了很多的append()方法,用于进行字符串拼接

  • StringBuffer delete(int start,int end):删除指定位置的内容

  • StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str

  • StringBuffer insert(int offset, xxx):在指定位置插入xxx

  • StringBuffer reverse() :把当前字符序列逆转

    1
    2
    3
    4
    5
    public int indexOf(String str)
    public String substring(int start,int end)
    public int length()
    public char charAt(int n )
    public void setCharAt(int n ,char ch)

🐶三者效率对比

  • String(JDK1.0):不可变字符序列

  • StringBuffer(JDK1.0):可变字符序列、效率低、线程安

  • StringBuilder(JDK 5.0):可变字符序列、效率高、线程不安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//初始设置
long startTime = 0L;
long endTime = 0L;
String text = "";
StringBuffer buffer = new StringBuffer("");
StringBuilder builder = new StringBuilder("");
//开始对比
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
buffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
builder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < 20000; i++) {
text = text + i; }
endTime = System.currentTimeMillis();
System.out.println("String的执行时间:" + (endTime - startTime));
//StringBuffer的执行时间:3
//StringBuilder的执行时间:1
//String的执行时间:188

🌑时间API


image-20220724180056540

🐆JDK8.0之前

🎈java.lang.System类

  • System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
  • 此方法适于计算时间差。
  • 计算世界时间的主要标准有:
    1. UTC(Coordinated Universal Time)
    2. GMT(Greenwich Mean Time)
    3. CST(Central Standard Time)

🎈java.util.Date类

  • 表示特定的瞬间,精确到毫秒
  • 很多方法已经是过时的了(@Deprecated) ,不建议去用了
  • 构造器:
  1. Date():使用无参构造器创建的对象可以获取本地当前时间。
  2. Date(long date)
  • 常用方法
    1. getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
    2. **toString()😗*把此 Date 对象转换为以下形式的 String: dow mon ddhh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat),zzz是时间标准。
    3. 其它很多方法都过时了。

🎈java.text.SimpleDateFormat类

  • Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat类是一个不与语言环境有关的方式来格式化和解析日期的具体类。
  • 它允许进行
  1. 格式化:日期—>文本、
  2. 解析:文本—>日期
  • 格式化:
  1. SimpleDateFormat() :默认的模式和语言环境创建对象
  2. public SimpleDateFormat(String pattern)该构造方法可以用参数pattern指定的格式创建一个对象,该对象调用:
  3. public String format(Date date):方法格式化时间对象date
  • 解析:
  1. **public Date parse(String source)**从给定字符串的开始解析文本,以生成一个日期。

🎈java.util.Calendar(日历)类

  • Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能。

  • 获取Calendar实例的方法

    1. 使用Calendar.getInstance()方法
    2. 调用它的子类GregorianCalendar的构造器。
  • 一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、MINUTE、SECOND

    1. public void set(int field,int value)
    2. public void add(int field,int amount)
    3. public final Date getTime()
    4. public final void setTime(Date date)
  • 注意:

    1. 获取月份时:一月是0,二月是1,以此类推,12月是11
    2. 获取星期时:周日是1,周二是2 …周六是7

⭐✡️🌟获取两个字符串中最大相同子串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package pers.dhx_.java0604;
/**
* @author Dhx_
* @className StringDemo
* @description TODO获取两个字符串中的 最大相同子串
* 获取两个字符串中最大相同子串。比如:
* str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"
* 提示:将短的那个串进行长度依次递减的子串与较长的串比较。
* @date 2022/6/5 18:59
*/
public class StringDemo {
public static void main(String[] args) {
String s1 = new String("abcwerthellodbnmmeryuiodef");
String s2 = new String("cvhellohg6nmmer");
// TODO 测试StringBuffer 直接赋值为null ,是否可以apped
//结果 : 不可以 null 的StringBuffer即使append ,依然为null;
// StringBuffer temp = new StringBuffer("");
// temp.append("123");
// System.out.println(temp);
System.out.println(solve2(s1, s2)[0]);
System.out.println(solve2(s1, s2)[1]);

}

static String solve(String s1, String s2) {
String bigger = (s1.length() >= s2.length() ? s1 : s2);
String shorter = (s1.length() < s2.length() ? s1 : s2);
int length = shorter.length();
for (int i = 0; i < shorter.length(); i++) {
//用长的去比,每一次循环 子串的长度越来越短 ,因此返回的必定是最长的子串
//abcwerthelloyuiodef
//cvhellobnm
//cvhellob -->vhellobn--->hellobnm
for (int x = 0, y = length - i; y <= length; x++, y++) {
String temp = shorter.substring(x, y);
if (bigger.contains(temp))
return temp;
}
}
return null; //一个相同的字符都没有
}

static String[] solve2(String s1, String s2) { //解决有 多个长度相同的子串的问题
//使用StringBuffer + 正则匹配 ,获取数组
StringBuffer result = new StringBuffer("");
String bigger = (s1.length() >= s2.length() ? s1 : s2);
String shorter = (s1.length() < s2.length() ? s1 : s2);
int length = shorter.length();
for (int i = 0; i < shorter.length(); i++) {
//用长的去比,每一次循环 子串的长度越来越短 ,因此返回的必定是最长的子串
//abcwerthelloyuiodef
//cvhellobnm
//cvhellob -->vhellobn--->hellobnm
for (int x = 0, y = length - i; y <= length; x++, y++) {
String temp = shorter.substring(x, y);
if (bigger.contains(temp))
result.append(temp + ",");
}
if (result.length() != 0) { //匹配到子串, 正则切割
//replaceAll 把结尾的 ","删去
String x = result.substring(0, result.length() - 1);
// String[] split = result.toString()..split("\\,");
String[] split = x.replaceAll(",$", "").split("\\,");
return split;
}
}
return null;
}
}

🙉StringBuffer.append() 空字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package pers.dhx_.java0606;

/**
* @author Dhx_
* @className IDEadebug
* @description TODO
* @date 2022/6/6 7:46
*/
public class IDEdebug {
public static void main(String[] args) {
String s = null;
StringBuffer ide = new StringBuffer();
ide.append(s); //append ("null")
System.out.println(ide.length()); //4
System.out.println(ide); //"null"
StringBuffer sb = new StringBuffer(s); //NullPointerException
/* 源代码
private AbstractStringBuilder appendNull() {
ensureCapacityInternal(count + 4);
int count = this.count;
byte[] val = this.value;
if (isLatin1()) {
val[count++] = 'n';
val[count++] = 'u';
val[count++] = 'l';
val[count++] = 'l';
} else {
count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');
}
this.count = count;
return this;
}
*/
}
}