Java系列文章目录
补充内容 Windows通过SSH连接Linux
第一章 Linux基本命令的学习与Linux历史
文章目录
- Java系列文章目录
- 一、前言
- 二、学习内容:
- 三、问题描述
- 四、解决方案:
- 4.1 代码学习与性能测试
- 4.1.1 代码
- 4.1.2 性能测试结果
- 4.2 区别
- 五、总结:
- 5.1 使用场景
- 5.2 关联记忆方法
一、前言
- 面试中可能会遇到这个问题,实操加深印象
二、学习内容:
- 学习
String
,StringBuffer
与StringBuilder
包含实操与理论面试
三、问题描述
- 这三个的使用方法与区别
- 使用场景
四、解决方案:
4.1 代码学习与性能测试
4.1.1 代码
- 这三个常用方法学习
可手动写试试效果
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 字符串操作演示类,展示Java中字符串的各种操作方法
*/
public class Main {
/**
* 程序入口
* @param args 命令行参数
*/
public static void main(String[] args) {
// 演示正则表达式和字符串分割
demonstrateRegexAndSplitting();
// 演示字符串操作
demonstrateStringManipulations();
// 演示StringBuffer操作
demonstrateStringBufferOperations();
// 演示StringBuilder性能
demonstrateStringBuilderPerformance();
}
/**
* 演示正则表达式和字符串分割的用法
*/
private static void demonstrateRegexAndSplitting() {
// 使用正则表达式匹配字母和数字
Matcher matcher = Pattern.compile("[a-zA-Z0-9]").matcher("www.1000phone.com");
// 检查字符串是否完全匹配字母和数字
String str1 = "www.1000phone.com";
boolean matches = str1.matches("[a-zA-Z0-9]");
System.out.println(matches);
// 替换字符串中第一个出现的0为1
System.out.println(str1.replaceFirst("0", "1"));
// 将字符串中的%替换为1
System.out.println(str1.replaceAll("%", "1"));
// 字符串分割演示
String str2 = "192.168.1.2.1";
printSplitResults(str2, "\\.", -2);
printSplitResults(str2, "\\.", -5);
printSplitResults(str2, "\\.", 4);
printSplitResults(str2, "\\.", 5);
}
/**
* 打印字符串分割结果
* @param str 待分割的字符串
* @param delimiter 分割符
* @param limit 分割结果限制,如果为负数,则不限制结果数量
*/
private static void printSplitResults(String str, String delimiter, int limit) {
String[] splitArray = str.split(delimiter, limit);
for (String s : splitArray) {
System.out.println("[" + s + "]");
}
System.out.println("===============");
}
/**
* 演示字符串的基本操作,包括截取、大小写转换等
*/
private static void demonstrateStringManipulations() {
String str = " 1000ohone.com";
// 去除字符串两端的空白字符
System.out.println(str.trim());
// 获取字符串的子字符串,从索引4开始到结尾
System.out.println(str.substring(4));
// 获取字符串的子字符串,从索引4开始到索引7结束
System.out.println(str.substring(4, 7));
// 将字符串转换为大写
System.out.println(str.toUpperCase());
// 将字符串转换为小写
System.out.println(str.toLowerCase());
// 分割线
System.out.println("=======1000ohone.com=========");
}
/**
* 演示StringBuffer的操作,包括追加、删除、插入和反转字符串
*/
private static void demonstrateStringBufferOperations() {
StringBuffer sb = new StringBuffer();
// 追加字符串
sb.append("Hello").append(" world");
// 打印追加后的字符串
System.out.println(sb);
// 删除字符串中索引5到6之间的字符
sb.delete(5, 6);
System.out.println("字符串删除" + sb);
// 在索引5处插入字符's'
sb.insert(5, "s");
System.out.println("字符串插入" + sb);
// 反转字符串
sb.reverse();
System.out.println("字符串反转" + sb);
// 分割线
System.out.println("========StringBuffer========");
}
/**
* 演示StringBuilder的性能,对比字符串直接拼接的方式
*/
private static void demonstrateStringBuilderPerformance() {
// 测量字符串直接拼接的性能
long startTime = System.currentTimeMillis();
String string = "";
for (int i = 0; i < 50000; i++) {
string += i;
}
long endTime = System.currentTimeMillis();
System.out.println("执行时间" + (endTime - startTime) + "毫秒");
// 测量StringBuilder拼接的性能
startTime = System.currentTimeMillis();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 50000; i++) {
builder.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("builder执行时间" + (endTime - startTime) + "毫秒");
// 测量StringBuffer拼接的性能
startTime = System.currentTimeMillis();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 50000; i++) {
buffer.append(i);
}
endTime = System.currentTimeMillis();
System.out.println("buffer执行时间" + (endTime - startTime) + "毫秒");
// 分割线
System.out.println("========性能比较========");
}
/**
* 生成具有指定属性的类代码
* @param className 生成的类名
* @param properties 属性列表,每个属性由类型和名称组成,用冒号分隔
*/
private static void generate(String className, String... properties) {
String voClassName = className + "VO";
StringBuilder sb = new StringBuilder();
// 生成类定义和属性以及getter和setter方法
sb.append("public class ").append(voClassName).append("{\n");
for (String property : properties) {
String[] parts = property.split(":");
String type = parts[0];
String name = parts[1];
sb.append("\tprivate ").append(type).append(" ").append(name).append(";\n");
sb.append("\tpublic void set").append(capitalize(name)).append("(").append(type).append(" ").append(name).append(") {\n");
sb.append("\t\tthis.").append(name).append(" = ").append(name).append(";\n");
sb.append("\t}\n");
sb.append("\tpublic ").append(type).append(" get").append(capitalize(name)).append("() {\n");
sb.append("\t\treturn this.").append(name).append(";\n");
sb.append("\t}\n");
}
// 打印生成的类代码
System.out.println(sb.toString());
}
/**
* 将字符串的第一个字符转换为大写
* @param str 待转换的字符串
* @return 转换后的字符串
*/
private static String capitalize(String str) {
if (str == null || str.isEmpty()) {
return str;
}
// 返回转换后的字符串
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}
4.1.2 性能测试结果
⭐️ 可以看到相同条件下StringBuilder
效率更高
结果不一定可能受其他因素影响,但相同条件StringBuilder效率更高是可以确定的
4.2 区别
StringBuffer
和StringBuilder
的区别:
-
可变性:
StringBuffer
和StringBuilder
对象的值是可以被修改的String
对象的值是不可修改的所以也是线程安全。
-
线程安全性:
StringBuffer
几乎所有的方法都使用synchronized
实现了同步,因此是线程安全的StringBuilder
没有实现同步,因此是非线程安全的。
-
性能:
StringBuffer
在多线程系统中可以保证数据同步,但效率比较低;StringBuilder
在单线程环境下效率较高,但在多线程环境下不安全。
在实际开发中
- 如果需要频繁修改字符串且要考虑线程安全,应该使用StringBuffer;
- 如果不需要考虑线程安全且追求效率,可以使用StringBuilder。
五、总结:
面试回答
5.1 使用场景
(1)如果要操作少量的数据用 String;
(2)多线程操作字符串缓冲区下操作大量数据用 StringBuffer;
(3)单线程操作字符串缓冲区下操作大量数据用 StringBuilder。
5.2 关联记忆方法
仅用作记忆
StringBuffer
:Buff有增益的意思,与多线程相关,多线程来回调用效率更低StringBuilder
:反者记,这个就是单线程使用效率更高
(后续有遇到问题再添加)
声明:如本内容中存在错误或不准确之处,欢迎指正。转载时请注明原作者信息(麻辣香蝈蝈)。