您的位置:首页 > 教育 > 锐评 > 公司名logo设计图片_b to b 网站建站_株洲专业seo优化_百度指数下载手机版

公司名logo设计图片_b to b 网站建站_株洲专业seo优化_百度指数下载手机版

2025/3/18 10:12:50 来源:https://blog.csdn.net/2401_87533975/article/details/146323458  浏览:    关键词:公司名logo设计图片_b to b 网站建站_株洲专业seo优化_百度指数下载手机版
公司名logo设计图片_b to b 网站建站_株洲专业seo优化_百度指数下载手机版

*个人主页

文章专栏

《赛博算命之梅花易数的JAVA实现》*

在这里插入图片描述

文章目录

    • *[个人主页](https://blog.csdn.net/2401_87533975?spm=1011.2124.3001.5343)
    • 文章专栏
    • 《赛博算命之梅花易数的JAVA实现》*
  • #前言:API
    • 1.定义
    • 2.已经学习过的API
    • 3.如何使用帮助文档:
  • 一、String
    • 1、String概述
    • 2.String的注意点
    • 3.创建String对象的两种方式
    • 4.java的常用方法(比较)
      • 字符串比较的方法:
      • 遍历字符串
      • 拼接字符串
      • 反转字符串
      • 字符串截取
      • 字符串的替换
  • 二、StringBuilder
    • 1.StringBuilder概述
    • 2。StringBuilder构造方法
    • 3.StringBuilder常用方法
  • 三、StringJoiner
    • 1.StringJoiner概述
    • 2.StringJoiner的构造方法
    • 3.StringJoiner的成员方法
      • 总结:String与StringBuilder与StringJoiner
  • 四、字符串原理
    • 扩展底层原理1:字符串存储的内存原理
    • 扩展底层原理2:==号比较的到底是什么?
    • 扩展底层原理3:字符串拼接的底层原理
      • 等号的右边没有变量
      • 等号的右边有变量
      • 总结:
    • 扩展底层原理4:StringBuilder提高效率原理图
      • 总结:
    • 扩展底层原理5:StringBuilder的源码分析
      • 总结:
    • 扩展底层原理5:StringBuilder的源码分析

#前言:API

1.定义

API(Application Programming Interface)应用程序编程接口

简单理解:API就是别人已经写好的东西,我们不需要自己编写,直接使用即可

public static void main (String []args){Random r = new Random ();int number = r.nextInt (100);
}

Java API : 指的就是JDK提供的各种功能的Java类

这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。

2.已经学习过的API

Scanner 键盘录入

Random 随机数

API和API帮助文档

API:目前是JDK中提供的各种功能的Java类

这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。

API帮助文档:帮助开发人员更好的使用API和查询API的一个工具

3.如何使用帮助文档:

  • 打开API帮助文档
  • 点击显示,并找到索引下面的输入框、
  • 在输入框中输入类名并点击显示
  • 查看类所在的包
  • 查看类的描述(一般情况下,只需要看第一行)
  • 查看构造方法
  • 查看成员方法

一、String

1、String概述

java.lang.String类代表字符串,java程序中的所有字符串文字(例如:”abc“)都为此类的对象。

String 是java定义好的一个类。定义在java.lang包中,所以使用的时候不需要导包。

String name = "尼古拉斯";
String schoolName = "黑马程序员";

2.String的注意点

字符串的内容是不会发生改变的,它的对象在创建后不能被更改

String name = "爱因斯晨";
String schoolName = "黑马程序员";
System.out.println(name+schoolName);

3.创建String对象的两种方式

  1. 直接赋值

    String name = "爱因斯晨";
    
  2. new

    构造方法说明
    public String ()创建空白字符串,不含任何内容
    public String (String original )根据传入的字符串,创建字符串对象
    public String(char [] chs)根据字符数组,创建字符串对象
    public String (byte [] chs)根据字节数组,创建字符串对象
    public class zifuu {public static void main(String[] args) {//直接赋值String s1 = "abc";System.out.println(s1);//使用new的方式创建字符串//空参构造String s2 = new String();System.out.println("@"+s2+"#");//传递一个字符串,根据传递的字符串内容再创建一个新的字符串对象String s3 = new String(original:"abc");System.out.println(s3);//传递一个字符数组,根据字符数组的内容,再创建一个新的字符串对象char[] ch = {'a','b','c'};String s4 = new String(ch);System.out.println(s4);//传递一个字节数组,根据字节数组的内容再创建一个新的字符串对象。byte [] bytes ={97,98,99};String s5 = new String (bytes);System.out.println(s5);}
    }

3.区别与用法:

Java的内存模型
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意:StringTable(串池)在JDK7版本开始,从方法区中挪到了堆内存

举例1:

public class Zicun {public static void main(String[] args) {String s1 = "abc";String s2 = "abc";System.out.println(s1);System.out.println(s2);}
}

在这里插入图片描述

当使用双引号直接赋值的时候,系统会检查该字符串在串池中是否存在。

不存在:创建新的

存在:复用

举例2:

public class fif {public static void main(String[] args) {char[] ch = {'a','b','c'};String str = new String(ch);String str1 = new String(ch);}
}

在这里插入图片描述

地址值不会复用

综上所述:我们推荐使用直接赋值,不仅因为书写简单而且内存方便

4.java的常用方法(比较)

public class bijiao {public static void main(String[] args) {String str1 = "abc";//串池里面有地址String str2 = "abc";//复用串池里面的地址System.out.println(str1==str2);}
}
//run:true
public class bijiao {public static void main(String[] args) {String str1 = "aaa";String str2 = "bbb";System.out.println(str1==str2);}
}
//run:false
public class bijiao {public static void main(String[] args) {String str1 = new String("abc");//记录的是堆里面的地址String str2 = "abc";//记录的是串池里面的地址System.out.println(str1==str2);}
}
//run:false

==号比的到底是什么?

  1. 基本数据类型:比较的是数据值

    int a = 10;
    int b = 20;
    System.out.println(a==b);//false
    
  2. 引用数据类型:比较的是地址值

    String s1 = new String ("abc");
    String s2 = new String ("abc");
    System.out.println(s1==s2);//false
    

字符串比较的方法:

boolean equals 方法(要比较的字符串)
完全一样结果才是true,否则为falseboolean equalslgnoreCase(要比较的字符串)
忽略大小写的比较
public class Stringd {public static void main(String[] args) {//1.创建两个字符串对象String s1 = new String("abc");String s2 = "ABC";//2.==号比较//基本数据类型:比较的是数据值是否相同//引用数据类型:比较的是地址值是否相同System.out.println(s1 == s2);//3.比较字符串内容是否相同boolean result =s1.equals(s2);System.out.println(result);//4.忽略大小写比较字符串内容是否相同//忽略大小写只能是英文boolean result2 = s1.equalsIgnoreCase(s2);System.out.println(result2);}
}//run:
//false
//false
//true
//键盘录入:
import java.util.Scanner;
public class llu {public static void main(String[] args) {//1.假设键盘录入一个abcScanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String s = sc.next();//2.代码中再定义一个字符串abcString s2 = "abc";//3.比较两个字符串内容是否相同boolean result = s.equals(s2);System.out.println(result);}}

练习:

//练习:已知正确的用户名和密码,请用程序实现模拟用户登录。总共给三次机会,登录之后,给出相应的提示。import java.util.Scanner;
public class yanzheng {public static void main(String[] args) {//定义正确的用户名和密码String rightUserName = "aiyinsichen";String rightPassword = "123456";Scanner sc = new Scanner(System.in);//模拟用户输入名字与密码,键盘录入for (int i = 1; i <= 3; i++) {System.out.println("请输入用户名:");String userName = sc.next();System.out.println("请输入密码:");String password = sc.next();//比较用户名和密码if (rightUserName.equals(userName) && rightPassword.equals(password)) {System.out.println("登录成功");break;}else {System.out.println("密码或用户名错误,登录失败,请重新输入");}}}
}

遍历字符串

需求:键盘录入一个字符串,使用程序实现在控制台遍历该字符串

public char charAt(int index):根据索引返回字符
public int length():返回此字符串的长度
//遍历字符串
import java.util.Scanner;
public class luru {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String a = sc.nextLine();//a.length().fori 回车for (int i = 0; i < a.length(); i++) {//i依次表示字符串的每一个索引char c = a.charAt(i);System.out.println(c);}}
}
//键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数
import java.util.Scanner;
public class shai {public static void main(String[] args) {//键盘录入一个字符串Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String str = sc.next();//定义三个统计变量,初始值都为0int bigCount = 0;int smallCount = 0;int numberCount = 0;for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (c >= 'A' && c <= 'Z') {//char类型的变量在参与计算的时候自动类型提升为int 查询ascii码表bigCount++;} else if (c >= 'a' && c <= 'z') {smallCount++;} else if (c >= '0' && c <= '9') {numberCount++;}}System.out.println("大写字母字符:" + bigCount);System.out.println("小写字母字符:" + smallCount);System.out.println("数字字符:" + numberCount);}
}

拼接字符串

//拼接
//定义一个方法,把int数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。
//例如,数组为int[] arr = {1,2,3}; ,执行方法后的输出结果为:[1, 2, 3]
public class pinjie {public static void main(String[] args) {int[] arr = {1,2,3};String s = arrayToString(arr);System.out.println(s);}public static String arrayToString(int[] arr){if (arr == null){return "";}if (arr.length == 0){return "[]";}String s = "[";for (int i = 0; i < arr.length; i++) {if (i == arr.length - 1){s = s + arr[i];}else{s = s + arr[i] + ",";}}s = s + "]";return s;}
}

反转字符串

//定义一个方法,实现字符串反转
//键盘录入一个字符串,调用该方法,并在控制台输出结果
import java.util.Scanner;
public class fanZhuan {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String s = sc.next();//调用方法String s1 = fan(s);System.out.println("反转后的字符串为:"+s1);}public static String fan(String s){// 将字符串转换为字符数组便于修改char[] arr = s.toCharArray();// 修正循环初始化和边界条件for (int i = 0, j = arr.length - 1; i < j; i++, j--) {char temp = arr[i];arr[i] = arr[j];arr[j] = temp;}return new String(arr);}
}
方法二:
使用自带的反向遍历的方法:
变量名.length().forr 回车
import java.util.Scanner;
public class fanzhuan {  // 字符串反转工具类public static void main(String[] args) {Scanner sc = new Scanner(System.in);  // 创建控制台输入扫描器String n = sc.next();                // 读取用户输入的字符串String result = fan(n);              // 调用反转方法处理输入System.out.println(result);           // 输出反转结果}// 字符串反转核心方法public static String fan(String s) {    // 参数s: 原始字符串String s1 = "";//s.length().forr回车,就是反向遍历(保留用户原有注释)for (int i = s.length()-1; i >= 0; i--) { // 倒序循环:从末位到首位char c = s.charAt(i);            // 提取当前位置字符s1 = s1 + c;                     // 反向拼接字符}return s1;                          // 返回反转后的结果}
}

综合练习:

金额转换:如键盘录入234.输出大写方法
import java.util.Scanner;
/*** Demoutwo 类用于将用户输入的金额转换为中文大写金额表示。*/
public class Demoutwo {/*** 程序的入口点,处理用户输入的金额并将其转换为中文大写金额。** @param args 命令行参数,在本程序中未使用。*/public static void main(String[] args) {// 1. 键盘录入一个金额// 创建一个 Scanner 对象,用于从标准输入读取用户输入Scanner sc = new Scanner(System.in);// 定义变量 money 用于存储用户输入的金额int money;// 使用 while 循环确保用户输入的金额在有效范围内(0 到 9999999 之间)while (true) {// 提示用户输入一个金额System.out.println("请输入一个金额:");// 从标准输入读取一个整数作为金额money = sc.nextInt();// 检查金额是否在有效范围内if (money >= 0 && money <= 9999999) {// 如果金额有效,跳出循环break;} else {// 如果金额无效,提示用户并继续循环等待新的输入System.out.println("金额无效");}}// 2. 把金额转换为中文// 定义一个空字符串 str 用于存储转换后的中文金额String str = "";// 使用 while 循环将金额逐位转换为中文数字while (true) {// 获取当前金额的个位数字int ge = money % 10;// 调用 getChinaNum 方法将个位数字转换为中文数字String chinaNum = getChinaNum(ge);// 将中文数字拼接到 str 字符串的前面str = chinaNum + str;// 去掉刚刚处理的个位数字money = money / 10;// 检查金额是否已经处理完if (money == 0) {// 如果金额为 0,跳出循环break;}}// 3. 补零,补到 7 位// 计算需要补充的零的数量int count = 7 - str.length();// 使用 for 循环在 str 字符串前面补充零for (int i = 0; i < count; i++) {str = "零" + str;}// 输出补零后的中文数字字符串System.out.println(str);// 4. 插入单位// 定义一个字符串数组 arr2,包含中文金额的单位String[] arr2 = {"佰", "拾", "万", "仟", "佰", "拾", "元"};// 使用 for 循环遍历补零后的中文数字字符串for (int i = 0; i < str.length(); i++) {// 获取当前位置的中文数字字符char c = str.charAt(i);// 将中文数字字符和对应的单位拼接成一个新的字符串String s = c + arr2[i];// 输出拼接后的字符串System.out.print(s);}}/*** 将阿拉伯数字转换为中文大写数字。** @param number 要转换的阿拉伯数字(0 到 9 之间)* @return 对应的中文大写数字字符串*/public static String getChinaNum(int number) {// 定义一个字符串数组 arr,包含中文大写数字String[] arr = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};// 返回数组中对应索引的中文大写数字return arr[number];}
}

字符串截取

截取:
String substring (int beginlandex , int endlndex )
注意点:包头不包尾,包左不包右只有返回值才是截取的小串
String substring (int beginlndex) 截取到末尾
//加密电话号码:
//15552534681
//加密成:155****4681
import java.util.Scanner;
public class demout {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入你的手机号码");String s = sc.nextLine();String s1 = s.substring(0,3);String s2 = s.substring(7);System.out.println(s1+"****"+s2);}
}
//练习:
//读取身份证中的信息:出生年月日还有性别
import java.util.Scanner;
public class demofour {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入你的身份证号码");String id = sc.next();String year = id.substring(6,10);String month = id.substring(10,12);String day = id.substring(12,14);int xing = id.charAt(16);String gender;if (xing % 2 == 0) {gender = "女";}else{gender = "男";}System.out.println("人物信息为:");System.out.println("出生年月日为:"+year+"年"+month+"月"+day+"日");System.out.println("性别为:"+gender);}
}

字符串的替换

String replace (旧值,新值)替换
注意点:只有返回值才是替换之后的结果
//练习:敏感词屏蔽
import java.util.Scanner;
public class mingan {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一句话");String said = sc.next();String [] cyuyan ={"cnm","sb","tmd"};for (int i = 0; i < cyuyan.length; i++) {said =said.replace(cyuyan[i],"***");}System.out.println(said);}
}

注意:字符串是常量,他们的值在创建之后不能被改变的。

二、StringBuilder

1.StringBuilder概述

StringBuilder可以看成是一个容器,创建之后里面的内容是可变

  • 作用:提高字符串的操作效率

2。StringBuilder构造方法

方法名说明
public StringBuilder ()创建一个空白可变字符串对象,不含有任何内容
public StringBuilder (String str )根据字符串的内容,来创建可变字符串对象

3.StringBuilder常用方法

方法名说明
public StringBuilder append (任意类型)添加数据,并返回对象本身
public StringBuilder reverse ()反转容器中的内容
public int length()返回长度(字符出现的个数)
public String toString通过toString()就可以实现把StringBuilder 转换成String
public class builder {public static void main(String[] args) {//1.创建对象StringBuilder sb = new StringBuilder("abc");//2.添加功能sb.append("def");sb.append("ghi");sb.append("jkl");sb.append("mno");//3.反转功能sb.reverse();//4.获取长度int length = sb.length();}
}
public class demoo {public static void main(String[] args) {//1.创建对象StringBuilder sb = new StringBuilder("abc");//2.添加功能sb.append("def");sb.append("ghi");sb.append("jkl");sb.append("mno");System.out.println(sb);//3.再把StringBuilder变回String//为什么要把StringBuilder变回String呢?//因为StringBuilder是一个可变的字符串,而String是一个不可变的字符串,所以我们需要把StringBuilder变回String,才能使用String的方法String str = sb.toString();System.out.println(str);}
}

链式编程

当我们在调用一个方法的时候,不需要用变量接受他的结果,可以继续调用其他方法

import java.util.Scanner;public class lianshi {public static void main(String[] args) {//链式编程://当我们在调用一个方法的时候,这个方法的返回值是一个对象,我们可以继续调用这个对象的方法。//这种方式叫做链式编程。int len = getString().substring(1).length();System.out.println(len);}public static String getString() {Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String s = sc.next();return s;}
}
//链式编程练习
public class lioain {public static void main(String[] args) {//1.创建对象StringBuilder sb = new StringBuilder("abc");//2.添加功能sb.append("def").append("ghi").append("jkl").append("mno");System.out.println(sb);String s = sb.toString();System.out.println(s);}
}
//判断是不是回文串
import java.util.Scanner;
public class xio {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");//键盘录入一个字符串String str = sc.next();//将字符串反转String sb = new StringBuilder().append(str).reverse().toString();//判断是否是回文串if (sb.equals(str)) {System.out.println("是回文串");}else {System.out.println("不是回文串");}}
}
//需求:定义方法,把int数组中的数据类型按照指定的格式拼接换成一个字符串返回,调用方法,并在控制台输出结果
public class ding {public static void main(String[] args) {int[] arr = {1,2,3,4,5,6,7,8,9,10};System.out.println(getArray(arr));}public static String getArray(int[] arr) {StringBuilder sb = new StringBuilder();sb.append("[");for (int i = 0; i < arr.length; i++) {if (i == arr.length - 1) {sb.append(arr[i]);}else {sb.append(arr[i]).append(",");}}sb.append("]");return sb.toString();}
}

三、StringJoiner

我们为什么要学StringJoiner?

我们原来在学习String时拼接元素太耗费时间,于是有了StringBuilder

但是我们在上面练习中,在打印字符串格式时,要做诸多限制,不是很方便于是

就有了StringJoiner。
在这里插入图片描述

1.StringJoiner概述

  • StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的
  • 作用:提高字符串的操作效率,而且代码编写的特别简洁,但是市场上很少有人看
  • JDK8出现的

2.StringJoiner的构造方法

没有空参构造

方法名说明
pubilc StringJoiner(间隔符号)创建一个StringJoiner对象,指定拼接时的间隔符号
pubilc StringJoiner(间隔符号,开始符号,结束符号 )创建一个StringJoiner对象,指定拼接时的间隔符号、开始符号、结束符号
StringJoiner sj = new StringJoiner("---");
1--2--3
StringJoiner sj = new StringJoiner(",","[","]");
[1,2,3]

3.StringJoiner的成员方法

方法名说明
public StringJoiner add (添加的内容)添加数据,并返回对象本身
public int length()返回长度(字符出现的个数)
public String toString()返回一个字符串(该字符串就是拼接之后的结果)
import java.util.StringJoiner;public class joner {public static void main(String[] args) {//1.创建对象StringJoiner sj = new StringJoiner("---");//2.添加功能sj.add("adc").add("def").add("ghi");System.out.println(sj);//3.创建对象2//delimiter: 分隔符//prefix: 前缀//suffix: 后缀StringJoiner sj2 = new StringJoiner(" ", "[", "]");//4.添加功能sj2.add("adc").add("def").add("ghi");System.out.println(sj2);}}//adc---def---ghi
//[adc def ghi]
import java.util.StringJoiner;public class zifu {public static void main(String[] args) {StringJoiner sj = new StringJoiner(",","[","]");int len = sj.add("aaa").add("bbb").add("ccc").length();//len不仅是字符串的长度,还包括了[]和,的长度System.out.println(len);}
}
//13

length不仅是字符串的长度,还包括符号的长度

总结:String与StringBuilder与StringJoiner

String:

表示字符串的类,定义了很多操作字符串的方法

StringBuilder:

一个可变的操作字符串的容器。

可以高效的拼接字符串,还可以将容器里面的内容反转

StringJoiner:

JDK8出现的一个可变的操作字符串的容器,可以高效,方便的拼接字符串。

在拼接的时候,可以指定间隔符号,开始符号,结束符号。

四、字符串原理

扩展底层原理1:字符串存储的内存原理

  • 直接赋值会复用字符串常量池中的
  • new出来不会复用,而是开辟一个新的空间

扩展底层原理2:==号比较的到底是什么?

  • 基本数据类型比较数据值
  • 引用数据类型比较地址值

扩展底层原理3:字符串拼接的底层原理

等号的右边没有变量

public class Test {public static void main (String [] args){String s = "a"+ "b"+"c";System.out.println(s);}
}

拼接的时候没有变量,都是字符串。触发字符串的优化机制。在编译的时候就已经是最终的结果了。

在这里插入图片描述

等号的右边有变量

public class Test {public static void main (String [] args ){String s1 = "a";String s2 = s1 + "b";String s3 = s2 + "c";System.out.println (s3);}
} 

在拼接的时候有变量,JDK8 以前底层会使用StringBuilder

在这里插入图片描述

内存分析:

1、进入 main 方法

在栈为 main 方法创建帧,用于存局部变量

2、执行变量赋值

String s1 = “a”;:

栈中创建 s1,若字符串常量池无 "a" 则创建,将其引用赋给 s1

String s2 = s1 + “b”;:

栈中创建 s2,堆中创建 StringBuilder 拼接 s1"b"(若常量池无 "b" 则创建),生成新字符串 "ab" 存于堆,引用赋给 s2

String s3 = s2 + “c”;:

栈中创建 s3,堆中新建 StringBuilder 拼接 s2 "c"(若常量池无 "c" 则创建),生成新字符串 "abc" 存于堆,引用赋给 s3

3、输出结果

从栈取s3引用,找到堆中 "abc" 输出。

4、方法结束

main 栈帧销毁,局部变量消失,堆对象等待垃圾回收,常量池字符串保留至程序结束。

**总结:**一个加号,堆内存中俩对象

public class Test {public static void main (String [] args ){String s1 = "a";String s2 = s1 + "b";String s3 = s2 + "c";System.out.println (s3);}
} 

字符串拼接的时候有变量参与:

在内存中创建了很多对象,浪费空间,时间也非常的慢

结论:如果很多字符串变量拼接,不要直接+。在底层会创建多个对象,浪费时间,浪费性能

总结:

  • 如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串
  • 如果没有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存

扩展底层原理4:StringBuilder提高效率原理图

public class Test {public static void main (String [] args){StringBuilder sb = new StringBuilder();sb.append("a");sb.append("b");sb.append("c");System.out.println(sb); }
}

在这里插入图片描述

StringBuilder 是一个可变的容器

内存分析

1、进入 main 方法

JVM 在栈为 main 方法创建帧,用于存储局部变量。

2、执行代码

StringBuilder sb = new StringBuilder();:

栈中创建局部变量 sb,堆中创建 StringBuilder 对象,sb 指向该对象。

sb.append(“a”);:

检查字符串常量池,若没有 "a" 则创建,StringBuilder 对象将 "a" 内容添加到自身存储区域。

sb.append(“b”);:

同理,若常量池无 "b" 则创建,StringBuilder 追加 "b"

sb.append(“c”);:

若常量池无 "c" 则创建,StringBuilder 追加 "c"

System.out.println(sb);:

从栈中获取 sb 引用,找到堆中 StringBuilder 对象,输出其内容。

2、方法结束

main 方法栈帧销毁,局部变量 sb 消失,堆中 StringBuilder 对象等待垃圾回收,字符串常量池中的 "a""b""c" 保留到程序结束。

//面试水题:
//问题:下列代码的运行结果是什么?
public static void main (String [] args ){String s1 = "abc";//记录串池中的地址值String s2 = "ab";String s3 = s2 + "c";//新new出来的对象,地址值不一样System.out.println(s1==s3);//==比较的是引用局部变量的地址值
}
//flase

字符串拼接的时候,如果有变量:

JDK8:系统底层会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接。拼接后,再调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象。

JDK8版本:系统会预估要字符串拼接之后的总大小,把要拼接的内容都放在数组中,此时也是产生一个新的字符串。

public class Test{public static void main (String [] args ){String s1 = "abc";//记录串池中的地址值String s2 = "a"+"b"+"c";//没有变量,触发优化机制,编译时,就会将“a”+"b"+"c"拼接为"abc"//复用串池中的字符串System.out.println(s1==s2);}
}
//ture

总结:

  • 所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存

扩展底层原理5:StringBuilder的源码分析

  • 默认创建一个长度为16的字节数组
  • 添加的内容长度小于16,直接存
  • 添加的内容大于16会扩容 (原来的容量 *2 +2)
  • 如果扩容之后还不够,以实际长度为准

System.out.println(sb);:

从栈中获取 sb 引用,找到堆中 StringBuilder 对象,输出其内容。

2、方法结束

main 方法栈帧销毁,局部变量 sb 消失,堆中 StringBuilder 对象等待垃圾回收,字符串常量池中的 "a""b""c" 保留到程序结束。

//面试水题:
//问题:下列代码的运行结果是什么?
public static void main (String [] args ){String s1 = "abc";//记录串池中的地址值String s2 = "ab";String s3 = s2 + "c";//新new出来的对象,地址值不一样System.out.println(s1==s3);//==比较的是引用局部变量的地址值
}
//flase

字符串拼接的时候,如果有变量:

JDK8:系统底层会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接。拼接后,再调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象。

JDK8版本:系统会预估要字符串拼接之后的总大小,把要拼接的内容都放在数组中,此时也是产生一个新的字符串。

public class Test{public static void main (String [] args ){String s1 = "abc";//记录串池中的地址值String s2 = "a"+"b"+"c";//没有变量,触发优化机制,编译时,就会将“a”+"b"+"c"拼接为"abc"//复用串池中的字符串System.out.println(s1==s2);}
}
//ture

总结:

  • 所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存

扩展底层原理5:StringBuilder的源码分析

  • 默认创建一个长度为16的字节数组
  • 添加的内容长度小于16,直接存
  • 添加的内容大于16会扩容 (原来的容量 *2 +2)
  • 如果扩容之后还不够,以实际长度为准

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com