目录
面试题:对比String、StringBuffer和StringBuilder
说实话,之前学完了java基础,也不知道API是啥,问了朋友,他也解释不清楚,看了网上的视频才明白。(惭愧惭愧)
API(Application Programming Interface):应用程序编程接口。就是别人已经写好的东西,我们不需要自己编写,直接使用即可,例如Scanner、Random、Math等。
Java API指的就是JDK中提供的各种功能的Java类。这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。
案例:
当使用双引号直接赋值时,系统会检查该字符串在[字符串常量池]中是否存在:如果不存在,则创建新的;如果存在,则进行复用。这种方法节约内存。
占用内存,不推荐。
比较基本数据类型时,比较的是数据值
- int a = 10;
- int b = 20;
- a==b; // false
在比较引用数据类型时,比较的是地址值
- String s1 = new String("abc");
- String s2 = new String("abc");
- s1 == s2; // false
- String s1 = new String("abc"); // 记录堆内存中的地址值
- Strinf s2 = "abc"; // 记录字符串常量池中的地址值,没有就创建,有就复用
- s1 == s2; // false
说明:Object类中定义的equals()和==的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体。
像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址值是否相同,而是比较两个对象的"实体内容"是否相同。
总结:当一个类中,没有重写过equls()方法,比较的是地址值;重写过equls()方法,比较的是实体内容。
只要想比较字符串的内容,就必须用String里面的方法。
StringBuilder可以看成是一个容器,创建之后里面的内容是可变的(String不可变),能够提高字符串的操作效率。
- StringBuilder sb = new StringBuilder();
-
- // 添加元素
- sb.append(1).append(1.23);
- sb.append("张三");
- sb.append(true);
-
- // 反转元素
- sb.reverse();
-
- // 获取长度
- System.out.println("长度:"+sb.length());
-
- // 变回字符串
- System.out.println(sb.toString());
-
- // 打印对象不是地址值而是属性值
- System.out.println(sb);
- Scanner sc = new Scanner(System.in);
- System.out.println("请输入一个字符串:");
- String next = sc.next();
- StringBuilder sb = new StringBuilder();
- String s = sb.append(next).reverse().toString();
- if(s.equals(next)){
- System.out.println("是对称字符串");
- }else {
- System.out.println("不是对称字符串");
- }
- public class StringBuilderDemo {
- public static void main(String[] args) {
- int[] arr = {1, 2, 3};
- System.out.println(arrTo(arr));
- }
-
- public static String arrTo(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(",");
- }
- }
- return sb.append("]").toString();
- }
- }
- StringBuffer append(xxx):提供了很多的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() :把当前字符序列逆转
- public int indexOf(String str)
- public String substring(int start,int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串
- public int length()
- public char charAt(int n )
- public void setCharAt(int n ,char ch)
总结:
增:append(xxx)
删:delete(int start,int end)
改:setCharAt(int n ,char ch) / replace(int start, int end, String str)
查:charAt(int n )
插:insert(int offset, xxx)
长度:length();
*遍历:for() + charAt() / toString()
相同点:三者都使用char[]存储
不同点:
String:不可变字符序列;
StringBuffer:可变字符序列、效率低、线程安全,如果项目中要使用多线程,则使用StringBuffer;
StringBuilder:可变字符序列、效率高、线程不安全,如果项目中不涉及到多线程,则使用StringBuilder。
注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值。
StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的。能够提高字符串的操作效率,而且代码编写特别简洁,但是用的较少。
代码示例:
- public class StringJoinerDemo {
- public static void main(String[] args) {
- int[] arr = {1, 2, 3};
-
- StringJoiner sj = new StringJoiner(",", "[", "]");
- for (int i = 0; i < arr.length; i++) {
- sj.add(arr[i] + "");
- }
-
- System.out.println(sj);
- }
- }